Bài tập về ADO căn bản.

Liên hệ QC
Anh giúp em tiếp với
1. Trường hợp lấy dữ liều truyền vào mãng thì dùng rstArr = lrs.GetRows
Nhưng nếu em lấy dữ liệu là Range thì dùng câu lệnh nào vậy anh? Set rstRng = ???
2. Nếu lấy được dữ liệu như trên để tìm kiếm 1 phần tử nào đó thì dĩ nhiên được. Nhưng cho em hỏi ADO có thể tìm kiếm trực tiếp trong file DataBase ? VD như tìm vị trí AI.31210 ở trường 1 file DataBase giống như VBA dùng Find() vậy
 
File Access có thể lưu dữ liệu 2Gb, như vậy số lượng dòng còn tùy thuộc vào dung lượng file access của anh.
Anh có thể tham khảo ví dụ ở
ADO căn bản: Kết nối truy vấn CSDL từ file Excel đến file Access.
Thảo luận về bài: ADO căn bản "Kết nối truy vấn CSDL từ file Excel đến file Access."

Nghĩa được biết, ở phiên bản Access 2003, mỗi Table có dung lượng lên tới 1Gb, hỏng lẽ theo Hai Lúa nói thì người ta chỉ sử dụng được 2 Table tối đa 2Gb thôi sao ta?

  • Fields
    • Access restricts field names to 64 characters. There is a maximum of 255 fields per table. Text fields can store 255 characters of data. Memo fields can store up to 65, 535 characters of data if it is entered within Access. If you enter the data programmatically, however, then there is 2 gigabytes of character storage per memo field. OLE Object files can store 1 gigabyte of data. Field descriptions and field property settings are limited to 255 characters.
    Tables

    • Access also limits table names to 64 characters. Tables can contain up to 2 gigabytes of data, excluding the space that is needed for system objects. You can open 2,048 tables if you have sufficient computer memory and processing power. A table can have as many as 32 indexes with a maximum of 10 fields in an index.
    Database

    • An Access database is limited to 2 gigabytes of storage in a single database. If you use a split database, however, you can connect to thousands of database files on a network share with only the front-end database loaded on your computer.



Nguồn: http://www.ehow.com/facts_7575269_much-data-can-access-hold.html


Giờ mới nắm rõ hơn về dung lượng của nó.
 
Chỉnh sửa lần cuối bởi điều hành viên:
1. Trường hợp lấy dữ liều truyền vào mãng thì dùng rstArr = lrs.GetRows
Nhưng nếu em lấy dữ liệu là Range thì dùng câu lệnh nào vậy anh? Set rstRng = ???
2. Nếu lấy được dữ liệu như trên để tìm kiếm 1 phần tử nào đó thì dĩ nhiên được. Nhưng cho em hỏi ADO có thể tìm kiếm trực tiếp trong file DataBase ? VD như tìm vị trí AI.31210 ở trường 1 file DataBase giống như VBA dùng Find() vậy
Các anh chị giúp cho trường hợp này với
Xin cảm ơn các anh chị
 
Anh giúp em tiếp với
1. Trường hợp lấy dữ liều truyền vào mãng thì dùng rstArr = lrs.GetRows
Nhưng nếu em lấy dữ liệu là Range thì dùng câu lệnh nào vậy anh? Set rstRng = ???
2. Nếu lấy được dữ liệu như trên để tìm kiếm 1 phần tử nào đó thì dĩ nhiên được. Nhưng cho em hỏi ADO có thể tìm kiếm trực tiếp trong file DataBase ? VD như tìm vị trí AI.31210 ở trường 1 file DataBase giống như VBA dùng Find() vậy

1./ Chưa hiểu câu hỏi của anh
2./ Anh có thể dùng điều kiện là where thử còn về find nó như sau:

[GPECODE=sql]Tenrecordset.Find "TenTruong ='DieuKienTimKiem'"[/GPECODE]

Nhưng mất nhiều thời gian để tìm, ví dụ như sau:

[GPECODE=sql]Sub Tim_ADO()
Dim lsSQL As String, cnn As Object, lrs As Object
Set cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
With cnn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.Path & "\DataBase2.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "SELECT * " & _
"FROM [Data$] "
lrs.Open lsSQL, cnn, 3, 1
With lrs
.Find "MDM ='AA.11212'"
If Not .EOF Then
Do While Not .EOF
Debug.Print .Fields("MDM").Value
.Find "MDM ='AA.11212'", SkipRecords:=1
Loop
Else
MsgBox "Khong tim thay danh muc nay"
End If
.Close
End With
Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub

[/GPECODE]
 
1./ Chưa hiểu câu hỏi của anh
2./ Anh có thể dùng điều kiện là where thử còn về find nó như sau:
Em muốn xác định vị trí nó (hàng mấy trong file DataBase.xls) chứ anh Debug.Print .Fields("MDM").Value thì in ra lại giá trị nó thì làm gì
Trường hợp 1: Ý em là lấy dữ liệu ở file DataBase.xls là 1 Range (không biết dùng lệnh nào) chứ không phải là Array như ở trên (sử dụng lệnh GetRows)
Em cảm ơn.
 
Lần chỉnh sửa cuối:
1./ Em muốn xác định vị trí nó (hàng mấy trong file DataBase.xls) chứ anh Debug.Print .Fields("MDM").Value thì in ra lại giá trị nó thì làm gì
2./ Trường hợp 1: Ý em là lấy dữ liệu ở file DataBase.xls là 1 Range (không biết dùng lệnh nào) chứ không phải là Array như ở trên (sử dụng lệnh GetRows)
Em cảm ơn.
1./ Anh dùng absoluteposition để xác định dòng của nó:

[GPECODE=sql]Sub Tim_ADO()
Dim lsSQL As String, cnn As Object, lrs As Object
Set cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
With cnn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.Path & "\DataBase2.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "SELECT * " & _
"FROM [Data$] "
lrs.Open lsSQL, cnn, 3, 1
With lrs
.Find "MDM ='AA.11212'"
If Not .EOF Then
Do While Not .EOF
MsgBox "Danh muc " & .Fields("MDM").Value & " dang nam o dong thu " & lrs.absoluteposition + 1 & " trong csdl"
.Find "MDM ='AA.11212'", SkipRecords:=1
Loop
Else
MsgBox "Khong tim thay danh muc nay"
End If
.Close
End With

Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub[/GPECODE]

2./ Anh dùng CopyFromRecordset để lấy dữ liệu như sau:

[GPECODE=sql]Sub Trich_ADO()
Dim lsSQL As String, cnn As Object, lrs As Object
Set cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
With cnn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.Path & "\DataBase2.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "SELECT * " & _
"FROM [Data$] "
lrs.Open lsSQL, cnn, 3, 1
Range("A2").CopyFromRecordset lrs
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub[/GPECODE]
 
1./ Anh dùng absoluteposition để xác định dòng của nó:

Mã:
Sub Tim_ADO()
'............................
    lsSQL = "SELECT[COLOR=#ff0000] * FROM [Data$] [/COLOR]"
       '...........................
End Sub

Hai Lúa cho tôi hỏi 1 chuyện.. nhỏ
Trong trường hợp tôi muốn lấy dữ liệu tại 1 file nhưng không biết tên sheet, cũng không biết địa chỉ vùng là gì.. Đại khái muốn lấy tất cả dữ liệu của sheet đầu tiên thì lsSQL = "SELECT * Cái gì đây? "
 
Hai Lúa cho tôi hỏi 1 chuyện.. nhỏ
Trong trường hợp tôi muốn lấy dữ liệu tại 1 file nhưng không biết tên sheet, cũng không biết địa chỉ vùng là gì.. Đại khái muốn lấy tất cả dữ liệu của sheet đầu tiên thì lsSQL = "SELECT * Cái gì đây? "

thì dùng VBA xác định tên sheet đầu tiên thôi:

PHP:
ShName = WB.Sheets(1).Name
...
lsSQL = "SELECT * from " & ShName & "$" & ... "Ẹc ẹc"
 
thì dùng VBA xác định tên sheet đầu tiên thôi:

PHP:
ShName = WB.Sheets(1).Name
...
lsSQL = "SELECT * from " & ShName & "$" & ... "Ẹc ẹc"

Nhưng file chưa mở thì lấy gì mà xác định sư phụ
Ý em đang nói là file đang đóng nha (vì nếu đã mở lên rồi thì khỏi cần ADO làm gì)
 
Hai Lúa cho tôi hỏi 1 chuyện.. nhỏ
Trong trường hợp tôi muốn lấy dữ liệu tại 1 file nhưng không biết tên sheet, cũng không biết địa chỉ vùng là gì.. Đại khái muốn lấy tất cả dữ liệu của sheet đầu tiên thì lsSQL = "SELECT * Cái gì đây? "

Cho em hỏi thêm là lấy ở file hiện hành hay là lấy từ 1 file khác?
 
Đương nhiên mình hỏi file khác rồi (vì nếu file hiện hành thì Sheets(1).Name là có ngay tên sheet rồi còn gì)

Thầy thử dùng cat.Tables(0).Name để lấy tên bảng đầu tiên nhé:

[GPECODE=sql]Sub TruyVan_ADO()
Dim cn As Object, rst As Object, cat As Object, tbl As Object
Set cn = CreateObject("ADODB.Connection")
Set cat = CreateObject("ADOX.Catalog")
Set tbl = CreateObject("ADOX.Table")
Set rst = CreateObject("ADODB.Recordset")
With cn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.Path & _
"\Database.xls;Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
cat.ActiveConnection = cn
With rst
.ActiveConnection = cn
.Open "select * from [" & cat.Tables(0).Name & "]"
End With
With Sheets("KetQua")
.[A2:IV65000].ClearContents
.[A2].CopyFromRecordset rst
End With
rst.Close: Set rst = Nothing
cn.Close: Set cn = Nothing
Set cat = Nothing: Set tbl = Nothing

End Sub

[/GPECODE]
 

File đính kèm

  • LayTenBang.rar
    22.4 KB · Đọc: 77
Thầy thử dùng cat.Tables(0).Name để lấy tên bảng đầu tiên nhé:

Má ơi! Mình đã làm nó từ đời nào rồi:
http://www.giaiphapexcel.com/forum/showthread.php?25407-Lấy-danh-sách-tên-các-Sheet-từ-file-excel
Lâu quá không dợt đúng là chẳng nhớ gì cả
-------------------
Từ đó suy ra cái thằng cat.Tables(0).Name chưa chắc là tên sheet đầu tiên đâu nha (nếu trong file có chứa Define Name)
 
Lần chỉnh sửa cuối:
Má ơi! Mình đã làm nó từ đời nào rồi:
http://www.giaiphapexcel.com/forum/showthread.php?25407-L%E1%BA%A5y-danh-s%C3%A1ch-t%C3%AAn-c%C3%A1c-Sheet-t%E1%BB%AB-file-excel
Lâu quá không dợt đúng là chẳng nhớ gì cả
-------------------
Từ đó suy ra cái thằng cat.Tables(0).Name chưa chắc là tên sheet đầu tiên đâu nha (nếu trong file có chứa Define Name)
Thì mình dùng vòng lặp duyệt qua để lấy tên sheet đầu được mà Thầy. Nói chung thì tuỳ từng trường hợp mà ta có cách giải quyết khác nhau.
 
Thì mình dùng vòng lặp duyệt qua để lấy tên sheet đầu được mà Thầy. Nói chung thì tuỳ từng trường hợp mà ta có cách giải quyết khác nhau.

Vâng! Xong vụ này xem như đã xong cái hàm GetData. Post lên Hai Lúa kiểm tra thử nha
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
  Dim lCount As Long, lR As Long, lC As Long
  
  Set rsCon = CreateObject("ADODB.Connection")
  Set rsData = CreateObject("ADODB.Recordset")
  Set cat = CreateObject("ADOX.Catalog")
  
  If Val(Application.Version) < 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
  
  rsCon.Open szConnect
  cat.ActiveConnection = rsCon
  
  If SheetName = "" Then
    For Each tbl In cat.Tables
      If (Right(tbl.Name, 1) = "$") Or (Right(tbl.Name, 2) = "$'") Then
        SheetName = tbl.Name
        Exit For
      End If
    Next
  End If
  If Right(SheetName, 1) = "'" Then SheetName = Mid(SheetName, 2, Len(SheetName) - 2)
  If Right(SheetName, 1) <> "$" Then SheetName = SheetName & "$"
  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
