Bài tập về ADO căn bản. (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Hai Lúa Miền Tây

❆❆❆❆❆❆❆❆
Thành viên BQT
Administrator
Tham gia
18/3/08
Bài viết
8,311
Được thích
15,874
Giới tính
Nam
Nghề nghiệp
Làm ruộng.
Bài 1:
Nhằm mục đích luyện tập và nâng cao kiến thức về ADO tôi xin mở topic này. Topic này chỉ dành cho những người mới học, bắt đầu học ADO như tôi tham gia.

Tôi có 2 Workbooks (A.xls và B.xls chung 1 folder): Wb A.xls có 1 sheet là sheet data dùng để chứa dữ liệu, wb B.xls là wb rỗng, trong đó có sheet1.

Xin hỏi là dùng ADO từ WB A.xls để copy toàn bộ dữ liệu của sheet data sang WB B.xls với sheet chứa dữ liệu là data
 

File đính kèm

Lần chỉnh sửa cuối:
Em chưa biết về ADO, có lẻ người biết thì không tham gia, người mới biết thì ít, người chưa biết thì nhiều. Vạn sự khởi đầu, vui lòng anh cho kết quả để người chưa biết bắt đầu học tập. Xin anh viết code kèm lời chú thích để dể hiểu hơn
Cảm ơn Anh.
P/s: Anh có thể đổi tiêu đề thành "Bài tập ADO" chẳng hạn được không?
 
Mình cũng vọc phá ADO vài lần. Loay hoay học được chút ít nhưng không ứng dụng thường rồi lại quên mất tiêu. Thế là nản lòng bỏ qua luôn. VBA đơn giản hơn là nếu quên cú pháp thì còn record macro để xem lại, còn ADO thì chẳng biết dựa vào chỗ nào hết.
 
Em chưa biết về ADO, có lẻ người biết thì không tham gia, người mới biết thì ít, người chưa biết thì nhiều. Vạn sự khởi đầu, vui lòng anh cho kết quả để người chưa biết bắt đầu học tập. Xin anh viết code kèm lời chú thích để dể hiểu hơn
Cảm ơn Anh.
P/s: Anh có thể đổi tiêu đề thành "Bài tập ADO" chẳng hạn được không?

Thật ra bài tập này tương tự như bài ở link http://www.giaiphapexcel.com/forum/...xcel-sang-file-Excel-khác&p=461164#post461164
Vậy anh làm thử nhé.
 
Thật ra bài tập này tương tự như bài ở link http://www.giaiphapexcel.com/forum/...xcel-sang-file-Excel-khác&p=461164#post461164
Vậy anh làm thử nhé.
Em thấy giống hoàn toàn, chỉ thay tên đổi họ mà vẫn không được
[GPECODE=vb]Sub CopyDL()
Dim cnn As Object, lsSQL As String, 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.FullName & _
";Extended Properties=""Excel 8.0;HDR=No;"";"
.Open
End With
lsSQL = "INSERT INTO [Data$] IN '" & ThisWorkbook.Path & _
"\B.xls ' 'Excel 8.0;' SELECT f1,f2,f3,f4 FROM [Data$A1:D15]"
lrs.Open lsSQL, cnn, 3, 1
Set lrs = Nothing
cnn.Close: Set cnn = Nothing
End Sub


[/GPECODE]

LoiADO.JPG

Báo lỗi dòng thứ 12. Em biết chưa hiểu hết cấu trúc lệnh thôi
Cụ thể:
1. Với câu lệnh trên là chèn dòng, vậy copy sang là lệnh nào
2. Khi dán A1:Ạ1 sheet "Data" vào File B.xls ở vị trí nào?
Anh gợi ý tiếp em với nhé
Cảm ơn Anh
--------
Xin lỗi sửa chưa hết ở dòng 11, nhưng sửa xong báo lỗi:

LoiADO1.JPG
 
Chỉnh sửa lần cuối bởi điều hành viên:
Em thấy giống hoàn toàn, chỉ thay tên đổi họ mà vẫn không được
[GPECODE=vb]Sub CopyDL()
Dim cnn As Object, lsSQL As String, 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.FullName & _
";Extended Properties=""Excel 8.0;HDR=No;"";"
.Open
End With
lsSQL = "INSERT INTO [Data$] IN '" & ThisWorkbook.Path & _
"\B.xls ' 'Excel 8.0;' SELECT f1,f2,f3,f4 FROM [Data$A1:D15]"
lrs.Open lsSQL, cnn, 3, 1
Set lrs = Nothing
cnn.Close: Set cnn = Nothing
End Sub


[/GPECODE]

View attachment 94291

Báo lỗi dòng thứ 12. Em biết chưa hiểu hết cấu trúc lệnh thôi
Cụ thể:
1. Với câu lệnh trên là chèn dòng, vậy copy sang là lệnh nào
2. Khi dán A1:Ạ1 sheet "Data" vào File B.xls ở vị trí nào?
Anh gợi ý tiếp em với nhé
Cảm ơn Anh
--------
Xin lỗi sửa chưa hết ở dòng 11, nhưng sửa xong báo lỗi:

View attachment 94296

Anh lưu ý là wb B.xls là wb rỗng, trong đó có sheet1. Code trên là chèn thêm dòng, và file B không có sheet data, anh cho chèn thêm dòng vào sheet data nó báo lỗi là đúng rồi. Bài tập là copy sheet thành sheet data, cách anh làm là chèn thêm dòng, thôi thì là làm chèn thêm dòng trước rồi copy thành sheet data. Anh thử sửa lại như sau:

  1. Đổi sheet Data thành Sheet1
  2. Vào file B.xls gõ vào tiêu đề cột của A1 là F1, B1 là F2, C1 là F3, D1 là F4 vì ở code trên anh chọn HDR=No và câu lệnh truy vấn đến tên cột để chèn phải có tên tương ứng với nhau.
Anh thử nhé
 
Anh lưu ý là wb B.xls là wb rỗng, trong đó có sheet1. Code trên là chèn thêm dòng, và file B không có sheet data, anh cho chèn thêm dòng vào sheet data nó báo lỗi là đúng rồi. Bài tập là copy sheet thành sheet data, cách anh làm là chèn thêm dòng, thôi thì là làm chèn thêm dòng trước rồi copy thành sheet data. Anh thử sửa lại như sau:

  1. Đổi sheet Data thành Sheet1
  2. Vào file B.xls gõ vào tiêu đề cột của A1 là F1, B1 là F2, C1 là F3, D1 là F4 vì ở code trên anh chọn HDR=No và câu lệnh truy vấn đến tên cột để chèn phải có tên tương ứng với nhau.
Anh thử nhé
- Trường hợp chèn dòng vậy nhưng kết quả không giống như file A.xls
Anh xem giúp em còn sai gì em với nhé
- Trường hợp copy sheet code như thế nào Anh?
Em cảm ơn.
 

File đính kèm

- Chèn thêm dữ liệu: Anh thử so sánh code sau với code của anh nhé

[GPECODE=sql]Sub CopyDL()
Dim cnn As Object, lsSQL As String, 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.FullName & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "INSERT INTO [Sheet1$] IN '" & ThisWorkbook.Path & _
"\B.xls ' 'Excel 8.0;' SELECT Stt, TEN, SOLUONG, GHICHU FROM [Data$]"
lrs.Open lsSQL, cnn, 3, 1
Set lrs = Nothing
cnn.Close: Set cnn = Nothing
End Sub

[/GPECODE]

- Code copy sang sheet data, chỉ chạy code được 1 lần.

[GPECODE=sql]Sub CopyDATA()
On Error GoTo Handle
Dim cnn As Object, lsSQL As String, 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.FullName & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "SELECT Stt, TEN, SOLUONG, GHICHU INTO [Excel 8.0;Database=" & ThisWorkbook.Path & _
"\B.xls].[DATA] FROM [Data$]"
lrs.Open lsSQL, cnn, 3, 1
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing
Exit Sub
Handle:
MsgBox Err.Description
Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub


[/GPECODE]
 
- Chèn thêm dữ liệu: Anh thử so sánh code sau với code của anh nhé

[GPECODE=sql]Sub CopyDL()
Dim cnn As Object, lsSQL As String, 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.FullName & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "INSERT INTO [Sheet1$] IN '" & ThisWorkbook.Path & _
"\B.xls ' 'Excel 8.0;' SELECT Stt, TEN, SOLUONG, GHICHU FROM [Data$]"
lrs.Open lsSQL, cnn, 3, 1
Set lrs = Nothing
cnn.Close: Set cnn = Nothing
End Sub

[/GPECODE]

- Code copy sang sheet data, chỉ chạy code được 1 lần.

[GPECODE=sql]Sub CopyDATA()
On Error GoTo Handle
Dim cnn As Object, lsSQL As String, 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.FullName & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "SELECT Stt, TEN, SOLUONG, GHICHU INTO [Excel 8.0;Database=" & ThisWorkbook.Path & _
"\B.xls].[DATA] FROM [Data$]"
lrs.Open lsSQL, cnn, 3, 1
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing
Exit Sub
Handle:
MsgBox Err.Description
Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub
[/GPECODE]
Cảm ơn Anh rất nhiều, em đã hiểu được cơ bản 2 nội dung trên
Anh cho em hỏi thêm: Câu lệnh
[GPECODE=vb]lrs.Open lsSQL, cnn, 3, 1[/GPECODE]
Nếu sửa thành [GPECODE=vb]lrs.Open lsSQL, cnn[/GPECODE]
Kết quả vẫn chạy. Vậy 2 thông số đó là gì vậy?
 
Cảm ơn Anh rất nhiều, em đã hiểu được cơ bản 2 nội dung trên
Anh cho em hỏi thêm: Câu lệnh
[GPECODE=vb]lrs.Open lsSQL, cnn, 3, 1[/GPECODE]
Nếu sửa thành [GPECODE=vb]lrs.Open lsSQL, cnn[/GPECODE]
Kết quả vẫn chạy. Vậy 2 thông số đó là gì vậy?

Nếu có thời gian anh vào trang sau: http://www.giaiphapexcel.com/forum/showthread.php?65492-Kết-nối-Thao-tác-giữa-Excel-và-Access
Hoặc tìm ebook của anh Duyệt về ngâm cứu nhé.
 
Mình cũng Loay hoay học được chút ít nhưng không ứng dụng thường rồi lại quên mất tiêu. Thế là nản bỏ qua luôn. VBA đơn giản hơn là nếu quên cú pháp thì còn record macro để xem lại, còn ADO thì chẳng biết dựa vào chỗ nào hết.

Các câu lệnh này sẽ na ná trong MS Access (ngăn query hay sao í)
 
Các câu lệnh này sẽ na ná trong MS Access (ngăn query hay sao í)

Chính xác là như thế, nếu chưa quen với những câu lệnh truy vấn thì ta chuyển vào access rồi vào query test thử, nếu kết quả ok thì copy kết quả của câu lệnh truy vấn ở access query đó vào excel là được. Nó rất đơn giản.
 
Nếu có thời gian anh vào trang sau: http://www.giaiphapexcel.com/forum/showthread.php?65492-Kết-nối-Thao-tác-giữa-Excel-và-Access
Hoặc tìm ebook của anh Duyệt về ngâm cứu nhé.
Có nghiên cứu nhưng cũng khó hiểu thật (Anh thông cảm kiến thức em có hạn)
có lẽ một số bài tập mới làm cho em dễ hiểu hơn. Anh giúp em nhé
Trường hợp bài tập ở bài 1 của Anh nhưng làm ngược lại là từ file B.xls lấy dự liệu ở file A.xls thì làm sao em loay hoay mãi không được, xin được giúp đỡ
Em cảm ơn.
 
Có nghiên cứu nhưng cũng khó hiểu thật (Anh thông cảm kiến thức em có hạn)
có lẽ một số bài tập mới làm cho em dễ hiểu hơn. Anh giúp em nhé
Trường hợp bài tập ở bài 1 của Anh nhưng làm ngược lại là từ file B.xls lấy dự liệu ở file A.xls thì làm sao em loay hoay mãi không được, xin được giúp đỡ
Em cảm ơn.

Mở file B, anh chép đoạn code sau vào và sau đó chạy code nhé:

[GPECODE=sql]Sub LayDL_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 & "\A.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
'lay het du lieu co trong sheet Data o file A.xls
lsSQL = "SELECT * " & _
"FROM [Data$] "
lrs.Open lsSQL, cnn, 3, 1
With Sheet1
.[A2:D1000].ClearContents
.[A2].CopyFromRecordset lrs
End With
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub[/GPECODE]
 
Mở file B, anh chép đoạn code sau vào và sau đó chạy code nhé:

[GPECODE=sql]Sub LayDL_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 & "\A.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
'lay het du lieu co trong sheet Data o file A.xls
lsSQL = "SELECT * " & _
"FROM [Data$] "
lrs.Open lsSQL, cnn, 3, 1
With Sheet1
.[A2:D1000].ClearContents
.[A2].CopyFromRecordset lrs
End With
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub[/GPECODE]
Trường hợp em không muốn copy vào bảng tính trực tiếp và chuyển vùng dữ liệu ở file A.xls vào 1 mãng Arr() sau đó mới truyền dữ liệu mãng đó xuống bảng tính thì code thay đổi thế nào hở Anh?
 
Trường hợp em không muốn copy vào bảng tính trực tiếp và chuyển vùng dữ liệu ở file A.xls vào 1 mãng Arr() sau đó mới truyền dữ liệu mãng đó xuống bảng tính thì code thay đổi thế nào hở Anh?

viehoai thử dùng cái này xem:

[GPECODE=vb]
Sub LayDL_ADO()
Dim lsSQL As String, cnn As Object, lrs As Object

Dim Arr As Variant

Set cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")

With cnn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.Path & "\A.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With

lsSQL = "SELECT * FROM [Data$] "
lrs.Open lsSQL, cnn, 3, 1

Arr = lrs.GetRows

lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing
End Sub
[/GPECODE]

LƯU Ý: Mảng Arr này là một mảng "ngược" nhé! muốn đổi lại mảng 2 chiều thì phải dùng vòng lặp thôi.

----------------------------------------------------------

Phần thêm: Chuyển mảng từ mảng "ngược"

[GPECODE=vb]

Sub LayDL_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 & "\A.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With

lsSQL = "SELECT * FROM [Data$] "
lrs.Open lsSQL, cnn, 3, 1

Dim Arr As Variant, ExcelArr As Variant, i As Long, _
c As Long, h As Long, r As Long, v As Long

Arr = lrs.GetRows

v = UBound(Arr, 1) + 1
h = UBound(Arr, 2) + 1

ReDim ExcelArr(1 To h, 1 To v): r = 0
For i = 1 To h
r = r + 1
For c = 1 To v
ExcelArr(r, c) = Arr(c - 1, i - 1)
Next
Next

Sheet2.Range("A1").Resize(h, v).Value = ExcelArr

lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing
End Sub
[/GPECODE]
 
Lần chỉnh sửa cuối:
Làm hẳn 1 hàm chuyển đổi luôn

Mã:
Function TransArr(sArr As Variant) As Variant
    Dim cllX As Long, cllY As Long, tmpX As Long, tmpY As Long, tmpArr As Variant
    tmpX = UBound(sArr, 2):    tmpY = UBound(sArr, 1)
    ReDim tmpArr(tmpX, tmpY)
    For cllX = 0 To tmpX
        For cllY = 0 To tmpY
            tmpArr(cllX, cllY) = sArr(cllY, cllX)
        Next cllY
    Next cllX
    TransArr = tmpArr

End Function

Chạy thử code sau:

[GPECODE=sql]Sub LayDL_ADO()
Dim lsSQL As String, cnn As Object, lrs As Object, rstArr As Variant, lFields As Long, lRecrds As Long
Set cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
With cnn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.Path & "\A.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "SELECT * " & _
"FROM [Data$] "
lrs.Open lsSQL, cnn, 3, 1
lFields = lrs.Fields.Count
With Sheet1
.[A2:D1000].ClearContents
rstArr = lrs.GetRows
lRecrds = UBound(rstArr, 2) + 1
.Range("A2").Resize(lRecrds, lFields).Value = TransArr(rstArr)
End With
Erase rstArr
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub

[/GPECODE]
 
Em làm thử một hàm nhưng xuất dữ liệu không đủ ở file A.xls
Nhờ các anh chị xem giúp
[GPECODE=vb]Function GetData(FileFullName, ShName As String)Dim lsSQL As String, Cnn As Object, lrs As Object, rstArr As Variant
Set Cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
With Cnn
If Val(Application.Version) < 12 Then
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FileFullName & ";Extended Properties=""Excel 8.0;HDR=Yes"";"
Else
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & FileFullName & ";Extended Properties=""Excel 12.0;HDR=Yes"";"
End If
.Open
End With
lsSQL = "SELECT * " & "FROM [" & ShName & "$] "
lrs.Open lsSQL, Cnn, 3, 1
rstArr = lrs.GetRows
GetData = TransArr(rstArr)
End Function[/GPECODE]
[GPECODE=vb]Sub Test()
Dim Arr()
Arr = GetData(ThisWorkbook.Path & "\A.xls", "Data")
Range("A2").Resize(UBound(Arr), UBound(Arr, 2)).Value = Arr
End Sub
[/GPECODE]
[GPECODE=vb]Function TransArr(sArr As Variant) As Variant Dim cllX As Long, cllY As Long, tmpX As Long, tmpY As Long, tmpArr As Variant
tmpX = UBound(sArr, 2): tmpY = UBound(sArr, 1)
ReDim tmpArr(tmpX, tmpY)
For cllX = 0 To tmpX
For cllY = 0 To tmpY
tmpArr(cllX, cllY) = sArr(cllY, cllX)
Next cllY
Next cllX
TransArr = tmpArr
End Function[/GPECODE]
Xin cảm ơn các anh chị
 
Anh thử chỉnh lại như sau:

[GPECODE=vb]Sub Test()
Dim Arr()
Arr = GetData(ThisWorkbook.Path & "\A.xls", "Data")
Range("A2").Resize(UBound(Arr) + 1, UBound(Arr, 2) + 1).Value = Arr
End Sub

[/GPECODE]
 
Anh thử chỉnh lại như sau:

[GPECODE=vb]Sub Test()
Dim Arr()
Arr = GetData(ThisWorkbook.Path & "\A.xls", "Data")
Range("A2").Resize(UBound(Arr) + 1, UBound(Arr, 2) + 1).Value = Arr
End Sub

[/GPECODE]
Ah.. Cảm ơn Anh. Đọc không kỹ hàm TransArr()
Anh cho em hỏi vì sao khi em set cnn có HDR=Yes nhưng khi xuất dữ liệu không có tiêu đề vậy Anh?
 
Ah.. Cảm ơn Anh. Đọc không kỹ hàm TransArr()
Anh cho em hỏi vì sao khi em set cnn có HDR=Yes nhưng khi xuất dữ liệu không có tiêu đề vậy Anh?

Hihi, câu hỏi khá thú vị.
Muốn lấy tiêu đề cột ta phải thêm code lấy, còn HDR=Yes có nghĩa là khi ta truy vấn đến csdl thì phải "kiu" tên cột rõ ràng. Còn ngược lại thì phải "kiu" nó = F1, F2... Fn theo số cột tương ứng.
Anh tham khảo từ bài 105 trở đi http://www.giaiphapexcel.com/forum/...vấn-CSDL-từ-file-Excel-đến-file-Access/page11
 
Hihi, câu hỏi khá thú vị.
Muốn lấy tiêu đề cột ta phải thêm code lấy, còn HDR=Yes có nghĩa là khi ta truy vấn đến csdl thì phải "kiu" tên cột rõ ràng. Còn ngược lại thì phải "kiu" nó = F1, F2... Fn theo số cột tương ứng.
Anh tham khảo từ bài 105 trở đi http://www.giaiphapexcel.com/forum/...vấn-CSDL-từ-file-Excel-đến-file-Access/page11
1. Anh cho em hỏi thêm: Hinh file dữ liệu có định dạng thì nó báo lỗi
LoiADO3.JPG
Tại dòng .Open
Em thử copy dữ liệu sang 1 file khác dán Value thì được. Vậy trường hợp này giải quyết như thế nào Anh?
2. Khi dữ liệu lên 53.200 dòng thì thấy hợi chậm. Có cách nào cải thiện tốc độ hơn không Anh?
Cảm ơn Anh rất nhiều
 
Lần chỉnh sửa cuối:
Anh cho em hỏi thêm: Hinh file dữ liệu có định dạng thì nó báo lỗi
View attachment 94649
Tại dòng .Open
Em thử copy dữ liệu sang 1 file khác dán Value thì được. Vậy trường hợp này giải quyết như thế nào Anh?
Cảm ơn Anh rất nhiều

Hỏng lẻ code thiếu IMEX=1. Anh có thể đưa ví dụ để em test thử được không?
 
Do cái tiêu đề tiếng việt của anh mà ra, anh chỉnh lại tiêu đề TV có dấu sang không dấu rồi test lại xem sao nhé.
Vẫn không được Anh à. Nhưng nếu thế thì ở bài 23 em copy nguyên sheet (tức bao gồm tiêu đề Tiếng Việt) nhưng nó vẫn được
 
Vẫn không được Anh à. Nhưng nếu thế thì ở bài 23 em copy nguyên sheet (tức bao gồm tiêu đề Tiếng Việt) nhưng nó vẫn được
Vậy anh test thử cái này:

[GPECODE=sql]Function GetData(FileFullName, ShName As String)
Dim lsSQL As String, Cnn As Object, lrs As Object, rstArr As Variant
Set Cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
With Cnn
If Val(Application.Version) < 12 Then
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FileFullName & ";Extended Properties=""Excel 8.0;HDR=No;IMEX=1"";"
Else
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & FileFullName & ";Extended Properties=""Excel 12.0;HDR=No;IMEX=1"";"
End If
.Open
End With
lsSQL = "SELECT * " & "FROM [" & ShName & "$A2:E53281] "
lrs.Open lsSQL, Cnn, 3, 1
rstArr = lrs.GetRows
GetData = TransArr(rstArr)
End Function

[/GPECODE]
 
Có điều là anh mở file Database1 lên rồi qua file B chạy code trong khi file csdl vẫn mở thì bình thường.

Không biết nó như thế nào nữa, để em test lại.
Hey ah.. đúng thật như vậy. Nếu mở file Database1 lên thì code chạy bình thường. Không biết sao nữa?
 
Có điều là anh mở file Database1 lên rồi qua file B chạy code trong khi file csdl vẫn mở thì bình thường.

Không biết nó như thế nào nữa, để em test lại.
Anh chú cho em vì sao cnn.Open không được? Khi ta mở file Database1 lên rồi có nghĩa là đã bỏ qua được lệnh này nên code chạy???

Em thử là như sau:
1. Tạo file Excel mới đặt tên DataBase2
2. Copy DL các sheet File DataBase1 sang DataBase2 và đổi tên sheet giống DataBase1
Chạy thử code ngon lành. Vậy chăng lỗi ấy từ File chứ không phải dữ liệu trong file???
 
Chỉnh sửa lần cuối bởi điều hành viên:
Em có mở rộng thêm nguồn dữ liệu ở hàm GetData()
Nhờ anh giúp tiếp nội dung sau
1. Vì sao dữ liệu xuất ra (cột D) là text mà đúng ra là Number
2. Bổ sung code để lấy dữ liệu cột 4 bă đầu bằng N chẳng hạn ("N*")
(Có đọc các link bằng câu lệnh WHERE nhưng làm chưa được)
Sửa câu lệnh sau như thế nào
[GPECODE=vb] lsSQL = "SELECT f1, f2, f3, f4, f5 " & "FROM [" & ShName & "$" & sRng & "]" & _
"WHERE f5 = N*"


[/GPECODE]
Cảm ơn Anh
 

File đính kèm

Lần chỉnh sửa cuối:
Em có mở rộng thêm nguồn dữ liệu ở hàm GetData()
Nhờ anh giúp tiếp nội dung sau
1. Vì sao dữ liệu xuất ra (cột D) là text mà đúng ra là Number
2. Bổ sung code để lấy dữ liệu cột 4 bă đầu bằng N chẳng hạn ("N*")
(Có đọc các link bằng câu lệnh WHERE nhưng làm chưa được)
Sửa câu lệnh sau như thế nào
[GPECODE=vb] lsSQL = "SELECT f1, f2, f3, f4, f5 " & "FROM [" & ShName & "$" & sRng & "]" & _
"WHERE f5 = N*"


[/GPECODE]
Cảm ơn Anh

1./ Chừa dòng tiêu đề ra, vì anh lấy cả dòng tiêu đề nên nó hiểu là text
2./ Dữ liệu của anh rất khó xử, vì có dòng dữ liệu xen kẻ nên không thể lọc theo ý muốn. Nếu lọc N thì nó chỉ lấy dòng có giá trị, còn những dòng trống nó bỏ đi thì kết quả không như mong đợi.
 
1./ Chừa dòng tiêu đề ra, vì anh lấy cả dòng tiêu đề nên nó hiểu là text
2./ Dữ liệu của anh rất khó xử, vì có dòng dữ liệu xen kẻ nên không thể lọc theo ý muốn. Nếu lọc N thì nó chỉ lấy dòng có giá trị, còn những dòng trống nó bỏ đi thì kết quả không như mong đợi.
Nhưng sao em sửa hàm lại như ban đầu thế này nó vẫn cho kết quả là Text?
[GPECODE=vb]Function GetData(FileFullName, ShName As String, Optional ByVal sRng As String = "")
Dim lsSQL As String, Cnn As Object, lrs As Object, rstArr As Variant
Set Cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
With Cnn
If Val(Application.Version) < 12 Then
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FileFullName & ";Extended Properties=""Excel 8.0;HDR=No;IMEX=1"";"
Else
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & FileFullName & ";Extended Properties=""Excel 12.0;HDR=No;IMEX=1"";"
End If
.Open
End With
lsSQL = "SELECT * " & "FROM [" & ShName & "$" & sRng & "] "
lrs.Open lsSQL, Cnn, 3, 1
rstArr = lrs.GetRows
GetData = TransArr(rstArr)
End Function[/GPECODE]
 
Anh thử như sau:

[GPECODE=sql]Function GetData(FileFullName, ShName As String, Optional ByVal sRng As String = "")
Dim lsSQL As String, Cnn As Object, lrs As Object, rstArr As Variant
Set Cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
With Cnn
If Val(Application.Version) < 12 Then
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FileFullName & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
Else
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & FileFullName & ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"
End If
.Open
End With
lsSQL = "SELECT * " & "FROM [" & ShName & "$" & sRng & "] where [mvt] like 'N%' or [mvt] is null"
lrs.Open lsSQL, Cnn, 3, 1
rstArr = lrs.GetRows
GetData = TransArr(rstArr)
End Function

[/GPECODE]

Dĩ nhiên là kết quả như em nói như trên
 
Cảm ơn Anh rất nhiều. Hóa ra là HDR=Yes
Em không biết về access, nếu dữ liệu đưa vào eccess liệu tốt độ cải thiện hơn không Anh?

Nếu trong bảng này đưa vào access dĩ nhiên là ngon, dữ liệu anh nhiều quá, mà excel 2003 chứa chỉ có 65536 dòng, trong khi đó dữ liệu của anh hơn 50 ngàn dòng.
 
Nếu trong bảng này đưa vào access dĩ nhiên là ngon, dữ liệu anh nhiều quá, mà excel 2003 chứa chỉ có 65536 dòng, trong khi đó dữ liệu của anh hơn 50 ngàn dòng.
Anh đưa vào access thử 1 file giúp em. Access có bao nhiêu dòng vậy Anh?
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 = ???
Cảm ơn Anh nhiều
 
Lần chỉnh sửa cuối:
Anh đưa vào access thử 1 file giúp em. Access có bao nhiêu dòng vậy Anh?
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 = ???
Cảm ơn Anh nhiều
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."
 
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

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

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?
 
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?
Em biết vậy, nhưng hỏi để biết các trường hợp xảy ra vì đang học mà anh
Anh cho biết thêm các cấu trúc tương tự như SELECT, hoặc ra bài tập đơn giản tiếp theo nhé
Cảm ơn Anh.
 
Em biết vậy, nhưng hỏi để biết các trường hợp xảy ra vì đang học mà anh
Anh cho biết thêm các cấu trúc tương tự như SELECT, hoặc ra bài tập đơn giản tiếp theo nhé
Cảm ơn Anh.
Select còn nhiều trường hợp, ta đi từ từ nhé.
Dùng câu lệnh select kết hợp với điều kiện lọc là Where
[GPECODE=sql]Select TenCot
From TenBang
Where TenCot TenDkLoc GiaTriDKLoc[/GPECODE]

Vui lòng xem thêm http://www.giaiphapexcel.com/forum/...ile-Excel-đến-file-Access&p=427955#post427955

Bài Tập 2: =>Ở file B.xls ta kết nối và lấy dữ liệu từ sheet Data của file A.xls với điều kiện là thứ tự cột (GhiChu>TEN>STT>SoLuong) + lọc cột GhiChu là những dòng có 'x'. Xin xem kết quả ở hình bên dưới.

32.jpg

paperclip.png
Tập tin đính kèm
 
Select còn nhiều trường hợp, ta đi từ từ nhé.
Dùng câu lệnh select kết hợp với điều kiện lọc là Where
[GPECODE=sql]Select TenCot
From TenBang
Where TenCot TenDkLoc GiaTriDKLoc[/GPECODE]

Vui lòng xem thêm http://www.giaiphapexcel.com/forum/...ile-Excel-đến-file-Access&p=427955#post427955

Bài Tập 2: =>Ở file B.xls ta kết nối và lấy dữ liệu từ sheet Data của file A.xls với điều kiện là thứ tự cột (GhiChu>TEN>STT>SoLuong) + lọc cột GhiChu là những dòng có 'x'. Xin xem kết quả ở hình bên dưới.

View attachment 95057

paperclip.png
Tập tin đính kèm
Ha, ha tư duy theo thứ tự đề ra được ngay liền à
[GPECODE=vb]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 & "\A.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "SELECT GhiChu, TEN, STT, SoLuong FROM [Data$] " & _
"WHERE GhiChu = 'x'"
lrs.Open lsSQL, cnn, 3, 1
Range("A2").CopyFromRecordset lrs
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub
[/GPECODE]
Kể cả 2 điều kiện lọc em cũng đã "Vọc" thử bằng cách thay lsSQL như sau
[GPECODE=vb] lsSQL = "SELECT GhiChu, TEN, STT, SoLuong FROM [Data$] " & _
"WHERE SoLuong >5 AND GhiChu ='x'"


[/GPECODE]
 
Lần chỉnh sửa cuối:
Ha, ha tư duy theo thứ tự đề ra được ngay liền à
[GPECODE=vb]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 & "\A.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "SELECT GhiChu, TEN, STT, SoLuong FROM [Data$] " & _
"WHERE GhiChu = 'x'"
lrs.Open lsSQL, cnn, 3, 1
Range("A2").CopyFromRecordset lrs
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub
[/GPECODE]
Kể cả 2 điều kiện lọc em cũng đã "Vọc" thử bằng cách thay lsSQL như sau
[GPECODE=vb] lsSQL = "SELECT GhiChu, TEN, STT, SoLuong FROM [Data$] " & _
"WHERE SoLuong >5 AND GhiChu ='x'"


[/GPECODE]
Anh trả lời rất nhanh, nhìn code thấy đúng yêu cầu. Nhưng anh nên xóa dữ liệu sheet đích trước khi ghi kết quả nhé.
Bổ sung bài tập 2: Lấy dòng tiêu đề cột ghi vào sheet kết quả = ado
 
Anh trả lời rất nhanh, nhìn code thấy đúng yêu cầu. Nhưng anh nên xóa dữ liệu sheet đích trước khi ghi kết quả nhé.
Bổ sung bài tập 2: Lấy dòng tiêu đề cột ghi vào sheet kết quả = ado
Em đang suy nghĩ điều này thì Anh đã ra đề
Em làm như sau nhưng không biết sao tiêu đề 2 cột cuối không xuất dữ liệu Anh giải thích thêm giúp em nhé
[GPECODE=vb]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 & "\A.xls" & _
";Extended Properties=""Excel 8.0;HDR=No;"";"
.Open
End With
lsSQL = "SELECT f4, f2, f1, f3 FROM [Data$] " & _
"WHERE f4= 'GhiChu' OR f4 ='x'"


lrs.Open lsSQL, cnn, 3, 1
[a:d].Clear
Range("A1").CopyFromRecordset lrs
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub


[/GPECODE]
 
Em đang suy nghĩ điều này thì Anh đã ra đề
Em làm như sau nhưng không biết sao tiêu đề 2 cột cuối không xuất dữ liệu Anh giải thích thêm giúp em nhé
[GPECODE=vb]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 & "\A.xls" & _
";Extended Properties=""Excel 8.0;HDR=No;"";"
.Open
End With
lsSQL = "SELECT f4, f2, f1, f3 FROM [Data$] " & _
"WHERE f4= 'GhiChu' OR f4 ='x'"


lrs.Open lsSQL, cnn, 3, 1
[a:d].Clear
Range("A1").CopyFromRecordset lrs
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing

End Sub


[/GPECODE]

Không phải thế anh à, phải chọn HDR = Yes, trong code anh phải dùng 1 vòng lặp duyệt qua các tiêu đề cột, sau đó gán cái tiêu đề cột đó xuống sheet.
 
Không phải thế anh à, phải chọn HDR = Yes, trong code anh phải dùng 1 vòng lặp duyệt qua các tiêu đề cột, sau đó gán cái tiêu đề cột đó xuống sheet.
Vậy như thế này thì không còn sai nữa nhỉ
[GPECODE=vb]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 & "\A.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "SELECT GhiChu, TEN, STT, SoLuong FROM [Data$] " & _
"WHERE GhiChu= 'x'"
lrs.Open lsSQL, cnn, 3, 1
[a:d].Clear
For i = 1 To lrs.fields.Count
Cells(1, i).Value = lrs.fields(i - 1).Name
Next
Range("A2").CopyFromRecordset lrs
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing
End Sub


[/GPECODE]
 
[TIP]Bổ sung thêm bài tập 2[/TIP]

[GPECODE=sql]Select TenCot
From TenBang
Where DKLoc
Order By TenCotCanSapXep KieuSapXep[/GPECODE]
Cũng tương tự như trên ta lọc lấy ra những dòng với cột GhiChu không có đáng 'x', sắp xếp dữ liệu cột SoLuong theo thứ tự giảm dần.

Lưu ý: Không hiển thị cột GhiChu vào bảng tính.
 
Lần chỉnh sửa cuối:
[TIP]Bổ sung thêm bài tập 2[/TIP]

[GPECODE=sql]Select TenCot
From TenBang
Where DKLoc
OrderBy TenCotCanSapXep KieuSapXep[/GPECODE]
Cũng tương tự như trên ta lọc lấy ra những dòng với cột GhiChu không có đáng 'x', sắp xếp dữ liệu cột SoLuong theo thứ tự giảm dần.

Lưu ý: Không hiển thị cột GhiChu vào bảng tính.
Cũng tương tự như trên ta lọc lấy ra những dòng với cột GhiChu không có đáng 'x' thôi (chưa nói đến sắp xếp) em thay câu lệnh
[GPECODE=vb] lsSQL = "SELECT GhiChu, TEN, STT, SoLuong FROM [Data$] " & _
"WHERE GhiChu= 'x'"[/GPECODE]
Bằng
[GPECODE=vb] lsSQL = "SELECT GhiChu, TEN, STT, SoLuong FROM [Data$] " & _

"WHERE GhiChu= ''"
[/GPECODE]
 
Cũng tương tự như trên ta lọc lấy ra những dòng với cột GhiChu không có đáng 'x' thôi (chưa nói đến sắp xếp) em thay câu lệnh
[GPECODE=vb] lsSQL = "SELECT GhiChu, TEN, STT, SoLuong FROM [Data$] " & _
"WHERE GhiChu= 'x'"[/GPECODE]
Bằng
[GPECODE=vb] lsSQL = "SELECT GhiChu, TEN, STT, SoLuong FROM [Data$] " & _

"WHERE GhiChu= ''"
[/GPECODE]

Chưa được đâu anh, anh thử lại nhé và anh xem:

Lưu ý Không hiển thị cột GhiChu vào bảng tính.
 
Chưa được đâu anh, anh thử lại nhé và anh xem:
Em loay hoay mãi với yêu cầu này "những dòng với cột GhiChu không có đáng 'x' " vẫn chưa được. Anh gợi ý cho em xem vì sao đùng "WHERE GhiChu = 'x'" hoặc"WHERE GhiChu <> ''" thì được
Còn "WHERE GhiChu = ''" thì lại không được nhỉ
 
Em loay hoay mãi với yêu cầu này "những dòng với cột GhiChu không có đáng 'x' " vẫn chưa được. Anh gợi ý cho em xem vì sao đùng "WHERE GhiChu = 'x'" hoặc"WHERE GhiChu <> ''" thì được
Còn "WHERE GhiChu = ''" thì lại không được nhỉ
Còn yêu cầu đề ra đại khái như thế này (tuy nhiên chưa được ý trên)
[GPECODE=vb] lsSQL = "SELECT TEN, STT, SoLuong FROM [Data$] " & _
"WHERE GhiChu = ''" & _
"ORDER BY SoLuong DESC"[/GPECODE]
 
Em loay hoay mãi với yêu cầu này "những dòng với cột GhiChu không có đáng 'x' " vẫn chưa được. Anh gợi ý cho em xem vì sao đùng "WHERE GhiChu = 'x'" hoặc"WHERE GhiChu <> ''" thì được
Còn "WHERE GhiChu = ''" thì lại không được nhỉ

Đơn giản nếu không cho hiển thị cột ghi chú vào bảng tính thì ở trên anh không select cột GhiChu. Còn where thì anh có thể cho vào điều kiện là :

Xin nói thêm:
  1. Is null là dòng dữ liệu bị trống.
  2. Is not null là dòng dữ liệu không trống.
Nó sẽ giúp ích rất nhiều cho anh sau này đó.
Anh thử nhé.
 
Đơn giản nếu không cho hiển thị cột ghi chú vào bảng tính thì ở trên anh không select cột GhiChu. Còn where thì anh có thể cho vào điều kiện là :


Xin nói thêm:
  1. Is null là dòng dữ liệu bị trống.
  2. Is not null là dòng dữ liệu không trống.
Nó sẽ giúp ích rất nhiều cho anh sau này đó.
Anh thử nhé.
Vậy là câu lệnh
[GPECODE=vb] lsSQL = "SELECT TEN, STT, SoLuong FROM [Data$] " & _
"WHERE GhiChu is Null " & _
"ORDER BY SoLuong DESC"
[/GPECODE]
Giải được bài tập của Anh rồi chứ gì
Em test thử với NullString mà không được không ngờ nó là Null
Cảm ơn Anh rất nhiều.
 
Vậy là câu lệnh
[GPECODE=vb] lsSQL = "SELECT TEN, STT, SoLuong FROM [Data$] " & _
"WHERE GhiChu is Null " & _
"ORDER BY SoLuong DESC"
[/GPECODE]
Giải được bài tập của Anh rồi chứ gì
Em test thử với NullString mà không được không ngờ nó là Null
Cảm ơn Anh rất nhiều.
Câu trả lời của anh hoàn toàn chính xác, anh rất có khiếu về ado lại chịu khó test và học. Sau 1 thời gian em sẽ học ado lại từ anh.
Hôm nay chỉ đến đây, ngày mai mình sẽ tiếp tục. Mong anh hưởng ứng.
 
[TIP]Bài tập 3: Gán tên cho cột[/TIP]
Gán tên cột của 1 bảng:

Cú pháp:
[GPECODE=sql]SELECT TenCotCuTrongCSDL AS GanThanhTenMoi
FROM TenBang[/GPECODE]

Với Ví dụ csdl ở trên làm sao khi ta gán xuống sheet lần lượt có tên như sau:

  • STT Thay = ID
  • TEN thay = Name
  • SoLuong thay = Q'Ty
  • GhiChu thay = Remarks
 
Lần chỉnh sửa cuối:
[TIP]Bài tập 3: Gán tên cho cột[/TIP]
Gán tên cột của 1 bảng:

Cú pháp:
[GPECODE=sql]SELECT TenCotCuTrongCSDL AS GanThanhTenMoi
FROM TenBang[/GPECODE]

Với Ví dụ csdl ở trên làm sao khi ta gán xuống sheet lần lượt có tên như sau:

  • STT Thay = ID
  • TEN thay = Name
  • SoLuong thay = Q'Ty
  • GhiChu thay = Remarks
Cũng phải thử đủ mội cách theo cấu trúc đã gợi ý
Và kết quả như thế này đúng không Anh?
[GPECODE=vb] lsSQL = "SELECT STT as [ID], TEN as [Name], SoLuong as [Q'ty], GhiChu as [Remarks] " & _
"FROM [Data$] "
[/GPECODE]
Thử gán
[GPECODE=vb]Arr = Array("ID", "Name", "Q'ty", "Remarks")[/GPECODE]
Rồi dùng:
[GPECODE=vb] lsSQL = "SELECT STT, TEN, SoLuong, GhiChu as Arr " & _
"FROM [Data$] "
[/GPECODE]
Nhưng không được. Có giải pháp giải quyết theo hướng này được không Anh?
 
Lần chỉnh sửa cuối:
Cũng phải thử đủ mội cách theo cấu trúc đã gợi ý
Và kết quả như thế này đúng không Anh?
[GPECODE=vb] lsSQL = "SELECT STT as [ID], TEN as [Name], SoLuong as [Q'ty], GhiChu as [Remarks] " & _
"FROM [Data$] "
[/GPECODE]
Thử gán
[GPECODE=vb]Arr = Array("ID", "Name", "Q'ty", "Remarks")[/GPECODE]
Rồi dùng:
[GPECODE=vb] lsSQL = "SELECT STT, TEN, SoLuong, GhiChu as Arr " & _
"FROM [Data$] "
[/GPECODE]
Nhưng không được. Có giải pháp giải quyết theo hướng này được không Anh?

Câu đầu tiên là ok rồi đó anh, còn gán vào Arr thì phải như sau:

[GPECODE=sql] arr = Array("ID", "Name", "Q'ty", "Remarks")
lsSQL = "SELECT STT as " & arr(0) & " , TEN as " & arr(1) & " , SoLuong as [" & arr(2) & "] , GhiChu as " & arr(3) & _
" FROM [Data$] "

[/GPECODE]
 
Câu đầu tiên là ok rồi đó anh, còn gán vào Arr thì phải như sau:

[GPECODE=sql] arr = Array("ID", "Name", "Q'ty", "Remarks")
lsSQL = "SELECT STT as " & arr(0) & " , TEN as " & arr(1) & " , SoLuong as [" & arr(2) & "] , GhiChu as " & arr(3) & _
" FROM [Data$] "

[/GPECODE]
Vậy thì có hơn gì cách trên đâu Anh?
 
[TIP]Bài Tập 4: Lấy dữ liệu duy nhất[/TIP]

Cú pháp:

[GPECODE=sql]SELECT DISTINCT TenCotCanLay
FROM TenBang[/GPECODE]

Với TenCotCanLay là tên các cột trong cơ sở dữ liệu mà ta muốn lấy dữ liệu.

[NOTE1]Với cơ sở dữ liệu như bên dưới anh, chị hãy:
  1. Lấy ra dữ liệu duy nhất các cột như sau: [TP],[MATERIAL NAME],[SPEC 2],[COLOR NAME],[UNIT], [ORIGIN],[SUPPLIER]
  2. Sắp xếp lại các cột trên theo thứ tự tăng dần.
[/NOTE1]
 

File đính kèm

[TIP]Bài Tập 4: Lấy dữ liệu duy nhất[/TIP]

Cú pháp:

[GPECODE=sql]SELECT DISTINCT TenCotCanLay
FROM TenBang[/GPECODE]

Với TenCotCanLay là tên các cột trong cơ sở dữ liệu mà ta muốn lấy dữ liệu.

[NOTE1]Với cơ sở dữ liệu như bên dưới anh, chị hãy:
  1. Lấy ra dữ liệu duy nhất các cột như sau: [TP],[MATERIAL NAME],[SPEC 2],[COLOR NAME],[UNIT], [ORIGIN],[SUPPLIER]
  2. Sắp xếp lại các cột trên theo thứ tự tăng dần.
[/NOTE1]
Cho em hỏi thêm:
1. Lấy duy nhất 1 cột nào đó, sao lại lấy duy nhất các cột?
2. Sắp xếp theo thứ tự tăng dần 1 cột hay nhiều cột, nếu nhiều cột phải có thứ tự ưu tiên
Trông có hơi khó nha
 
Cho em hỏi thêm:
1. Lấy duy nhất 1 cột nào đó, sao lại lấy duy nhất các cột?
2. Sắp xếp theo thứ tự tăng dần 1 cột hay nhiều cột, nếu nhiều cột phải có thứ tự ưu tiên
Trông có hơi khó nha

1. Lấy duy nhất dòng của các cột có tên như trên.
2. Sắp xếp tất cả các cột theo thứ tự như trên hoặc theo thứ tự như sau:
[TP],[ORIGIN],[SUPPLIER],[MATERIAL NAME],[SPEC 2],[COLOR NAME],[UNIT]
 
1. Lấy duy nhất dòng của các cột có tên như trên.
2. Sắp xếp tất cả các cột theo thứ tự như trên hoặc theo thứ tự như sau:
[TP],[ORIGIN],[SUPPLIER],[MATERIAL NAME],[SPEC 2],[COLOR NAME],[UNIT]
Anh kiểm tra xem đáp có đúng ý Anh không nhé
[GPECODE=vb]Sub Trich_ADO_Unique()
Dim lsSQL As String, cnn As Object, lrs As Object
Set cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
Dim Arr()
With cnn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.Path & "\Database.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "SELECT DISTINCT [TP], [MATERIAL NAME], [SPEC 2], [COLOR NAME], [UNIT], [ORIGIN], [SUPPLIER] " & _
"FROM [tblData$] " & _
"ORDER BY [TP],[ORIGIN],[SUPPLIER],[MATERIAL NAME],[SPEC 2],[COLOR NAME],[UNIT]"
lrs.Open lsSQL, cnn, 3, 1
[a:g].Clear


For i = 1 To lrs.fields.Count
Cells(1, i).Value = lrs.fields(i - 1).Name
Next
Range("A2").CopyFromRecordset lrs
lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing
End Sub[/GPECODE]
Trong có vẽ học kiểu này rất nhanh nhỉ. Cảm ơn Anh rất nhiều
 
Anh đã trả lời đúng chính xác theo yêu cầu.
Xin hỏi thêm là:
[NOTE1]Anh, chị hãy mở file Batabase lên rồi gõ cell nào đó tùy ý vào cột có dạng số là giá trị text nào đó, lưu lại:
  1. Hãy dùng câu lệnh select bình thường để chọn tất cả các cột có trong csdl, cho biết kết quả những cell có dạng text đó có xuất hiện hay không?
  2. Nếu không thì tại sao và cho biết cách khắc phục.
[/NOTE1]
 
Anh đã trả lời đúng chính xác theo yêu cầu.
Xin hỏi thêm là:
[NOTE1]Anh, chị hãy mở file Batabase lên rồi gõ cell nào đó tùy ý vào cột có dạng số là giá trị text nào đó, lưu lại:
  1. Hãy dùng câu lệnh select bình thường để chọn tất cả các cột có trong csdl, cho biết kết quả những cell có dạng text đó có xuất hiện hay không?
  2. Nếu không thì tại sao và cho biết cách khắc phục.
[/NOTE1]
1. Dữ liệu không xuất hiện
2. Để khắc phục sử dụng thêm: IMEX=1 cuối câu lệnh cnn.ConnectionString
 
1. Dữ liệu không xuất hiện
2. Để khắc phục sử dụng thêm: IMEX=1 cuối câu lệnh cnn.ConnectionString

Em xin nói thêm: Nếu sử dụng IMEX=1 thì nó sẽ lấy tất tần tật, nếu trong cột vừa dạng số vừa dạng text thì nó sẽ chuyển kiểu dữ liệu cột đó thành text, ngược lại nếu dùng IMEX=0 và 2 thì nó sẽ bỏ giá trị text mà chỉ lấy số.
 
Em xin nói thêm: Nếu sử dụng IMEX=1 thì nó sẽ lấy tất tần tật, nếu trong cột vừa dạng số vừa dạng text thì nó sẽ chuyển kiểu dữ liệu cột đó thành text, ngược lại nếu dùng IMEX=0 và 2 thì nó sẽ bỏ giá trị text mà chỉ lấy số.
Điều em muốn hỏi là trong cột dữ liệu vừa có định dạng số, vừa text nếu IMEX=1 thì lấy toàn bộ nhưng số vẫn chuyển thành text. Vậy làm sao để lấy được dữ liệu xuất ra vừa cả số, vừa cả text theo đúng định dạng csdl của nó
 
Điều em muốn hỏi là trong cột dữ liệu vừa có định dạng số, vừa text nếu IMEX=1 thì lấy toàn bộ nhưng số vẫn chuyển thành text. Vậy làm sao để lấy được dữ liệu xuất ra vừa cả số, vừa cả text theo đúng định dạng csdl của nó

Phải kết hợp VBA anh à, trong CSDL quy định kiểu dữ liệu của cả field (Cột), nên việc nhập liệu vừa số vừa text là không đúng chuẩn, nó sẽ hiểu là text.
 
Phải kết hợp VBA anh à, trong CSDL quy định kiểu dữ liệu của cả field (Cột), nên việc nhập liệu vừa số vừa text là không đúng chuẩn, nó sẽ hiểu là text.
Anh nói cụ thể hơn kết hợp như thế nào? chẳng lẻ duyệt hết dữ liệu lấy ra và chuyển sang định dạng số? như vậy tốc độ chắc là chậm
 
Anh nói cụ thể hơn kết hợp như thế nào? chẳng lẻ duyệt hết dữ liệu lấy ra và chuyển sang định dạng số? như vậy tốc độ chắc là chậm

Đâu cần duyệt qua từng cell anh, có nhiều cách để chuyển qua dạng số, ví dụ như *1, tạo cột phụ chuyển nó về value rồi xóa cột phụ... Em nghĩ Anh dư sức để làm.
 
[TIP]Bài tập 5: Chèn 1 mẫu tin vào cơ sở dữ liệu[/TIP]

1./ Cú pháp:

[GPECODE=sql]INSERT INTO [Tên Bảng] ([Cột 1], [Cột 2], ...,[Cột n])
VALUES (GiaTri_1, GiaTri_2, ...,GiaTri_n)[/GPECODE]

Lưu ý phần GiaTri:

  • Nhập ngày thì phải thêm # bao quanh ngày (VD:#15/06/1977#)
  • Nhập số thì chỉ ghi số, không cần thêm gì cả
  • Nhập dạng chuổi thì phải thêm dấu nháy bao quanh chuổi đó(VD: 'HLMT')

2./ Bài Tập:

[INFO1]Anh, chị hãy nhập liệu 1 mẫu tin sau vào cơ sở dữ liệu
  • ID=415
  • W_HDATE=10/01/2013
  • PONO=DW12WQ009
  • MATERIAL NAME=POLY ZIPPER #5
  • COLOR NAME=BEIGE
  • UNIT=M
  • SUPPLIER=HHH VIETNAM
[/INFO1]
 
[TIP]Bài tập 5: Chèn 1 mẫu tin vào cơ sở dữ liệu[/TIP]

1./ Cú pháp:

[GPECODE=sql]INSERT INTO [Tên Bảng] ([Cột 1], [Cột 2], ...,[Cột n])
VALUES (GiaTri_1, GiaTri_2, ...,GiaTri_n)[/GPECODE]

Lưu ý phần GiaTri:

  • Nhập ngày thì phải thêm # bao quanh ngày (VD:#15/06/1977#)
  • Nhập số thì chỉ ghi số, không cần thêm gì cả
  • Nhập dạng chuổi thì phải thêm dấu nháy bao quanh chuổi đó(VD: 'HLMT')
2./ Bài Tập:

[INFO1]Anh, chị hãy nhập liệu 1 mẫu tin sau vào cơ sở dữ liệu
  • ID=415
  • W_HDATE=10/01/2013
  • PONO=DW12WQ009
  • MATERIAL NAME=POLY ZIPPER #5
  • COLOR NAME=BEIGE
  • UNIT=M
  • SUPPLIER=HHH VIETNAM
[/INFO1]
Loay hiay mãi với code sau, nó chèn được dữ liệu nhưng với các code chèn dữ liệu dạng text bị lỗi nhưng chưa tim được nguyên nhân
[GPECODE=vb] Sub Insert_Data_ADO()
Dim lsSQL As String, cnn As Object, lrs As Object
Set cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
Dim Arr()
With cnn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.Path & "\Database.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "INSERT INTO [tblData$] ([ID], [W_HDATE], [PONO], [MATERIAL NAME], [COLOR NAME], [UNIT], [SUPPLIER]) " & _
"VALUES (415, #1/10/2013#, 'DW12WQ009', 'POLY ZIPPER #5', 'BEIGE', 'M', 'HH VIETNAM')"
lrs.Open lsSQL, cnn, 3, 1
Set lrs = Nothing
cnn.Close: Set cnn = Nothing
End Sub
[/GPECODE]
Thử với IMEX=1 cũng không được
 
[info]ADO có thể ghi dữ liệu từ file đang mở vào file đang đóng cùng một Folder được không ạ? Ngoài ADO thì còn có cách nào khác không?
Em dùng code Bài tập 2 để lấy dữ liệu từ 1 file đang đóng thì được, nếu muốn lấy dữ liệu từ 2 file cùng Form thì có được hay không?
Xin cảm ơn ![/info]
 
[info]ADO có thể ghi dữ liệu từ file đang mở vào file đang đóng cùng một Folder được không ạ? Ngoài ADO thì còn có cách nào khác không?
Em dùng code Bài tập 2 để lấy dữ liệu từ 1 file đang đóng thì được, nếu muốn lấy dữ liệu từ 2 file cùng Form thì có được hay không?
Xin cảm ơn ![/info]
1. ADO có thể ghi dữ liệu từ file đang mở vào file đang đóng cùng một Folder được không ạ?
Câu hỏi này chính là Bài tập 5 đây bạn
2. nếu muốn lấy dữ liệu từ 2 file cùng Form thì có được hay không?
Ý của bạn cụ thể nhe thế nào?
 
1. ADO có thể ghi dữ liệu từ file đang mở vào file đang đóng cùng một Folder được không ạ?
Câu hỏi này chính là Bài tập 5 đây bạn
2. nếu muốn lấy dữ liệu từ 2 file cùng Form thì có được hay không?
Ý của bạn cụ thể nhe thế nào?
Hai file cùng 1 folder, cùng form (tiêu đề cột, số cột, chỉ khác dòng), đơn giản là chỉ coppy 2 sheet được chỉ định trong 2 file đang đóng vào 1 file đang mở.
 
Loay hiay mãi với code sau, nó chèn được dữ liệu nhưng với các code chèn dữ liệu dạng text bị lỗi nhưng chưa tim được nguyên nhân
[GPECODE=vb] Sub Insert_Data_ADO()
Dim lsSQL As String, cnn As Object, lrs As Object
Set cnn = CreateObject("ADODB.Connection")
Set lrs = CreateObject("ADODB.Recordset")
Dim Arr()
With cnn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.Path & "\Database.xls" & _
";Extended Properties=""Excel 8.0;HDR=Yes;"";"
.Open
End With
lsSQL = "INSERT INTO [tblData$] ([ID], [W_HDATE], [PONO], [MATERIAL NAME], [COLOR NAME], [UNIT], [SUPPLIER]) " & _
"VALUES (415, #1/10/2013#, 'DW12WQ009', 'POLY ZIPPER #5', 'BEIGE', 'M', 'HH VIETNAM')"
lrs.Open lsSQL, cnn, 3, 1
Set lrs = Nothing
cnn.Close: Set cnn = Nothing
End Sub
[/GPECODE]
Thử với IMEX=1 cũng không được
Em thấy kết quả của anh như thế là ok rồi mà. Đâu thấy xuất hiện lỗi gì đâu anh?

Hai file cùng 1 folder, cùng form (tiêu đề cột, số cột, chỉ khác dòng), đơn giản là chỉ coppy 2 sheet được chỉ định trong 2 file đang đóng vào 1 file đang mở.
Hoàn toàn có thể được em à, emm hãy đưa ví dụ nhé.
 

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

Back
Top Bottom