Điều kiện để xác định Sheet có tồn tại trong Workbook, sử dụng ADO

Liên hệ QC

themorzer

Thành viên chính thức
Tham gia
24/5/13
Bài viết
95
Được thích
1
Chao mọi người, mình sử dụng code Getdata của thầy Ndu, nhưng với code này thì Workbook chỉ mở khi có tồn tại Sheet cần mở, còn nếu Sheet đó không có thì báo lỗi
Mã:
Function GetData(ByVal FileName As String, ByVal SheetName As String, ByVal RangeAddress As String, _
            ByVal HasTitle As Boolean, ByVal UseTitle As Boolean)
            
  Dim rsCon As Object, rsData As Object, cat As Object, tbl As Object
  Dim tmpArr, Arr()
  Dim szConnect As String, szSQL As String, tmp As String
  Dim lCount As Long, lR As Long, lC As Long, lVer As Long
  lVer = Val(Application.Version)
  Set rsCon = CreateObject("ADODB.Connection")
  Set rsData = CreateObject("ADODB.Recordset")
  Set cat = CreateObject("ADOX.Catalog")
 
  If lVer < 12 Then
    szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FileName & ";" & _
                "Extended Properties=""Excel 8.0;HDR=" & IIf(HasTitle, "Yes", "No") & """;"
  Else
    szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & FileName & ";" & _
                "Extended Properties=""Excel 12.0;HDR=" & IIf(HasTitle, "Yes", "No") & """;"
  End If
  If SheetName = "" Then
    Dim Dbs  As Object, db As Object
    Set Dbs = CreateObject("DAO.DBEngine." & IIf(lVer < 12, "36", "120"))
    Set db = Dbs.OpenDatabase(FileName, False, False, "Excel 8.0;")
    tmp = db.TableDefs(0).Name
    tmp = Replace(tmp, " ", "?")
    tmp = Replace(tmp, "'", " ")
    tmp = WorksheetFunction.Trim(tmp)
    tmp = Replace(tmp, " ", "'")
    tmp = Replace(tmp, "?", " ")
    SheetName = tmp
    db.Close
    Set Dbs = Nothing: Set db = Nothing
  End If
  If Right(SheetName, 1) <> "$" Then SheetName = SheetName & "$"
  rsCon.Open szConnect
  cat.ActiveConnection = rsCon
 
  szSQL = "SELECT * FROM [" & SheetName & RangeAddress & "];"
  rsData.Open szSQL, rsCon, 0, 1, 1
  tmpArr = rsData.GetRows
  ReDim Arr(UBound(tmpArr, 2) - UseTitle, UBound(tmpArr, 1) + 1)
  If UseTitle Then
    For lC = LBound(tmpArr, 1) To UBound(tmpArr, 1)
      Arr(0, lC) = rsData.Fields(lC).Name
    Next
  End If
  For lR = LBound(tmpArr, 2) To UBound(tmpArr, 2)
    For lC = LBound(tmpArr, 1) To UBound(tmpArr, 1)
      Arr(lR - UseTitle, lC) = tmpArr(lC, lR)
    Next
  Next
  rsData.Close: Set rsData = Nothing
  rsCon.Close: Set rsCon = Nothing
  GetData = Arr
End Function
-Vậy đặt điều kiện thế nào trong hàm Getdata này để chương trình biết Sheet đó có tồn tại hay không
+ Nếu có tồn tại thì thực hiện tiếp chương trình
+ Nếu không tồn tại thì bỏ qua
 
