Thắc mắc kết nối Excel với Excel bằng ADO

Liên hệ QC

Hoàng Trọng Nghĩa

Chuyên gia GPE
Thành viên BQT
Moderator
Tham gia
17/8/08
Bài viết
8,610
Được thích
16,671
Giới tính
Nam
Tôi tạo một hàm kết nối trả về giá trị Boolean, thế nhưng chẳng hiểu tại sao, với tên file Excel bất kỳ (dù không tồn tại trong đường dẫn) nó vẫn trả về giá trị TRUE!

Mã:
Function AccConn(ByVal FileName As String) As Boolean
      On Error GoTo ErrorHandle
      Dim sAppPath As String, ConnString As String
      sAppPath = ThisWorkbook.Path & "\" & FileName
      
      ConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sAppPath _
                 & ";Extended Properties=Excel 8.0;"
                 
      Set gcnObj = CreateObject("ADODB.Connection")
      
      With gcnObj
          .Mode = 3
          .ConnectionTimeout = 30
          .CursorLocation = 3
          .ConnectionString = ConnString
          .Open
      End With
      
      AccConn = True
      gcnObj.Close
      
ErrorExit:
      Exit Function
ErrorHandle:
      AccConn = False
      Err.Clear
      Resume ErrorExit
End Function

Thủ tục Test:
Mã:
Sub Test()
      MsgBox AccConn("Value12.[B][COLOR=#ff0000]xls[/COLOR][/B]")
End Sub

Thế nhưng lạ ở chỗ đổi phần đuôi xls thành cái gì đó nó lại báo FALSE.

Xin cho biết lý do gì? Hàm tôi sai ở đâu?
 

File đính kèm

  • ExcelADO.xls
    30.5 KB · Đọc: 21
Xin lỗi phải hỏi lại, làm ơn hướng dẫn mình đề tài này! Cảm ơn rất nhiều ạ!
 
Upvote 0
Sao mình thấy code lạ quá! Bạn gán AccConn = True thì nó luôn trả về true thôi, đâu có đề kiện gì để trả về False, chỉ khi có lỗi (phần đuôi xls thành cái gì đó) tìm không ra file thì mới nhảy về ErrorHandle --> False. Mình chỉ nghỉ vậy thôi chớ chưa dám khẳng định vì Nghĩa hiểu VBA nói chung và ADO nói riêng hơn mình mà. Nếu không phải nhờ các bạn giải thích cho mình luôn với!
 
Upvote 0
Tôi tạo một hàm kết nối trả về giá trị Boolean, thế nhưng chẳng hiểu tại sao, với tên file Excel bất kỳ (dù không tồn tại trong đường dẫn) nó vẫn trả về giá trị TRUE!



Thủ tục Test:
Mã:
Sub Test()
      MsgBox AccConn("Value12.[B][COLOR=#ff0000]xls[/COLOR][/B]")
End Sub

Thế nhưng lạ ở chỗ đổi phần đuôi xls thành cái gì đó nó lại báo FALSE.

Xin cho biết lý do gì? Hàm tôi sai ở đâu?

Kiểm tra sự tồn tại của 1 file, đương nhiên phải dùng Scripting.FileSystemObject rồi
Tôi không rành ADO, chỉ suy luận logic rồi sửa code thành:
Mã:
Function AccConn(ByVal FileName As String) As Boolean
  On Error GoTo ErrorHandle
  Dim sAppPath As String, ConnString As String
  With CreateObject("Scripting.FileSystemObject")
    sAppPath = ThisWorkbook.Path & "\" & FileName
    If .FileExists(sAppPath) Then
      ConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sAppPath _
                 & ";Extended Properties=Excel 8.0;"
                 
      Set gcnObj = CreateObject("ADODB.Connection")
      
      With gcnObj
          .Mode = 3
          .ConnectionTimeout = 30
          .CursorLocation = 3
          .ConnectionString = ConnString
          .Open
      End With
      AccConn = True
      gcnObj.Close
    End If
