Kết nối giữa các file Excel bằng ADODC.

Liên hệ QC

sealand

Thành viên gạo cội
Tham gia
16/5/08
Bài viết
4,884
Được thích
7,687
Giới tính
Nam
Nghề nghiệp
Kế Toán
Mình đã cùng Thu Nghi và Challenge98 thảo luận về vấn đề kết nối và trích rút dữ liệu giữa các File Excel. Có rất nhiều cách, nhưng ADODC cũng là 1 cách khá hay. Nhưng rồi kết quả cũng quên đi.
Trong thực tế có rất nhiều người hỏi về vấn đề này, vậy mình Post lên đây file ví dụ để các bạn tham khảo và mở rộng cho chương trình khi cần thiết. Đây là ví dụ đơn giản nhất có thể nên cũng là dễ hiểu với các bạn mới vọc. Hy vọng các bạn tìm được điều gì đó ở ví dụ này.
(Lưu ý: Khởi bằng ZMain)
 

File đính kèm

  • Ket noi bang ADODC.rar
    27 KB · Đọc: 1,540
Lần chỉnh sửa cuối:
Hic, tôi không hiểu lắm. Khi bật file cuối cùng để chạy thì toàn báo lỗi nên vẫn chưa biết file này để làm gì.
 

File đính kèm

  • untitled.JPG
    untitled.JPG
    140 KB · Đọc: 728
Form nằm ở file ZMain, mở file này để mở form.
Bạn phải giải nén ra ổ đĩa chứ chạy trưc tiếp từ mạng sẽ lỗi không thấy các fỉle trừ file gốc( Tất nhiên mở vẫn có kết quả).
Trường hợp lỗi nữa là bạn chọn file bất kỳ không có cấu trúc dữ liệu dạng bảng hoặc không có sheet tên là sheet1.
 
Lần chỉnh sửa cuối:
Cảm ơn sealand Càng học hỏi càng thấy hay và bổ ích để nâng cao kiến thức nhưng mình vẫn còn gà lắm chưa hiểu gì về cái món ADODC này xin mọi người chỉ giáo . mọi người cùng trao đổi về sử dụng ADODC nhé để kết nối dữ liệu nhé.
Mình search trên diễn đàn có thấy tài liệu về ADO nhưng không tải được http://www.giaiphapexcel.com/forum/showthread.php?t=3561 . Ai có tài liệu này cho mình xin với.
Cho mình hỏi là nó có thể đưa ra hộp thoại chọn dữ liệu sau đó khi nào mình gọi nó mới tự động kết nối không? ví dụ như khi nạp xong nhấn Enter ở cột A sheet1 thì hiện lisview?
 
Lần chỉnh sửa cuối:
To Pomete: Đến 90% dạng lỗi này là do VBA của bạn có khai Option Explicit trên đầu. Như vậy tất cả các biến không được khai báo tường minh trước khi dùng đều báo lỗi.

Để chạy, tạm thời bạn xóa dòng Option Explicit hoặc sử lý như sau:
Menu Tools--Option--Thẻ Edit: Xóa dấu kiểm ở dòng Require Variable Declaration
 
Cho mình hỏi cái theo như ebook của bác levanduyet có đoạn
Bởi vì bây giờ người ta thường đề cập đến ADO.NET chứ ai lại giới thiệu về cái ADO cũ rích này. Sau khi tham khảo, tôi thấy vẫn nhiều người dùng các phiên bản cũ từ Excel 2003 trở về trước(**). Thế nên tôi quyết định chỉnh sửa lại những gì tôi đã viết về ADO, và thêm một số nội dung quan trọng khác để giới thiệu đến các bạn yêu thích lập trình VBA-Excel.
Thì có phải là ADO chỉ chạy cho Excel 2003 trở về trước phải không?
 
Lần chỉnh sửa cuối:
Sao vậy được, đừng nghĩ VB.NET đã ăn đứt được VB trước đây. Bạn thấy đấy Macro4 của Exc so với VBA ra sao? Vậy mà nó vẫn có chỗ đứng của nó. Đừng nghĩ cái gì mới cũng hơn tất cả. Hiện mình vẫn dùng Off 2003 chưa thể chấp nhận Off2007. Các ứng dụng VB cũ vẫn tồn tại đó thôi. Thậm chí, Foxpro 2.6 cũng vẫn còn chứ bộ.
 