Chao mọi người, mình sử dụng code Getdata của thầy Ndu, nhưng với code này thì Workbook chỉ mở khi có tồn tại Sheet cần mở, còn nếu Sheet đó không có thì báo lỗi
Mã:
Function GetData(ByVal FileName As String, ByVal SheetName As String, ByVal RangeAddress As String, _
            ByVal HasTitle As Boolean, ByVal UseTitle As Boolean)
           
  Dim rsCon As Object, rsData As Object, cat As Object, tbl As Object
  Dim tmpArr, Arr()
  Dim szConnect As String, szSQL As String, tmp As String
  Dim lCount As Long, lR As Long, lC As Long, lVer As Long
  lVer = Val(Application.Version)
  Set rsCon = CreateObject("ADODB.Connection")
  Set rsData = CreateObject("ADODB.Recordset")
  Set cat = CreateObject("ADOX.Catalog")

  If lVer < 12 Then
    szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FileName & ";" & _
                "Extended Properties=""Excel 8.0;HDR=" & IIf(HasTitle, "Yes", "No") & """;"
  Else
    szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & FileName & ";" & _
                "Extended Properties=""Excel 12.0;HDR=" & IIf(HasTitle, "Yes", "No") & """;"
  End If
  If SheetName = "" Then
    Dim Dbs  As Object, db As Object
    Set Dbs = CreateObject("DAO.DBEngine." & IIf(lVer < 12, "36", "120"))
    Set db = Dbs.OpenDatabase(FileName, False, False, "Excel 8.0;")
    tmp = db.TableDefs(0).Name
    tmp = Replace(tmp, " ", "?")
    tmp = Replace(tmp, "'", " ")
    tmp = WorksheetFunction.Trim(tmp)
    tmp = Replace(tmp, " ", "'")
    tmp = Replace(tmp, "?", " ")
    SheetName = tmp
    db.Close
    Set Dbs = Nothing: Set db = Nothing
  End If
  If Right(SheetName, 1) <> "$" Then SheetName = SheetName & "$"
  rsCon.Open szConnect
  cat.ActiveConnection = rsCon

  szSQL = "SELECT * FROM [" & SheetName & RangeAddress & "];"
  rsData.Open szSQL, rsCon, 0, 1, 1
  tmpArr = rsData.GetRows
  ReDim Arr(UBound(tmpArr, 2) - UseTitle, UBound(tmpArr, 1) + 1)
  If UseTitle Then
    For lC = LBound(tmpArr, 1) To UBound(tmpArr, 1)
      Arr(0, lC) = rsData.Fields(lC).Name
    Next
  End If
  For lR = LBound(tmpArr, 2) To UBound(tmpArr, 2)
    For lC = LBound(tmpArr, 1) To UBound(tmpArr, 1)
      Arr(lR - UseTitle, lC) = tmpArr(lC, lR)
    Next
  Next
  rsData.Close: Set rsData = Nothing
  rsCon.Close: Set rsCon = Nothing
  GetData = Arr
End Function
-Vậy đặt điều kiện thế nào trong hàm Getdata này để chương trình biết Sheet đó có tồn tại hay không
+ Nếu có tồn tại thì thực hiện tiếp chương trình
+ Nếu không tồn tại thì bỏ qua
Vậy thì tốt nhất là bạn viết thêm 1 hàm kiểm tra xem sheet có tồn tại không, nếu tồn tại thì chạy hàm getdata, không thì không chạy nữa.
 
Upvote 0
Chao mọi người, mình sử dụng code Getdata của thầy Ndu, nhưng với code này thì Workbook chỉ mở khi có tồn tại Sheet cần mở, còn nếu Sheet đó không có thì báo lỗi
Mã:
Function GetData(ByVal FileName As String, ByVal SheetName As String, ByVal RangeAddress As String, _
            ByVal HasTitle As Boolean, ByVal UseTitle As Boolean)
           
  Dim rsCon As Object, rsData As Object, cat As Object, tbl As Object
  Dim tmpArr, Arr()
  Dim szConnect As String, szSQL As String, tmp As String
  Dim lCount As Long, lR As Long, lC As Long, lVer As Long
  lVer = Val(Application.Version)
  Set rsCon = CreateObject("ADODB.Connection")
  Set rsData = CreateObject("ADODB.Recordset")
  Set cat = CreateObject("ADOX.Catalog")

  If lVer < 12 Then
    szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FileName & ";" & _
                "Extended Properties=""Excel 8.0;HDR=" & IIf(HasTitle, "Yes", "No") & """;"
  Else
    szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & FileName & ";" & _
                "Extended Properties=""Excel 12.0;HDR=" & IIf(HasTitle, "Yes", "No") & """;"
  End If
  If SheetName = "" Then
    Dim Dbs  As Object, db As Object
    Set Dbs = CreateObject("DAO.DBEngine." & IIf(lVer < 12, "36", "120"))
    Set db = Dbs.OpenDatabase(FileName, False, False, "Excel 8.0;")
    tmp = db.TableDefs(0).Name
    tmp = Replace(tmp, " ", "?")
    tmp = Replace(tmp, "'", " ")
    tmp = WorksheetFunction.Trim(tmp)
    tmp = Replace(tmp, " ", "'")
    tmp = Replace(tmp, "?", " ")
    SheetName = tmp
    db.Close
    Set Dbs = Nothing: Set db = Nothing
  End If
  If Right(SheetName, 1) <> "$" Then SheetName = SheetName & "$"
  rsCon.Open szConnect
  cat.ActiveConnection = rsCon

  szSQL = "SELECT * FROM [" & SheetName & RangeAddress & "];"
  rsData.Open szSQL, rsCon, 0, 1, 1
  tmpArr = rsData.GetRows
  ReDim Arr(UBound(tmpArr, 2) - UseTitle, UBound(tmpArr, 1) + 1)
  If UseTitle Then
    For lC = LBound(tmpArr, 1) To UBound(tmpArr, 1)
      Arr(0, lC) = rsData.Fields(lC).Name
    Next
  End If
  For lR = LBound(tmpArr, 2) To UBound(tmpArr, 2)
    For lC = LBound(tmpArr, 1) To UBound(tmpArr, 1)
      Arr(lR - UseTitle, lC) = tmpArr(lC, lR)
    Next
  Next
  rsData.Close: Set rsData = Nothing
  rsCon.Close: Set rsCon = Nothing
  GetData = Arr