ErrorExit:
    Exit Function
ErrorHandle:
    AccConn = False
    Err.Clear
    Resume ErrorExit
  End With
End Function
 
Upvote 0
Sao mình thấy code lạ quá! Bạn gán AccConn = True thì nó luôn trả về true thôi, đâu có đề kiện gì để trả về False, chỉ khi có lỗi (phần đuôi xls thành cái gì đó) tìm không ra file thì mới nhảy về ErrorHandle --> False. Mình chỉ nghỉ vậy thôi chớ chưa dám khẳng định vì Nghĩa hiểu VBA nói chung và ADO nói riêng hơn mình mà. Nếu không phải nhờ các bạn giải thích cho mình luôn với!

Nó luôn luôn trả về True nếu nó kết nối, khi phát sinh lỗi, đương nhiên là không kết nối, thủ tục On Error GoTo ErrorHandle sẽ chuyển phần lỗi xuống nhãn ErrorHandle: và tại đây sẽ chạy qua thủ tục AccConn = False, vì thế lúc này hàm sẽ trả về giá trị FALSE. Nói tới đây chắc Anh đã hiểu.
 
Upvote 0
Kiểm tra sự tồn tại của 1 file, đương nhiên phải dùng Scripting.FileSystemObject rồi
Tôi không rành ADO, chỉ suy luận logic rồi sửa code thành:

...............

Thật ra cái Hàm đó ngoài việc kiểm tra file tồn tại ra nó còn kiểm tra kết nối vì thế nó như 2 trong 1 vậy. Cũng với cái hàm đó, em sửa lại kết nối với file Access thì chạy đúng 100% luôn em mới thắc mắc chứ!

Mã:
Public gcnObj As Object
'----------------------------------------------------------------------
Function AccConn(ByVal DBName As String) As Boolean
    On Error GoTo ErrorHandle
    
    Dim sAppPath As String, ConnString As String
    
    sAppPath = ThisWorkbook.Path & "\" & DBName
    
    [B][COLOR=#ff0000]ConnString = "Driver={Microsoft Access Driver (*.mdb)};" _
                     & "Dbq=" & sAppPath & "; UID=Admin; PWD=;"[/COLOR][/B]
    
    Set gcnObj = CreateObject("ADODB.Connection")
    
    With gcnObj
        .Mode = 3
        .ConnectionTimeout = 30
        .CursorLocation = 3
        .ConnectionString = ConnString
        .Open
    End With
    
    AccConn = True
    
    gcnObj.Close

ErrorExit:
    Exit Function
ErrorHandle:
    AccConn = False
    Err.Clear
    Resume ErrorExit
End Function

PHP:
Sub test()
      MsgBox AccConn("LienKet.mdb")
End Sub

Từ đó em đang suy nghĩ phải chăng có gì đó không ổn giữa kết nối Excel với Access tại dòng màu đỏ mà ra? Phải chăng với kết nối với Excel phải thêm một thuộc tính nào nữa chăng?
 
Upvote 0
Đối việc kết nối với Excel thì lại khác khi kết nối với Ms Access.
Nếu em thay đổi *.xlsx (hay *.xls) thành tên khác thì
Mã:
External table is not in the expected format.

Đối với Ms Access thì việc đổi tên, em vẫn kết nối được. Chính vì điều này, một số người viết ứng dụng đổi "mdb" thành bất cứ gì "abc", nên nếu không chú ý, mình không biết đâu là CSDL của chương trình đang chạy.
Mặc dù vậy ta vẫn có cách, khi chạy ứng dụng kiểu này, nếu để ý, sẽ có tập tin *.ldb xuất hiện. Vậy thì "dấu đầu lòi đuôi".

Lê Văn Duyệt

Tham khảo.
 
Lần chỉnh sửa cuối:
Upvote 0
Mã:
      ConnString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
              "Data Source=" & sAppPath & ";" & _
              "Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"

kyo dùng thế này thì nếu đúng tên file thì mới là True, còn sai tên file thì là False mặc dù vẫn là đuôi .xls
Còn dùng như anh ở trên thì dù là sai tên file, miễn sao vẫn là đuôi .xls thì đều báo True cả.
Tất nhiên là cái này vẫn chỉ giải quyết được đuôi file .xls thôi, còn xlsx thì phải chỉnh lại.

Với đuôi file .xlsx (Excel 2007) thì đổi một chút như thế này:
Mã:
      ConnString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
              "Data Source=" & sAppPath & ";" & _
              "Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"
 
Lần chỉnh sửa cuối:
Upvote 0
Mã:
      ConnString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
              "Data Source=" & sAppPath & ";" & _
              "Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"

kyo dùng thế này thì nếu đúng tên file thì mới là True, còn sai tên file thì là False mặc dù vẫn là đuôi .xls
Còn dùng như anh ở trên thì dù là sai tên file, miễn sao vẫn là đuôi .xls thì đều báo True cả.
Tất nhiên là cái này vẫn chỉ giải quyết được đuôi file .xls thôi, còn xlsx thì phải chỉnh lại.

Cám ơn Kyo, vấn đề đã được giải quyết! Nếu mở rộng ra Excel 2007 hay 2010 thì phải làm thế nào?
 
Upvote 0
Cám ơn Kyo, vấn đề đã được giải quyết! Nếu mở rộng ra Excel 2007 hay 2010 thì phải làm thế nào?

Kyo mới sửa lại bài trên đó anh, anh xem bài trên nhé. Dùng kết nối luôn Excel 2007 cũng kiểm tra được đuôi .xls của Excel 2003 luôn anh, kyo mới test thử.
 
Upvote 0
Kyo mới sửa lại bài trên đó anh, anh xem bài trên nhé. Dùng kết nối luôn Excel 2007 cũng kiểm tra được đuôi .xls của Excel 2003 luôn anh, kyo mới test thử.

Vậy có thể nó xài luôn 2010 được! Phiên bản sau xài trước được nhỉ? Hay thật!

Cho hỏi thêm, nếu kết nối với Access 2007 thì thủ tục đó sẽ đổi thành thế nào?
 
Upvote 0
Vậy có thể nó xài luôn 2010 được! Phiên bản sau xài trước được nhỉ? Hay thật!

Cho hỏi thêm, nếu kết nối với Access 2007 thì thủ tục đó sẽ đổi thành thế nào?

Mã:
      ConnString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
              "Data Source=" & sAppPath & ";"
Đây anh, bỏ bớt chút là xài được thôi.
 
Upvote 0
Mã:
      ConnString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
              "Data Source=" & sAppPath & ";"
Đây anh, bỏ bớt chút là xài được thôi.

Yeah! Đúng là tuyệt vời! Mình có thể xài nhiều phiên bản trước và sau với thủ tục này! Cám ơn Kyo nhiều!
 
Upvote 0
Bác ơi, khoản này thì xử lý thế nào ạ? em đã dùng cả driver Excel 12.0 thì lại mọc ra lỗi khác. Bác có cách nào xử lý chưa??

Đối việc kết nối với Excel thì lại khác khi kết nối với Ms Access.
Nếu em thay đổi *.xlsx (hay *.xls) thành tên khác thì
Mã:
External table is not in the expected format.

Đối với Ms Access thì việc đổi tên, em vẫn kết nối được. Chính vì điều này, một số người viết ứng dụng đổi "mdb" thành bất cứ gì "abc", nên nếu không chú ý, mình không biết đâu là CSDL của chương trình đang chạy.
Mặc dù vậy ta vẫn có cách, khi chạy ứng dụng kiểu này, nếu để ý, sẽ có tập tin *.ldb xuất hiện. Vậy thì "dấu đầu lòi đuôi".

Lê Văn Duyệt

Tham khảo.
 
Upvote 0
Web KT
Back
Top Bottom