----------
Áp dụng: Lấy dữ liệu tại file Source.xls (cùng thư mục), tại sheet đầu tiên
Mã:
Sub GetData_Example()
  Dim Arr
  Arr = GetData(ThisWorkbook.Path & "\Source.xls", "", "", True, True)
  Range("A1").Resize(UBound(Arr, 1) + 1, UBound(Arr, 2) + 1).Value = Arr
End Sub
 

File đính kèm

  • ADO_Test.rar
    18.5 KB · Đọc: 131
Lần chỉnh sửa cuối:
Vâng! Xong vụ này xem như đã xong cái hàm GetData. Post lên Hai Lúa kiểm tra thử nha

Kiểm tra kỹ lại thấy vẫn.. không ăn thua
Cái thằng cat.Tables này nó sort theo thứ tự ABC nên trường hợp Sheet1 có tển là "Z..." còn Sheet2 có tên là "A..." thì nó sẽ lấy sheet2
Hic...
Khó nhai nhỉ?
Chẳng lẽ phải dùng SheetName = GetObject(fileName).Worksheets(1).Name
Vô duyên quá!
 
1./ Anh dùng absoluteposition để xác định dòng của nó:

[GPECODE=sql]Sub Tim_ADO()
Dim lsSQL As String, cnn As Object, lrs As Object
Set cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
With cnn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.Path & "\DataBase2.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "SELECT * " & _
"FROM [Data$] "
lrs.Open lsSQL, cnn, 3, 1
With lrs
.Find "MDM ='AA.11212'"
If Not .EOF Then
Do While Not .EOF
MsgBox "Danh muc " & .Fields("MDM").Value & " dang nam o dong thu " & lrs.absoluteposition + 1 & " trong csdl"
.Find "MDM ='AA.11212'", SkipRecords:=1
Loop
Else
MsgBox "Khong tim thay danh muc nay"
End If
.Close
End With

Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub[/GPECODE]

2./ Anh dùng CopyFromRecordset để lấy dữ liệu như sau:

[GPECODE=sql]Sub Trich_ADO()
Dim lsSQL As String, cnn As Object, lrs As Object
Set cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
With cnn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.Path & "\DataBase2.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "SELECT * " & _
"FROM [Data$] "
lrs.Open lsSQL, cnn, 3, 1
Range("A2").CopyFromRecordset lrs
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub[/GPECODE]
Cảm ơn Anh đã giúp đỡ
1./ Dùng absoluteposition để xác định dòng của nó:
Cái này đã đúng ý em
2./ Dùng CopyFromRecordset để lấy dữ liệu:
Nếu như cái này thì Anh đã giúp ở bài 15 rồi. Tương tự như vậy nhưng Ý em là gán vùng dữ liệu vào Range trước khi đưa dữ liệu xuống bảng tính
Đại khai code của nó là:
set Rng=?? (không biết cấu lệnh như thế nào) 'Câu lệnh này em muốn hỏi
Rng.Copy Range("A2").Paste 'copy Rng xuống bảng tính
Anh thông cảm vì là muốn học thêm kỹ về ADO nên hỏi anh từng cái một để kiến thức vững hơn
 
2./
set Rng=?? (không biết cấu lệnh như thế nào) 'Câu lệnh này em muốn hỏi
Rng.Copy Range("A2").Paste 'copy Rng xuống bảng tính
Anh thông cảm vì là muốn học thêm kỹ về ADO nên hỏi anh từng cái một để kiến thức vững hơn
Làm chi cho nó lòng vòng vậy anh? sao ta không xác định luôn ngay từ đầu cái vùng đó rồi gán xuống luôn?
 
Web KT
Back
Top Bottom