End Function
-Vậy đặt điều kiện thế nào trong hàm Getdata này để chương trình biết Sheet đó có tồn tại hay không
+ Nếu có tồn tại thì thực hiện tiếp chương trình
+ Nếu không tồn tại thì bỏ qua
Nếu không tìm thấy sheet thì... nghỉ chơi, đúng không? Vậy cứ đơn giản hóa vấn đề bằng câu lệnh:
Mã:
On Error Goto NghiChoi
.......
NghiChoi: Exit Function
Hoặc
Mã:
On Error Resume Next
If Err.Number then Exit Function
Đại khái vậy đi!
 
Upvote 0
Sheet mà cũng chưa biết có tồn tại hay không thì dữ liệu nó query ra lấy gì làm tin tưởng?
Loại query này chỉ dùng lấy lượng đè phẩm.
 
Upvote 0
Sheet mà cũng chưa biết có tồn tại hay không thì dữ liệu nó query ra lấy gì làm tin tưởng?
Loại query này chỉ dùng lấy lượng đè phẩm.
do công việc lấy dữ liệu từ khách hàng để trích lọc ra, nhưng dữ liệu khách hàng gửi có khi không tồn tại Sheet mà mình đã chọn
 
Upvote 0
do công việc lấy dữ liệu từ khách hàng để trích lọc ra, nhưng dữ liệu khách hàng gửi có khi không tồn tại Sheet mà mình đã chọn
Đã nói là lượng đè phẩm thì là lượng đè phẩm.
Nếu cả cái sheet cũng không biết có tồn tại hay không thì lấy dữ liệu đủ thiếu thế nào có kiểm tra được chăng?
Ví dụ có 100.000 dòng mà query nó chỉ lấy 65.000 dòng thì có biết không?
 
Upvote 0
Đã nói là lượng đè phẩm thì là lượng đè phẩm.
Nếu cả cái sheet cũng không biết có tồn tại hay không thì lấy dữ liệu đủ thiếu thế nào có kiểm tra được chăng?
Ví dụ có 100.000 dòng mà query nó chỉ lấy 65.000 dòng thì có biết không?
Cám ơn ban đã trả lời, nhưng bạn hiểu sai ý mình,
VD: - ngày hôm này khách hàng gửi dữ liệu cho mình xử lý, trong đó có 3 Sheet là A,B,C
- nhưng qua ngày hôm sau khách hàng gửi cho mình tiếp file nhưng trong đó có 4 Sheet A,B,C,D, những ngày khác thì có Sheet A,C,D
- những ngày khác thì có 5 Sheet A,B,C,D,E, vì vậy mới cần xét có tồn tại 1 Sheet
Dữ liêu khách hàng gửi chỉ Max là 10000 dòng, không hơn
 