Lần chỉnh sửa cuối:
Em chay bị lỗi

Em chạy thì báo lỗi tại dòng
Set cnEx = New ADODB.Connection

Bác giải thích giúp em nhé
 

File đính kèm

  • loi.JPG
    loi.JPG
    183.1 KB · Đọc: 693
To zazabovn: Bạn vào tools--Reference--Chọn Microsoft ActiveX Data Ojects 2.0...và Visual Basic for App...
 
Em chạy thì báo lỗi tại dòng
Set cnEx = New ADODB.Connection

Bác giải thích giúp em nhé

Để khắc phục lỗi này chúng ta nên dùng khai báo trễ (late binding). Ví dụ:

Mã:
Dim gcnAccess As Variant
Set gcnAccess = CreateObject("ADODB.Connection")
sConnect = .... 'Chuổi kết nối
With gcnAccess
        .Mode = 3    'i.e adModeReadWrite
        'Neu sau thoi gian nay ma khong ket noi duoc se bao loi
        'If after this time pass, the error come out
        .ConnectionTimeout = 30
        'CursorTypeEnum
        'adOpenDynamic     = 2
        'adOpenForwardOnly = 0
        'adOpenKeySet      = 1
        'adOpenStatic      = 3

        'The CursorLocationEnum:
        'adUseClient = 3
        'adUseServer = 2
        .CursorLocation = 3    'adUseClient
        .ConnectionString = sConnect
        .Open
End With
'Sau khi kết nối được rồi thì sẽ thực hiện truy xuất
'


Lê Văn Duyệt
 
Đối với ví dụ này ta có thể chuyển thao tác kiểm tra việc kết nối thành công hay không vào một hàm như sau:
Mã:
Public eConnection As Variant

Function lConnection(sFullFilePath As String) As Long
    Dim sConnection As String

    'Gia su rang khong co ket noi duoc
    lConnection = 0
    'Kiem tra sFileName co ton tai hay khong?
    If Not FileExists(sFullFilePath) Then
        lConnection = -1
        GoTo ErrorExit
    End If

    sConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
                  sFullFilePath & ";Persist Security Info=False; Extended Properties=Excel 8.0;"
    Set eConnection = CreateObject("ADODB.Connection")
    With eConnection
        .Mode = 3    'Tuc la adModeReadWrite
        'Neu sau thoi gian nay ma khong ket noi duoc se bao loi
        .ConnectionTimeout = 30
        'CursorTypeEnum
        'adOpenDynamic     = 2
        'adOpenForwardOnly = 0
        'adOpenKeySet      = 1
        'adOpenStatic      = 3

        'The CursorLocationEnum:
        'adUseClient = 3
        'adUseServer = 2
        .CursorLocation = 3    'adUseClient
        .ConnectionString = sConnection
        .Open
    End With
    'Neu thanh cong thi gan la 1
    lConnection = 1
    'Dong ket noi
    eConnection.Close
    
ErrorExit:

    Exit Function

ErrorHandler:
    'Cac thao tac kiem tra loi o day
    'Cac loi khac thi lConnection=-2
    lConnection = -2
    Resume ErrorExit

End Function

' fname là đường dẫn bao gồm cả tên tập tin
Function FileExists(fname) As Boolean
    FileExists = Dir(fname) <> ""
End Function

Hàm
Mã:
lConnection
sẽ trả về:
  • 1: nếu kết nối thành công
  • 0: nếu kết nối không thành công
  • -1: kết nối không thành công do tập tin không tồn tại
  • -2: kết nối không thành công bởi những lỗi khác
Các giá trị này thì tùy bạn, bạn cũng có thể viết chỉ 2 giá trị thôi là 0 (không kết nối được) và 1 (kết nối thành công).
Trong hàm này tôi sử dụng khai báo trễ (late biding), như vậy nó sẽ không phục thuộc vào phiên bản của ADO.

Sau đó là việc chúng ta viết một hàm để lấy về một Recordset dựa trên câu lệnh SQL ta truyền cho hàm này. Như vậy công việc của chúng ta sẽ đơn giản hơn với việc viết các hàm, thủ tục để thực hiện các chức năng chúng ta thường sử dụng trong quá trình kết nối.


Lê Văn Duyệt
 
Lần chỉnh sửa cuối:
To Levanduyet
Cám ơn bạn cung cấp khá nhiều kiến thức hay và rất cơ bản.
Riêng về Set cnEx = New ADODB.Connection gây lỗi thì mình nghĩ khai báo bằng mã lệnh là khai báo trễ (Run-time) chứ, Khai sớm là đặt cố định trên Form khi thiết kế. Mặt khác, mình làm như vậy kể cả trong VB6 dịch ra file *.exe sử dụng khá nhiều máy thấy bình thường.

Nay có điều không hiểu là cũng nhưng câu lệnh đó với điều kiện cơ bản như nhau thì có máy hiểu còn 1 số không hiểu. Phiên bản ADO thì hầu như máy nào cũng có 1 loạt các phiên bản trong máy.
 
Nay có điều không hiểu là cũng nhưng câu lệnh đó với điều kiện cơ bản như nhau thì có máy hiểu còn 1 số không hiểu. Phiên bản ADO thì hầu như máy nào cũng có 1 loạt các phiên bản trong máy.
Như tôi đã nói, khi bạn tham chiếu đến đối tượng ADO theo kiểu khai báo sớm (early binding) thì nếu phiên bản của máy người dùng khác với phiên bản của máy người viết, thì thông báo lỗi cũng xãy ra. Còn về việc khai báo sớm, khai báo trễ, lợi ích hay khó khăn của chúng thì chúng ta đã bàn nhiều trên GPE.

Bạn cũng có thể tham khảo các bài viết, so sánh sau:
http://word.mvps.org/fAQs/InterDev/EarlyvsLateBinding.htm
http://www.dicks-clicks.com/excel/olBinding.htm
http://blogs.msdn.com/davidklinems/archive/2006/11/27/what-is-late-binding.aspx


Lê Văn Duyệt
 
Lần chỉnh sửa cuối:
To Pomete: Đến 90% dạng lỗi này là do VBA của bạn có khai Option Explicit trên đầu. Như vậy tất cả các biến không được khai báo tường minh trước khi dùng đều báo lỗi.

Để chạy, tạm thời bạn xóa dòng Option Explicit hoặc sử lý như sau:
Menu Tools--Option--Thẻ Edit: Xóa dấu kiểm ở dòng Require Variable Declaration

Hi, Bạn xem lại giúp mình nhé vì mình đã vào mục Edit trong Optinon nhưng không tìm thấy mục Require Variable Declaration.

Mình làm được rồi nhưng lại bị lỗi Set cnEx = New ADODB.Connection.
Mình thấy các bác chèn thêm đoạn code để sửa lỗi nhưng không biết chèn vào đâu. Bác nào hoàn chỉnh file này giúp mình nhé!
 
Lần chỉnh sửa cuối:
To pomete: Bạn thực hiện như bài #10 nhé.
Hi, Bạn xem lại giúp mình nhé vì mình đã vào mục Edit trong Optinon nhưng không tìm thấy mục Require Variable Declaration.
Đây là Tools trong VBA nhé
 
TO SEALAND
HIX MÌNH VẪN KHÔNG THỂ CHẠY FILE BẠN GỬI ĐƯỢC. NÓ VẪN BÁO LỖI SAU:
"Set cnEx = New ADODB.Connection" >> " CAN NOT FIND PROJECT OR LIBRARY"
XEM LẠI GIÚP MÌNH VỚI
 
To zazabovn: Bạn vào tools--Reference--Chọn Microsoft ActiveX Data Ojects 2.0...và Visual Basic for App...

Mình làm theo bạn nhưng chỉ được cái đầu tiên là Microsoft ActiveX Data Ojects 2.0 còn những cái kìa thì nó thông báo như hình vẽ. Liệu có phải là do window không tương thích không????
 

