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

Liên hệ QC
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
Lấy dữ liệu bài 1 của HLMT để test trường hợp sau
Mã:
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
   
   ''''''''Bat dau doan 1''''''''''''''''''''''''''''''''''''''''''''''''''
[B]   Dim Arr(1 To 100, 1 To 4)[/B]
[B]   Dim k As Long[/B]
[B]        k = 1[/B]
[B]      While lrs.EOF = False[/B]
[B]           Arr(k, 1) = lrs.Fields(0)[/B]
[B]           Arr(k, 2) = lrs.Fields(1)[/B]
[B]           Arr(k, 3) = lrs.Fields(2)[/B]
[B]           Arr(k, 4) = lrs.Fields(3)[/B]
[B]           k = k + 1[/B]
[B]           lrs.MoveNext[/B]
[B]    Wend[/B]
[B]'Range("A2").Resize(k, 4) = Arr[/B]
''''''''''Ket Thuc Doan 1


   ''''''''Bat dau doan 2''''''''''''''''''''''''''''''''''''''''''''''


[B]  Range("A2").CopyFromRecordset lrs[/B]


   ''''''''Ket Thuc Doan 2'''''''''''''''''''''''''''''''''''''''''


lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing
End Sub
Xin cho hỏi là tại sau có đoạn 1 thì Range("A2").CopyFromRecordset lrs không hoạt động?
 
CopyFromRecordset chỉ copy từ record hiện tại thôi, nếu muốn copy từ đầu thì thêm lrs.MoveFirst vào.
 
Lấy dữ liệu bài 1 của HLMT để test trường hợp sau
Mã:
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
   
   ''''''''Bat dau doan 1''''''''''''''''''''''''''''''''''''''''''''''''''
[B]   Dim Arr(1 To 100, 1 To 4)[/B]
[B]   Dim k As Long[/B]
[B]        k = 1[/B]
[B]      While lrs.EOF = False[/B]
[B]           Arr(k, 1) = lrs.Fields(0)[/B]
[B]           Arr(k, 2) = lrs.Fields(1)[/B]
[B]           Arr(k, 3) = lrs.Fields(2)[/B]
[B]           Arr(k, 4) = lrs.Fields(3)[/B]
[B]           k = k + 1[/B]
[B]           lrs.MoveNext[/B]
[B]    Wend[/B]
[B]'Range("A2").Resize(k, 4) = Arr[/B]
''''''''''Ket Thuc Doan 1


   ''''''''Bat dau doan 2''''''''''''''''''''''''''''''''''''''''''''''


[B]  Range("A2").CopyFromRecordset lrs[/B]


   ''''''''Ket Thuc Doan 2'''''''''''''''''''''''''''''''''''''''''


lrs.Close: Set lrs = Nothing
cnn.Close: Set cnn = Nothing
End Sub
Xin cho hỏi là tại sau có đoạn 1 thì Range("A2").CopyFromRecordset lrs không hoạt động?

Bạn hãy thử đưa cái đoạn đó lên trước cái Arr rồi chạy, sau đó say luận nhé.
 
Lần chỉnh sửa cuối:
đưa lên trước thì ok, và anh Hậu cũng đã giải thích nên có phần nào hiểu được cấu trúc của nó. Cảm ơn HLMT đã quan tâm.
 
Theo nguyên tắc CSDL, việc truy vấn phải tương đối dễ dàng. Nếu có sự rắc rối thì bảng và CSDL nên thiết kế lại cho phù hợp.
Đọc toàn topic thấy cái câu này của anh VetMini nói là hợp lý nhất. Xưa kia học CSDL thấy thiết kế các bảng là phức tạp nhất, sau khi thiết kế xong các bảng phù hợp thì công việc truy vấn bằng SQL rất đơn giản, tối đa truy vấn các phép kết cũng chỉ dừng lại là con số 4 bản.
 
Đọc toàn topic thấy cái câu này của anh VetMini nói là hợp lý nhất. Xưa kia học CSDL thấy thiết kế các bảng là phức tạp nhất, sau khi thiết kế xong các bảng phù hợp thì công việc truy vấn bằng SQL rất đơn giản, tối đa truy vấn các phép kết cũng chỉ dừng lại là con số 4 bản.

Chẳng lẻ hơn ba trăm bài còn lại chẳng hợp lý? Nếu bài nào không hợp lý bạn có thể cho biết để chúng tôi học hỏi thêm.
 
CÒn em đọc bài về DAO cũng không hiểu gì cả, hay bị ĐAO rồi?

Thật sự bạn không cần hiểu. Một trong những mục đích của LT Hướng Đối Tượng là giúp cho người ta tránh cái rắc rối này.
Nếu bạn tìm được bài có function hoặc sub gói trọn cách truy cập thì bạn chỉ cần nạp tham số (trước măt là tên file và câu truy vấn), function trả về cho bạn một recordset, bạn dùng lệnh copyfromrecordset đẩy nó nào worksheet.

Nếu người viết cái function kia viết chính chắn thì người sử dụng không cần phải biết nó dùng ADO hay DAO.
 
Thấy cái vụ ADO đã khó nhớ rồi lại thêm Vụ DAO nữa thật sự cùng muốn học lắm những cũng không biết bắt đầu từ đâu ....

Nếu được đề nghị Bạn nào đó cho xin một ví dụ về ADO Và 1 DAO để mình phân biệt đâu là DAO và đâu Là ADO....

xin cảm ơn
 
Nếu người viết cái function kia viết chính chắn thì người sử dụng không cần phải biết nó dùng ADO hay DAO.

Vấn đề nằm ở chỗ này nè!
Thường khi sưu tầm code trên mạng, đa phần là không vừa ý, phải sửa lại. Mà muốn sửa được thì bắt buộc phải HIỂU nó. Vậy là.. xong phim luôn
Bời vậy tôi thường cố gắng viết code sao cho đạt mức tổng quát nhất, để người dùng chỉ cần nạp thông số đầu vào là đủ (khỏi cần hiểu, khỏi cần sửa code)
 
Thấy cái vụ ADO đã khó nhớ rồi lại thêm Vụ DAO nữa thật sự cùng muốn học lắm những cũng không biết bắt đầu từ đâu ....

Nếu được đề nghị Bạn nào đó cho xin một ví dụ về ADO Và 1 DAO để mình phân biệt đâu là DAO và đâu Là ADO....

xin cảm ơn

DAO truy cập dữ liệu ở tầng lớp thấp hơn ADO (*). Vì vậy nếu đặt đúng chỗ thì DAO hiệu nghiệm hơn ADO. Ngược lại, vì ở tầng cao hơn nên ADO tổng quát hơn.

Làm cách nào để phân biệt? Chịu thua. Tôi nhìn cái đối tượng, nó bảo dao thì mình biết dao, búa thì mình biết búa.

(*) từ "tầng lớp thấp" là dịch từ "low level", trong thuât ngữ lập trình, tầng lớp được hiểu theo lớp vỏ củ hành, thấp chỉ có nghĩa là nó gần với cái lõi hơn, hoàn toàn không liên quan gì đến hay hoặc dở.
 
DAO truy cập dữ liệu ở tầng lớp thấp hơn ADO (*). Vì vậy nếu đặt đúng chỗ thì DAO hiệu nghiệm hơn ADO. Ngược lại, vì ở tầng cao hơn nên ADO tổng quát hơn.

Làm cách nào để phân biệt? Chịu thua. Tôi nhìn cái đối tượng, nó bảo dao thì mình biết dao, búa thì mình biết búa.

(*) từ "tầng lớp thấp" là dịch từ "low level", trong thuât ngữ lập trình, tầng lớp được hiểu theo lớp vỏ củ hành, thấp chỉ có nghĩa là nó gần với cái lõi hơn, hoàn toàn không liên quan gì đến hay hoặc dở.

Bạn nói về tầng? Mà là tầng gì? Tầng vật lý? Nếu là tầng vật lý thì nó nằm trong tầng thứ mấy trong 7 tầng?
 
Bạn nói về tầng? Mà là tầng gì? Tầng vật lý? Nếu là tầng vật lý thì nó nằm trong tầng thứ mấy trong 7 tầng?

1. Tầng thứ mấy thì có liên quan gì đến lập trình VBA?

2. ADO: Nếu cần phải xác định tính chất vật lý thì "tổng quát" làm quái gì nữa.
 
1. Tầng thứ mấy thì có liên quan gì đến lập trình VBA?

2. ADO: Nếu cần phải xác định tính chất vật lý thì "tổng quát" làm quái gì nữa.

Ậy tôi thấy bạn nói về tầng nên tôi giật mình mà hỏi bạn thế thôi, vì tầng low level thì tôi mới nghe.
 
Cho mình hỏi dùng câu lệnh nào (hàm nào) để lọc ra các dòng có giá trị của 1 cột bị trùng.
Ví dụ mình có dử liệu gồm 3 cột A, B, C mình muốn lọc ra các dòng có cột A xuất hiện từ 2 lần trở lên.
(Mình tìm mãi mà chưa tìm ra được cách giải quyết bằng câu lệnh SQL)
Mình cám ơn!
 
Lần chỉnh sửa cuối:
Web KT
Back
Top Bottom