Upvote 0
Tôi chỉ nói là dùng chính sách câu được con gì ăn con nấy có ngày gặp con cá nốc.
Nhìn cái code truy vấn dữ liệu trên thì biết chuyện. Việc hiểu ý bạn hay không nó đâu phải là vấn đề.
Nếu cái tên sheet còn chưa biết có tồn tại hay không thì có chắc gì người lập file đã đặt đúng dữ liệu vào nó? Ví dụ người ta bình thường đặt tên ABC cho bảng dữ liệu A, bây giờ nổi hứng đặt là DEF, tên ABC thì đặt cho dữ liệu B thì sao?

Truy vấn dữ liệu từ Database có 2 giai đoạn, một là kết nối và hai là truy xuất dữ liệu. Cả hai giai đoạn này đều có khả năng bị vấn đề. Muốn biết giai đoạn nào bị vướng thì tách riêng chúng ra. (thực ra còn giai đoạn thứ 3 là đọc và dịch, tổng hợp dữ liệu truy vấn được, nhưng code tổng quát như trên thì không kể)
Ngừoi sử dụng ADODB phải biết những vấn đề của nó để kiểm soát.
 
Upvote 0
Nếu không tìm thấy sheet thì... nghỉ chơi, đúng không? Vậy cứ đơn giản hóa vấn đề bằng câu lệnh:
Mã:
On Error Goto NghiChoi
.......
NghiChoi: Exit Function
Hoặc
Mã:
On Error Resume Next
If Err.Number then Exit Function
Đại khái vậy đi!
Anh có thể cho em hỏi hàm getdata này tối da được bao nhiêu dòng vậy anh !.
 
Upvote 0
Chao mọi người, mình sử dụng code Getdata của thầy Ndu, nhưng với code này thì Workbook chỉ mở khi có tồn tại Sheet cần mở, còn nếu Sheet đó không có thì báo lỗi
Mã:
Function GetData(ByVal FileName As String, ByVal SheetName As String, ByVal RangeAddress As String, _
            ByVal HasTitle As Boolean, ByVal UseTitle As Boolean)
           
  Dim rsCon As Object, rsData As Object, cat As Object, tbl As Object
  Dim tmpArr, Arr()
  Dim szConnect As String, szSQL As String, tmp As String
  Dim lCount As Long, lR As Long, lC As Long, lVer As Long
  lVer = Val(Application.Version)
  Set rsCon = CreateObject("ADODB.Connection")
  Set rsData = CreateObject("ADODB.Recordset")
  Set cat = CreateObject("ADOX.Catalog")

  If lVer < 12 Then
    szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FileName & ";" & _
                "Extended Properties=""Excel 8.0;HDR=" & IIf(HasTitle, "Yes", "No") & """;"
  Else
    szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & FileName & ";" & _
                "Extended Properties=""Excel 12.0;HDR=" & IIf(HasTitle, "Yes", "No") & """;"
  End If
  If SheetName = "" Then
    Dim Dbs  As Object, db As Object
    Set Dbs = CreateObject("DAO.DBEngine." & IIf(lVer < 12, "36", "120"))
    Set db = Dbs.OpenDatabase(FileName, False, False, "Excel 8.0;")
    tmp = db.TableDefs(0).Name
    tmp = Replace(tmp, " ", "?")
    tmp = Replace(tmp, "'", " ")
    tmp = WorksheetFunction.Trim(tmp)
    tmp = Replace(tmp, " ", "'")
    tmp = Replace(tmp, "?", " ")
    SheetName = tmp
    db.Close
    Set Dbs = Nothing: Set db = Nothing
  End If
  If Right(SheetName, 1) <> "$" Then SheetName = SheetName & "$"
  rsCon.Open szConnect
  cat.ActiveConnection = rsCon

  szSQL = "SELECT * FROM [" & SheetName & RangeAddress & "];"
  rsData.Open szSQL, rsCon, 0, 1, 1
  tmpArr = rsData.GetRows
  ReDim Arr(UBound(tmpArr, 2) - UseTitle, UBound(tmpArr, 1) + 1)
  If UseTitle Then
    For lC = LBound(tmpArr, 1) To UBound(tmpArr, 1)
      Arr(0, lC) = rsData.Fields(lC).Name
    Next
  End If
  For lR = LBound(tmpArr, 2) To UBound(tmpArr, 2)
    For lC = LBound(tmpArr, 1) To UBound(tmpArr, 1)
      Arr(lR - UseTitle, lC) = tmpArr(lC, lR)
    Next
  Next
  rsData.Close: Set rsData = Nothing
  rsCon.Close: Set rsCon = Nothing
  GetData = Arr