File đính kèm

  • 1.JPG
    1.JPG
    144.5 KB · Đọc: 314
To Quoc Huy: Bạn xem bài #10 và sử lý.
To pomete: Rất có thể biến trong bài trùng với tên UDF, Sub... nằm trong ad- in nào đó mà bạn đã bổ xung, vì vốn dĩ nó không bị trùng mà.Bạn đóng tất cảc các file đang mở cùng xem sao. Bạn xem lỗi tại biến nào thì tạm đổi toàn bộ tên biến đó sang biến khác.
 
1. Anh sealand xem thử code bên dưới nhé:
Và anh hãy bỏ đoạn "On error Resume Next" đi, để còn biết nó lỗi ở đâu mà sửa!
==> nghĩa là query trong Excel không dùng "*" mà phải dùng "%" mới được!%#^#$

2. Thêm vào đó, muốn truy xuất dữ liệu từ 1 file excel theo code bên dưới thì file excel nguồn phải đặt NAME cho vùng dữ liệu nguồn đó! ==> Với cách này, 1 sheet nguồn ta có thể có nhiều bảng tương ứng với nhiều NAME đặt cho nhiều vùng khác nhau trên sheet nguồn đó; và có thể truy xuất từ nhiều bảng này ra file khác theo code bên dưới.
(như trong file đính kèm, ta vào Insert/Name/Define sẽ thấy 1 Name có tên "DATA" với địa chỉ là vùng dữ liệu của sheet("DATA"); Ta xóa thử Name này đi thì code sẽ báo lỗi vì không tìm thấy bảng DATA nào cả!)
mySQL = "SELECT * FROM [DATA]" & Chr(13) & "WHERE DATA.tk like '111%'"
- Tuy nhiên không phải vì thể mà không giải quyết được, chúng ta có thể thêm "$" vào sau tên sheet của file --> excel sẽ tự coi sheet này là bảng luôn (giống như cách anh sealand phát biểu lệnh SQL ban đầu) ==> Tuy nhiên, với cách này, 1 sheet sẽ chỉ là 1 bảng dữ liệu mà thôi:
mySQL = "SELECT * FROM [DATA$]" & Chr(13) & "WHERE tk like '111%'"
3. Em có thêm phần ghi chú trong code để người mới tiếp cận ADO dễ hình dung các bước tạo connection và truy xuất dữ liệu từ cơ sở dữ liệu nguồn ban đầu!
[highlight=vb]
Sub Chepdl()
Dim FName As String, cnEx As Variant, RecEx As Variant, mySQL As String
'Chuan bi xuat du lieu:
a = MsgBox("Chep Du lieu sang noi khac!?", vbInformation + vbYesNo, "Info")
If a = vbYes Then
'Lay File hien hanh lam file du lieu Nguon [Source data]:
FName = ThisWorkbook.Path & "\" & ThisWorkbook.Name
'Tao ket noi voi du lieu nguon:
Set cnEx = New ADODB.Connection
cnEx.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FName & _
";Persist Security Info=False; Extended Properties=Excel 8.0;"
cnEx.Open
'Truy xuat du lieu [records] bang cau lenh SQL:
Set RecEx = New ADODB.Recordset
mySQL = "SELECT * FROM [DATA]" & Chr(13) & "WHERE DATA.tk like '111%'"
RecEx.Open mySQL, cnEx, adOpenKeyset, adLockOptimistic
'Chep du lieu truy xuat duoc qua sheet2:
Sheet2.Cells.ClearContents
Sheet1.[1:1].Copy Sheet2.[1:1]
Sheet2.[A2].CopyFromRecordset RecEx
'Refresh lai hai bien cnEx va RecEx:
RecEx.Close: Set RecEx = Nothing
cnEx.Close: Set cnEx = Nothing
b = MsgBox("Du Lieu da chep xong!", vbInformation + vbOKOnly, "Info")
Sheet2.Activate
Else
Exit Sub
End If
End Sub
[/highlight]
 

File đính kèm

  • GLTRAN.zip
    50 KB · Đọc: 299
Lần chỉnh sửa cuối:
Web KT
Back
Top Bottom