End Function
-Vậy đặt điều kiện thế nào trong hàm Getdata này để chương trình biết Sheet đó có tồn tại hay không
+ Nếu có tồn tại thì thực hiện tiếp chương trình
+ Nếu không tồn tại thì bỏ qua
Mình có xem qua những bài trả lời của các thành viên và bài phản hồi của bạn thì mình có thiển ý thế này:

1. Nếu bạn biết sơ về code và chưa đủ giỏi thì không nên dùng code liên quan đến ADO
2. Nếu dùng ADO thì dữ liệu phải chuẩn, lơ mơ thì kết quả ra tè le
3. Nếu bạn tự tin trình độ code của bản thân thì có thể kết hợp ADO và vài tiểu xảo nhỏ thì việc xử lý yêu cầu của bạn dễ như trở bàn tay. Mình nghĩ cách chắc chắn là có, nhưng không ai rảnh mà nghiên cứu nếu việc đó không liên quan đến họ vì ai cũng bận lo kiếm cơm mà.
 
Upvote 0
Upvote 0
Với 65.536 dòng với 1 File thì được anh ạ ! Vượt quá thì không đuợc hoặc có thể em làm sai !
Cái giao diện của VBA với ADO nó được mặc đinh từ thời Excel 2003, chỉ có 65.536 dòng.
Về sau này, qua 2007, số dòng vượt trên đó nhưng cái giao diện mặc định thì cũng vậy. Có 1 vài cách để nó vượt qua giới hạn mặc định này. Nhưng để sửa cái code trên thì theo tôi không xứng đáng. Code trên chắc được viết trên 5 năm nay, cách thức viết cỗ rồi. Viết lại tốt hơn. Vả lại chắc hồi đó tác giả chưa rành lắm về các đối tượng cho nên tuy code vẫn chạy tốt nhưng đặt tên biến loạn xạ hết. Điển hình connection là cái đường kết nối, đâu có liên quan gì đến recordset, lại đặt tên rsCon !
 
Upvote 0
Cái giao diện của VBA với ADO nó được mặc đinh từ thời Excel 2003, chỉ có 65.536 dòng.
Về sau này, qua 2007, số dòng vượt trên đó nhưng cái giao diện mặc định thì cũng vậy. Có 1 vài cách để nó vượt qua giới hạn mặc định này. Nhưng để sửa cái code trên thì theo tôi không xứng đáng. Code trên chắc được viết trên 5 năm nay, cách thức viết cỗ rồi. Viết lại tốt hơn. Vả lại chắc hồi đó tác giả chưa rành lắm về các đối tượng cho nên tuy code vẫn chạy tốt nhưng đặt tên biến loạn xạ hết. Điển hình connection là cái đường kết nối, đâu có liên quan gì đến recordset, lại đặt tên rsCon !
Bác này cứ quan trọng hóa quá
Ở đây người ta cần mỗi mì ăn liền
Thì có người rót nước vào mì là húp xong
Có khi code cũng chạy 1 lần trong đời, trong năm
 
Upvote 0
Bác này cứ quan trọng hóa quá
Ở đây người ta cần mỗi mì ăn liền
Thì có người rót nước vào mì là húp xong
Có khi code cũng chạy 1 lần trong đời, trong năm
1. người ta là ai?
Tôi rất hiếm khi chỉ cho mì ăn liền. Dân quen diễn đàn này hầu hết đều biết rằng tôi chuyên chỉ cách code tổng quát.

2. chạy 1 lần trong đời?
Đọc cho kỹ yêu cầu của thớt rồi nói chuyện tiếp.
 
Upvote 0
1. người ta là ai?
Tôi rất hiếm khi chỉ cho mì ăn liền. Dân quen diễn đàn này hầu hết đều biết rằng tôi chuyên chỉ cách code tổng quát.

2. chạy 1 lần trong đời?
Đọc cho kỹ yêu cầu của thớt rồi nói chuyện tiếp.
Người ta= những người hỏi ở đây
Chạy 1 lần= nhiều câu hỏi ở diễn đàn này toàn đưa lên giúp, cần thay lại đưa lên - xử lý xon vứt bỏ (có thể không đúng với thớt này)
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom