Khai thác và tùy biến thêm, sửa, xuất file và lấy dữ liệu từ Recordset (2 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.
Thông thường ta lấy dữ liệu từ Recordset đổ tất cả dữ liệu vào 1 địa chỉ nào đó bằng cách sau:

Rich (BB code):
Sub LayDL_HLMT()
    With CreateObject("ADODB.Connection")
        .Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0;Data Source=" & ThisWorkbook.FullName
        Sheet2.Range("A2").CopyFromRecordset .Execute("Select * from [Sheet1$]")
    End With
End Sub
Nhưng ta có thể có những tùy chọn để lấy dữ liệu theo ý. Ví dụ như lấy dữ liệu từng trang với số dòng quy định trước, và còn nhiều cái mà ta chưa khai thác đến. Vậy hôm nay tôi quyết định mở đề tài này để mọi người cùng nhau chia sẻ và thảo luận.
 

File đính kèm

bây giờ em muốn lấy từ dòng 30 đến 70 được không anh hai lúa ?

Được, nếu CSDL có đánh số thứ tự hoặc thông tin gì đó tương tự (như số Row của Sheet Excel) . :)

Ví dụ như lấy dữ liệu từng trang với số dòng quy định trước

Nếu không lầm thì ý trên của bạn HLMT nên hiểu như thế này: xem hình.

Screen Shot 2020-11-09 at 10.46.39 PM.png

Thường làm việc với CSDL, nếu số lượng records lớn thì trong Form hiển thị danh sách, người ta không cho tải một lúc toàn bộ record lên Form mà chỉ tải từng trang với số lượng records qui định (như trong ví dụ trên là 50 records cho mỗi trang). Việc làm này giúp giảm tải lưu lượng dữ liệu truyền qua mạng quá lớn khi kết nối qua mạng LAN, WAN cũng như tài nguyên máy tính nếu phải lưu một Recordset quá lớn vào bộ nhớ.

Mã:
lngBeginId = lngEndId + 1
lngEndId = lngEndId + 50
   
Set rsDanhSachNV = ojbDanhSachNV.RetrieveList(lngBeginId, lngEndId)

Tôi hiểu là vậy, nếu không đúng ý đồ thì thôi nhé :)
 
Lần chỉnh sửa cuối:
Phần ADODB.Connection này với mình lạ quắc.mọi người cho mình link tài liệu tham khảo từ cơ bản với. mình chưa biết nên bắt đầu tìm kiếm và tìm hiểu từ đâu nữa
 
Được, nếu CSDL có đánh số thứ tự hoặc thông tin gì đó tương tự (như số Row của Sheet Excel) . :)



Nếu không lầm thì ý trên của bạn HLMT nên hiểu như thế này: xem hình.

View attachment 248973

Thường làm việc với CSDL, nếu số lượng records lớn thì trong Form hiển thị danh sách, người ta không cho tải một lúc toàn bộ record lên Form mà chỉ tải từng trang với số lượng records qui định (như trong ví dụ trên là 50 records cho mỗi trang). Việc làm này giúp giảm tải lưu lượng dữ liệu truyền qua mạng quá lớn khi kết nối qua mạng LAN, WAN cũng như tài nguyên máy tính nếu phải lưu một Recordset quá lớn vào bộ nhớ.

Mã:
lngBeginId = lngEndId + 1
lngEndId = lngEndId + 50
  
Set rsDanhSachNV = ojbDanhSachNV.RetrieveList(lngBeginId, lngEndId)

Tôi hiểu là vậy, nếu không đúng ý đồ thì thôi nhé :)
Đúng đó bạn, ví dụ thêm là nếu tôi truy vấn mà ra kết quả hơn số dòng quy định (Hơn vùng dữ liệu, hơn số dòng mặc định trong 1 sheet...) thì tôi sẽ ngắt nó ra và chuyển sang nơi khác.
 
Đúng đó bạn, ví dụ thêm là nếu tôi truy vấn mà ra kết quả hơn số dòng quy định (Hơn vùng dữ liệu, hơn số dòng mặc định trong 1 sheet...) thì tôi sẽ ngắt nó ra và chuyển sang nơi khác.
Vậy cho ví dụ thực tiễn luôn cho mọi người học hỏi bác Hai Lúa ơi!
 
Lần chỉnh sửa cuối:
Lấy được nhưng không ý nghĩa gì hết,
Khi cơ sở dữ liệu thì người ta không để ý thứ tự dòng, vì coi vai trò dòng như nhau (khác excel)
Tùy biến sử dụng thôi bạn, tôi chỉ đưa ra là có thể làm được điều đó. Có thể đối với người này không có ý nghĩa gì nhưng cũng có khi đối với người khác nó rất có ý nghĩa.
 
Nếu lấy dòng 20 to 30 thử chơi kiểu cho nó vào 1 Array xong chạy 2 dòng For Next chặt cái đầu cái đuôi cho vào thùng rác xong lấy khúc giữa xem sao ???!!!
 
Nếu lấy dòng 20 to 30 thử chơi kiểu cho nó vào 1 Array xong chạy 2 dòng For Next chặt cái đầu cái đuôi cho vào thùng rác xong lấy khúc giữa xem sao ???!!!
Đó là một cách, mời các bạn tìm thêm cách khác mà không đưa vào Array nhé.
 
Hihi về CSDL em yếu lắm, đợt trước anh @ongke0711 có gợi ý em cũng viết được 1 sub bằng ADO lấy được số Record theo ý muốn trong Table, chỉ cần nhập số dòng bắt đầu và kết thúc không cần STT gì cả.
Cách đơn giản nhất là em di chuyển con trỏ đến dòng đó rồi đổ dữ liệu.
Ví dụ anh lấy 70 dòng từ dòng 30 thì code như sau:

Mã:
Sub LayDL_HLMT1()
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        .Move 29
        Sheet2.Range("A2").CopyFromRecordset .DataSource, 70
    End With
End Sub
 
Cách đơn giản nhất là em di chuyển con trỏ đến dòng đó rồi đổ dữ liệu.
Ví dụ anh lấy 70 dòng từ dòng 30 thì code như sau:

Mã:
Sub LayDL_HLMT1()
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        .Move 29
        Sheet2.Range("A2").CopyFromRecordset .DataSource, 70
    End With
End Sub
Vậy thì thế này cũng được mà bác
Mã:
Sub LayDL_HLMT()
    With CreateObject("ADODB.Connection")
        .Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0;Data Source=" & ThisWorkbook.FullName
        Sheet2.Range("A2").CopyFromRecordset .Execute("Select * from [Sheet1$A30:C100]")
    End With
End Sub
 
Cách đơn giản nhất là em di chuyển con trỏ đến dòng đó rồi đổ dữ liệu.
Ví dụ anh lấy 70 dòng từ dòng 30 thì code như sau:

Mã:
Sub LayDL_HLMT1()
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        .Move 29
        Sheet2.Range("A2").CopyFromRecordset .DataSource, 70
    End With
End Sub
hay thế ... cứ dấu hoài giờ mới biết
 
Vậy thì thế này cũng được mà bác
Mã:
Sub LayDL_HLMT()
    With CreateObject("ADODB.Connection")
        .Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0;Data Source=" & ThisWorkbook.FullName
        Sheet2.Range("A2").CopyFromRecordset .Execute("Select * from [Sheet1$A30:C100]")
    End With
End Sub
bài 13 viết thành cái hàm truyền cái Tham số dòng dầu và dòng cuối vào sẻ hay hơn đấy
Mạnh nhìn qua là biết ngay à
 
Vậy thì thế này cũng được mà bác
Mã:
Sub LayDL_HLMT()
    With CreateObject("ADODB.Connection")
        .Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0;Data Source=" & ThisWorkbook.FullName
        Sheet2.Range("A2").CopyFromRecordset .Execute("Select * from [Sheet1$A30:C100]")
    End With
End Sub
Ví dụ mình truy vấn với CSDL là Access thì trường hợp này không thể đáp ứng yêu cầu nhé bạn.
hay thế ... cứ dấu hoài giờ mới biết
Giấu gì đâu anh, nếu giấu thì đã không viết bài về ADO cách đây khá lâu rồi.
 
Lần chỉnh sửa cuối:
Cách đơn giản nhất là em di chuyển con trỏ đến dòng đó rồi đổ dữ liệu.
Ví dụ anh lấy 70 dòng từ dòng 30 thì code như sau:

Mã:
Sub LayDL_HLMT1()
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        .Move 29
        Sheet2.Range("A2").CopyFromRecordset .DataSource, 70
    End With
End Sub
trời ngắn dữ vậy anh :eek:
 
bài 13 viết lại sơ bộ như sau thấy hay mà vui đấy .... HLMT = số 1 he -0-0-0-

Mã:
Sub GetRs(ByVal dongdau As Long, ByVal dongcuoi As Long)
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        .Move dongdau
        Sheet2.Range("A2").CopyFromRecordset .DataSource, dongcuoi
    End With
End Sub

Sub Main()
    Call GetRs(29, 70)
End Sub
 
bài 13 viết lại sơ bộ như sau thấy hay mà vui đấy .... HLMT = số 1 he -0-0-0-

Mã:
Sub GetRs(ByVal dongdau As Long, ByVal dongcuoi As Long)
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        .Move dongdau
        Sheet2.Range("A2").CopyFromRecordset .DataSource, dongcuoi
    End With
End Sub

Sub Main()
    Call GetRs(29, 70)
End Sub
trời còn cái tham số Range A2 để đi đâu ? sao khong truyền luôn
 
bài 13 viết lại sơ bộ như sau thấy hay mà vui đấy .... HLMT = số 1 he -0-0-0-

Mã:
Sub GetRs(ByVal dongdau As Long, ByVal dongcuoi As Long)
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        .Move dongdau
        Sheet2.Range("A2").CopyFromRecordset .DataSource, dongcuoi
    End With
End Sub

Sub Main()
    Call GetRs(29, 70)
End Sub
Tùy biến sử dụng thôi anh. Thêm ít nhất 3 tham số nữa là cái đường dẫn đến file nguồn, câu lệnh truy vấn và vùng đổ dữ liệu.
 
bài 13 viết lại sơ bộ như sau thấy hay mà vui đấy .... HLMT = số 1 he -0-0-0-

Mã:
Sub GetRs(ByVal dongdau As Long, ByVal dongcuoi As Long)
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        .Move dongdau
        Sheet2.Range("A2").CopyFromRecordset .DataSource, dongcuoi
    End With
End Sub

Sub Main()
    Call GetRs(29, 70)
End Sub
Anh lưu ý thêm là cái tham số dòng đầu nó bắt đầu từ 0 nhé. Do vậy để cho người dùng khỏi bỡ ngỡ anh nên xử lý nó trong hàm luôn.
 
Đừng nói thế anh ngại lắm em, chỉ biết thế nào chia sẻ thế ấy thôi. Anh nghĩ không ít người biết nhưng họ chưa có cơ hội chia sẻ thôi.
Em biết mà, trên diễn đàn nhiều người giỏi lắm có người về phân tích CSDL, có người giỏi về hệ thống..... mà chắc máy ảnh bận nên ít comment
 
Vậy cho ví dụ thực tiễn luôn cho mọi người học hỏi bác Hai Lúa ơi!
Gửi ví dụ dưới đây luôn, code dựa vào file mẫu bài 1. Ví dụ tôi lấy ví dụ là 17 dòng cho mỗi sheet, đổ khi nào hết thì thôi. Tùy biến sử dụng với dữ liệu lấy theo ý nhé.

Mã:
Sub LayDL_HLMT_2()
    Dim sht As Worksheet
    Dim SoSheet As Integer
    Const SoDong = 17
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        While Not .EOF
            SoSheet = SoSheet + 1
            Set sht = Worksheets.Add
            sht.Range("A1") = "Sheet: " & SoSheet
            sht.Name = "Sheet_" & SoSheet
            sht.Range("A2").CopyFromRecordset .DataSource, SoDong
        Wend
    End With
End Sub
 
Gửi ví dụ dưới đây luôn, code dựa vào file mẫu bài 1. Ví dụ tôi lấy ví dụ là 17 dòng cho mỗi sheet, đổ khi nào hết thì thôi. Tùy biến sử dụng với dữ liệu lấy theo ý nhé.

Mã:
Sub LayDL_HLMT_2()
    Dim sht As Worksheet
    Dim SoSheet As Integer
    Const SoDong = 17
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        While Not .EOF
            SoSheet = SoSheet + 1
            Set sht = Worksheets.Add
            sht.Range("A1") = "Sheet: " & SoSheet
            sht.Name = "Sheet_" & SoSheet
            sht.Range("A2").CopyFromRecordset .DataSource, SoDong
        Wend
    End With
End Sub
Cái .EOF và BOF đọc microsoft mà em chưa hiểu lắm, nhờ bác nói rõ cái này hơn tí được không?
1604980696073.png
 
Thêm nữa,anh Hai lúa cho em hỏi, như bài #13 em thấy ".move 29" mới lấy được dữ liêu từ 30 trở đi. Sao ở bài #28 này lại không thấy mà vẫn lấy đúng thứ tự ạ
 
Thông thường ta lấy dữ liệu từ Recordset đổ tất cả dữ liệu vào 1 địa chỉ nào đó bằng cách sau:

Rich (BB code):
Sub LayDL_HLMT()
    With CreateObject("ADODB.Connection")
        .Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0;Data Source=" & ThisWorkbook.FullName
        Sheet2.Range("A2").CopyFromRecordset .Execute("Select * from [Sheet1$]")
    End With
End Sub
Nhưng ta có thể có những tùy chọn để lấy dữ liệu theo ý. Ví dụ như lấy dữ liệu từng trang với số dòng quy định trước, và còn nhiều cái mà ta chưa khai thác đến. Vậy hôm nay tôi quyết định mở đề tài này để mọi người cùng nhau chia sẻ và thảo luận.
Lấy dữ liệu có hoặc không có tiêu đề thì ghi sao Sếp?
 
Cái .EOF và BOF đọc microsoft mà em chưa hiểu lắm, nhờ bác nói rõ cái này hơn tí được không?
View attachment 249000
Bạn đọc Bài này để tìm hiểu thêm
Thêm nữa,anh Hai lúa cho em hỏi, như bài #13 em thấy ".move 29" mới lấy được dữ liêu từ 30 trở đi. Sao ở bài #28 này lại không thấy mà vẫn lấy đúng thứ tự ạ

Khác nhau nhe bạn
 
Thiệt là em hỏng có hiểu cái ẩn ý của Sư Phụ luôn.
Có lẽ ý của Thầy là làm thêm cái lựa chọn, nếu muốn lấy dòng tiêu đề hoặc không muốn lấy thì code viết sao ấy anh Hai Lúa , nếu không phải ý của Thầy muốn vậy thì OT muốn vậy thì code sẽ viết thế nào vậy anh, phiền anh chỉ thêm ạ.
Cảm ơn anh Hai Lúa.
 
Có lẽ ý của Thầy là làm thêm cái lựa chọn, nếu muốn lấy dòng tiêu đề hoặc không muốn lấy thì code viết sao ấy anh Hai Lúa , nếu không phải ý của Thầy muốn vậy thì OT muốn vậy thì code sẽ viết thế nào vậy anh, phiền anh chỉ thêm ạ.
Cảm ơn anh Hai Lúa.
Nếu lấy tiêu đề cột thì thêm code sau vào em nhé, tùy biến đưa xuống sheet :
Mã:
        For i = 0 To .Fields.Count - 1
            MsgBox .Fields(i).Name
        Next
Anh ví dụ code anh đưa nó vào mỗi trang được tách ra như sau:

Mã:
Sub LayDL_HLMT_2()
    Dim sht As Worksheet
    Dim SoSheet As Integer, i As Integer
    Const SoDong = 17
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        While Not .EOF
            SoSheet = SoSheet + 1
            Set sht = Worksheets.Add
            sht.Range("A1") = "Sheet: " & SoSheet
            For i = 0 To .Fields.Count - 1
                sht.Cells(2, i + 1) = .Fields(i).Name
            Next
            sht.Name = "Sheet_" & SoSheet
            sht.Range("A3").CopyFromRecordset .DataSource, SoDong
        Wend
    End With
End Sub
 
Nếu lấy tiêu đề cột thì thêm code sau vào em nhé, tùy biến đưa xuống sheet :
Mã:
        For i = 0 To .Fields.Count - 1
            MsgBox .Fields(i).Name
        Next
Anh ví dụ code anh đưa nó vào mỗi trang được tách ra như sau:

Mã:
Sub LayDL_HLMT_2()
    Dim sht As Worksheet
    Dim SoSheet As Integer, i As Integer
    Const SoDong = 17
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        While Not .EOF
            SoSheet = SoSheet + 1
            Set sht = Worksheets.Add
            sht.Range("A1") = "Sheet: " & SoSheet
            For i = 0 To .Fields.Count - 1
                sht.Cells(2, i + 1) = .Fields(i).Name
            Next
            sht.Name = "Sheet_" & SoSheet
            sht.Range("A3").CopyFromRecordset .DataSource, SoDong
        Wend
    End With
End Sub
OT giờ mới chạy thử code tách dữ liệu thành nhiều trang,Ot có đọc bài 28 chỉ hiểu là code lấy từ dòng 17 nhưng chưa hiểu code tách dữ liệu từ dòng 17 sẽ lấy theo điều kiện nào cho mỗi sheet, anh Hai Lúa chỉ dẫn thêm cho OT với ạ.
Cảm ơn anh Hai Lúa nhiều ạ.
 
OT giờ mới chạy thử code tách dữ liệu thành nhiều trang,Ot có đọc bài 28 chỉ hiểu là code lấy từ dòng 17 nhưng chưa hiểu code tách dữ liệu từ dòng 17 sẽ lấy theo điều kiện nào cho mỗi sheet, anh Hai Lúa chỉ dẫn thêm cho OT với ạ.
Cảm ơn anh Hai Lúa nhiều ạ.
Không phải lấy dữ liệu từ dòng 17 mà là lấy hết dữ liệu, mỗi trang là 17 dòng, lấy đến khi hết dữ liệu. Code bài trên đúng yêu cầu của em rồi.
 
OT giờ mới chạy thử code tách dữ liệu thành nhiều trang,Ot có đọc bài 28 chỉ hiểu là code lấy từ dòng 17 nhưng chưa hiểu code tách dữ liệu từ dòng 17 sẽ lấy theo điều kiện nào cho mỗi sheet, anh Hai Lúa chỉ dẫn thêm cho OT với ạ.
Cảm ơn anh Hai Lúa nhiều ạ.
Ah OT hiểu rồi không phải lấy từ dòng 17 mà lấy mỗi sheet 17 dòng, sheet cuối là còn lại.. hihi
Lợi hại lợi hại.. anh Hai Lúa ạ
Bài đã được tự động gộp:

Không phải lấy dữ liệu từ dòng 17 mà là lấy hết dữ liệu, mỗi trang là 17 dòng, lấy đến khi hết dữ liệu. Code bài trên đúng yêu cầu của em rồi.
Dạ vâng, cảm ơn anh Hai Lúa nhiều nhiều.
 
Nếu lấy tiêu đề cột thì thêm code sau vào em nhé, tùy biến đưa xuống sheet :
Mã:
        For i = 0 To .Fields.Count - 1
            MsgBox .Fields(i).Name
        Next
Anh ví dụ code anh đưa nó vào mỗi trang được tách ra như sau:

Mã:
Sub LayDL_HLMT_2()
    Dim sht As Worksheet
    Dim SoSheet As Integer, i As Integer
    Const SoDong = 17
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        While Not .EOF
            SoSheet = SoSheet + 1
            Set sht = Worksheets.Add
            sht.Range("A1") = "Sheet: " & SoSheet
            For i = 0 To .Fields.Count - 1
                sht.Cells(2, i + 1) = .Fields(i).Name
            Next
            sht.Name = "Sheet_" & SoSheet
            sht.Range("A3").CopyFromRecordset .DataSource, SoDong
        Wend
    End With
End Sub
Tôi cứ tưởng là có chiêu gì đó giống như HDR=Yes, kiểu vậy chứ
 
Tiếp tục với dữ liệu bài 1, với đoạn truy vấn sau:

Mã:
"Select * from [Sheet1$]"

Làm cách nào ta lấy dữ liệu 2 cột đầu và 5 dòng cuối của bảng. Kết quả như sau:

1604992549657.png
 
Làm cách nào ta lấy dữ liệu 2 cột đầu và 5 dòng cuối của bảng. Kết quả như sau:

View attachment 249032

Lấy cột thì tôi chỉ biết dùng GetRows, còn cách khác thì chưa biết. (Không tính dùng đến câu lệnh SQL)

Mã:
.Move .RecordCount - 5
varBookmark = .Bookmark
varArray = .GetRows(5, varBookmark, Fields:=Array("ID", "Code"))
Sheet2.Range("A3:B7").Value = Application.WorksheetFunction.Transpose(varArray)
 
Lấy cột thì tôi chỉ biết dùng GetRows, còn cách khác thì chưa biết. (Không tính dùng đến câu lệnh SQL)

Mã:
.Move .RecordCount - 5
varBookmark = .Bookmark
varArray = .GetRows(5, varBookmark, Fields:=Array("ID", "Code"))
Sheet2.Range("A3:B7").Value = Application.WorksheetFunction.Transpose(varArray)
có cách nào khác mà ko xài Transpose không bạn nhỉ ?
 
2 cột thì đoạn này sửa lại thôi, dòng thì em không biết dòng cuối lùi lại 5 tính làm sao cả :D
Rich (BB code):
Sheet2.Range("A2").CopyFromRecordset .DataSource, 5, 2
 
Lấy cột thì tôi chỉ biết dùng GetRows, còn cách khác thì chưa biết. (Không tính dùng đến câu lệnh SQL)

Mã:
.Move .RecordCount - 5
varBookmark = .Bookmark
varArray = .GetRows(5, varBookmark, Fields:=Array("ID", "Code"))
Sheet2.Range("A3:B7").Value = Application.WorksheetFunction.Transpose(varArray)
Duyệt qua từng field được mà bạn
có cách nào khác mà ko xài Transpose không bạn nhỉ ?
Đưa vào listbox rồi đưa xuống, tuy nhiên nó chậm lắm.
 
2 cột thì đoạn này sửa lại thôi, dòng thì em không biết dòng cuối lùi lại 5 tính làm sao cả :D
Rich (BB code):
Sheet2.Range("A2").CopyFromRecordset .DataSource, 5, 2
Lấy số tổng của dòng - 5, di chuyển đến kết quả đó. Bài #44 của bạn @ongke0711 có rồi đó bạn.
 
hay đấy

Mã:
Sheet2.Range("A2").CopyFromRecordset .DataSource, , 3     ''Lay 3 cot
Sheet2.Range("A2").CopyFromRecordset .DataSource, , 1     ''Lay 1 cot

thì nó cũng trên nguyên tắc Rs(dòng, cột) thui mà -0-0-0-
 
Tiếp tục với dữ liệu bài 1, với đoạn truy vấn sau:

Mã:
"Select * from [Sheet1$]"

Làm cách nào ta lấy dữ liệu 2 cột đầu và 5 dòng cuối của bảng. Kết quả như sau:

View attachment 249032
Hehe em đã làm được:
Mã:
Sub LayDL_HLMT1()
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1, 1
        Debug.Print .RecordCount
        .Move .RecordCount - 5
        Sheet2.Range("A2").CopyFromRecordset .DataSource, 5, 2
    End With
End Sub
 
Hehe em đã làm được:
Mã:
Sub LayDL_HLMT1()
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1, 1
        Debug.Print .RecordCount
        .Move .RecordCount - 5
        Sheet2.Range("A2").CopyFromRecordset .DataSource, 5, 2
    End With
End Sub
Ghi tên cột xuống sheet luôn nhé bạn.
 
Hehe em đã làm được:
Mã:
Sub LayDL_HLMT1()
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1, 1
        Debug.Print .RecordCount
        .Move .RecordCount - 5
        Sheet2.Range("A2").CopyFromRecordset .DataSource, 5, 2
    End With
End Sub
vầy đi chon gọn move làm chi nữa
Mã:
Sub LayDL2_HLMT1()
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1, 1
        Debug.Print .RecordCount
        ''.Move .RecordCount - 5
        Sheet2.Range("A2").CopyFromRecordset .DataSource, 5, 2
    End With
End Sub

á vậy thì ra nó lấy 5 dòng trên -0-0-0-
 
vầy đi chon gọn move làm chi nữa
Mã:
Sub LayDL2_HLMT1()
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1, 1
        Debug.Print .RecordCount
        ''.Move .RecordCount - 5
        Sheet2.Range("A2").CopyFromRecordset .DataSource, 5, 2
    End With
End Sub

á vậy thì ra nó lấy 5 dòng trên -0-0-0-
Không move sao lấy được dòng cuối anh?
 
Dễ với các anh chị, khó với em :D
Bạn mượn bài của anh @ongke0711 thêm cáu Array(2,3,5) vô
Bài đã được tự động gộp:

Mã:
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1, 1
        .Move .RecordCount - 5
        ArrData = Application.Transpose(.GetRows(, , Array(1, 2, 4)))
        Sheet2.Cells(1).Resize(UBound(ArrData), UBound(ArrData, 2)).Value = ArrData
    End With
 
Lần chỉnh sửa cuối:
Bạn mượn bài của anh @ongke0711 thêm cáu Array(2,3,5) vô
Bài đã được tự động gộp:

Mã:
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1, 1
        .Move .RecordCount - 5
        ArrData = Application.Transpose(.GetRows(, , Array(1, 2, 4)))
        Sheet2.Cells(1).Resize(UBound(ArrData), UBound(ArrData, 2)).Value = ArrData
    End With
Chị gái hay quá!
 
Bạn mượn bài của anh @ongke0711 thêm cáu Array(2,3,5) vô
Bài đã được tự động gộp:

Mã:
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1, 1
        .Move .RecordCount - 5
        ArrData = Application.Transpose(.GetRows(, , Array(1, 2, 4)))
        Sheet2.Cells(1).Resize(UBound(ArrData), UBound(ArrData, 2)).Value = ArrData
    End With
OT thử code này thì bị lỗi tại dòng.
ArrData = Application.Transpose(.GetRows(, , Array(1, 2, 4)))
Tên lỗi là:
Item cannot be found in the collection corresponding to the requested name or ordinal.
 
OT thử code này thì bị lỗi tại dòng.
ArrData = Application.Transpose(.GetRows(, , Array(1, 2, 4)))
Tên lỗi là:
Item cannot be found in the collection corresponding to the requested name or ordinal.
Không biết chị đã thêm dữ liệu vào sheet1 hay chưa
 
OT thử code này thì bị lỗi tại dòng.
ArrData = Application.Transpose(.GetRows(, , Array(1, 2, 4)))
Tên lỗi là:
Item cannot be found in the collection corresponding to the requested name or ordinal.
Lỗi này xảy ra khi Fields không có trong bảng truy cập. Bạn kiểm tra lại trên Sheet bạn có bao nhiêu cột.
Mãng ADO bắt đầu tính từ 0 nhé ví dụ 5 cột là từ 0,1,2,3,4,
 
Thường thì em dùng như thế này.
PHP:
  Set cn = New ADODB.Connection
  cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strDb & ";"
  Set rs = New ADODB.Recordset
 With rs
    .Open "SELECT ***** WHERE **** ", cn, , , adCmdText
    .MoveFirst
 End With
Sau đó thì tùy biến đưa ra các thông tin như :
PHP:
rs.Fields.Count
Rồi sau em mới
PHP:
.CopyFromRecordset rs
 
Thường thì em dùng như thế này.
PHP:
  Set cn = New ADODB.Connection
  cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strDb & ";"
  Set rs = New ADODB.Recordset
With rs
    .Open "SELECT ***** WHERE **** ", cn, , , adCmdText
    .MoveFirst
End With
Sau đó thì tùy biến đưa ra các thông tin như :
PHP:
rs.Fields.Count
Rồi sau em mới
PHP:
.CopyFromRecordset rs
Đang nói đến xử lý Recordset nhé bạn, có nghĩa là với lý do nào đó mà ta muốn xử lý dữ liệu sau khi đã truy vấn.
Nhưng bàn chút, bạn ghi.
PHP:
.MoveFirst
Nếu chỉ đơn thuần là lấy dữ liệu ra sheet hoặc đếm số cột thì có cần?
 
Đang nói đến xử lý Recordset nhé bạn, có nghĩa là với lý do nào đó mà ta muốn xử lý dữ liệu sau khi đã truy vấn.
Nhưng bàn chút, bạn ghi.
PHP:
.MoveFirst
Nếu chỉ đơn thuần là lấy dữ liệu ra sheet hoặc đếm số cột thì có cần?
Thêm tên cột có vòng lặp gì không anh ơi, gợi ý chút xíu với
 
Vòng lặp hay không vòng lặp đều được bạn nhé. Vì trường hợp này chỉ có 2 cột.
Làm đại chứ em nghĩ ý anh không phải vậy:
Mã:
With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1, 1
        .Move .RecordCount - 5
        Sheet2.Range("A1") = .Fields(0).Name: Sheet2.Range("B1") = .Fields(1).Name
        Sheet2.Range("A2").CopyFromRecordset .DataSource, 5, 2
End With
 
Mã:
Sub LaydulieuWithSever()
    Dim cnn As ConnectionDataHub
    Dim myRst  As Object
On Error GoTo ErrorProcess
    
    Application.ScreenUpdating = False
    If isconnect Then GoTo EndSub
    Set cnn = appClient.OpenConnection("D:\SampleData - Copy.accdb")
    Range("A5:L1000").ClearContents
    Set myRst = cnn.GetdataServer("SELECT * FROM Data")
    'myRst.MoveFirst
    For i = 0 To myRst.Fields.Count - 1
        Cells(5, 1 + i).Value = myRst.Fields(i).Name
    Next i
    Range("A6").CopyFromRecordset myRst
    
GoTo EndSub
ErrorProcess:
    MsgBox Err.Number & ": " & Err.Description
EndSub:

Set myRst = Nothing
Set cnn = Nothing

Application.ScreenUpdating = True
End Sub

Chuẩn bị ra lò đây anh ;)
 
Làm đại chứ em nghĩ ý anh không phải vậy:
Mã:
With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1, 1
        .Move .RecordCount - 5
        Sheet2.Range("A1") = .Fields(0).Name: Sheet2.Range("B1") = .Fields(1).Name
        Sheet2.Range("A2").CopyFromRecordset .DataSource, 5, 2
End With
Đúng là thế, từ những cái đơn giản để người mới có thể hiểu và vận dụng một cách dễ dàng vào bài toán của riêng mình.
 
Mã:
Sub LaydulieuWithSever()
    Dim cnn As ConnectionDataHub
    Dim myRst  As Object
On Error GoTo ErrorProcess
   
    Application.ScreenUpdating = False
    If isconnect Then GoTo EndSub
    Set cnn = appClient.OpenConnection("D:\SampleData - Copy.accdb")
    Range("A5:L1000").ClearContents
    Set myRst = cnn.GetdataServer("SELECT * FROM Data")
    'myRst.MoveFirst
    For i = 0 To myRst.Fields.Count - 1
        Cells(5, 1 + i).Value = myRst.Fields(i).Name
    Next i
    Range("A6").CopyFromRecordset myRst
   
GoTo EndSub
ErrorProcess:
    MsgBox Err.Number & ": " & Err.Description
EndSub:

Set myRst = Nothing
Set cnn = Nothing

Application.ScreenUpdating = True
End Sub

Chuẩn bị ra lò đây anh ;)
Chúc mừng em. Khi nào "ra lò" nhớ mở tiệc mừng nhé.
 
Có gì đâu mà ăn mừng anh, máy hôm nay chưa có thời gian với lại em dang nghiên cứu cái encryption nên chưa đưa hội đồng sư phạm xem trước hihihi
Vẫn theo kiểu truyền thống là gửi và nhận gói tin hay là kiểu mới JSON? Hay là cả hay đều không phải? Có thể bật mí chút không em :::"""><
 
Vẫn theo kiểu truyền thống là gửi và nhận gói tin hay là kiểu mới JSON? Hay là cả hay đều không phải? Có thể bật mí chút không em :::"""><
hihih có gì ghê gớm đâu anh, ai hiểu sao cứ làm vậy, mỗi người mỗi kiểu mà, đã làm trên Win thì cứ bám theo ông MS mà làm. trên android thì theo ông Google, trên Linux thì theo Linux
 
Cũng tương tự với bài tách dữ liệu ở Bài #28 nhưng dưới đây ta khai thác đến 'Page' trong Recordset như sau:

Mã:
Sub Page_HLMT_1()
    With CreateObject("ADODB.Recordset")
        .Open "Select * from [Sheet1$]", "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1
        .PageSize = 20
        MsgBox .PageCount
    End With
End Sub
Tôi đưa ví dụ chia mỗi trang ra 20 dòng và sau đó chạy code trên với dữ liệu bài số 1 thì ta được 6 trang. Như vậy ta có thể khai thác thêm để đưa dữ liệu trong Recordset cho từng trang xuống sheet.
 
Cũng tương tự với bài tách dữ liệu ở Bài #28 nhưng dưới đây ta khai thác đến 'Page' trong Recordset như sau:

Mã:
Sub Page_HLMT_1()
    With CreateObject("ADODB.Recordset")
        .Open "Select * from [Sheet1$]", "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1
        .PageSize = 20
        MsgBox .PageCount
    End With
End Sub
Tôi đưa ví dụ chia mỗi trang ra 20 dòng và sau đó chạy code trên với dữ liệu bài số 1 thì ta được 6 trang. Như vậy ta có thể khai thác thêm để đưa dữ liệu trong Recordset cho từng trang xuống sheet.

Cảm ơn anh @Hai Lúa Miền Tây về bài em viết em đang quan tâm.
Em có nhu cầu đưa dữ liệu ra màn hình. Do dữ liệu dài mà muốn hiển thị đầy đủ nên cần đưa dữ liệu theo cách trôi dần từng dòng lên trên màn hình 1 cách tự động.
Màn hình hiển thị được 10 dòng, lần đầu em đưa 10 record đầu tiên (record 0-9), sau 5s sẽ hiển thị từ record 1 đến 10, sau 5s tiếp theo lại query từ record 2-11, cứ thế cho đến khi hết dữ liệu. (Bản chất 1 muốn trượt dữ liệu 1 cách mượt nhất và trượt tự động thông qua lệnh Application.Ontime)
Qua những bài viết đầu tiên em cũng đã hiểu 1 chút tuy nhiên vẫn còn lúng túng. Anh hướng dẫn giúp tình huống trên nhé.
Cảm ơn anh
 
Mình oánh dấu thớt này để theo dõi chứ hông phải sì pem đâu á.
 
Cũng tương tự với bài tách dữ liệu ở Bài #28 nhưng dưới đây ta khai thác đến 'Page' trong Recordset như sau:

Mã:
Sub Page_HLMT_1()
    With CreateObject("ADODB.Recordset")
        .Open "Select * from [Sheet1$]", "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1
        .PageSize = 20
        MsgBox .PageCount
    End With
End Sub
Tôi đưa ví dụ chia mỗi trang ra 20 dòng và sau đó chạy code trên với dữ liệu bài số 1 thì ta được 6 trang. Như vậy ta có thể khai thác thêm để đưa dữ liệu trong Recordset cho từng trang xuống sheet.
Đoạn này không có tác dụng ghi dữ liệu xuống bảng tính ở sheet khác à anh Hai Lúa ơi T_T
 
Cảm ơn anh @Hai Lúa Miền Tây về bài em viết em đang quan tâm.
Em có nhu cầu đưa dữ liệu ra màn hình. Do dữ liệu dài mà muốn hiển thị đầy đủ nên cần đưa dữ liệu theo cách trôi dần từng dòng lên trên màn hình 1 cách tự động.
Màn hình hiển thị được 10 dòng, lần đầu em đưa 10 record đầu tiên (record 0-9), sau 5s sẽ hiển thị từ record 1 đến 10, sau 5s tiếp theo lại query từ record 2-11, cứ thế cho đến khi hết dữ liệu. (Bản chất 1 muốn trượt dữ liệu 1 cách mượt nhất và trượt tự động thông qua lệnh Application.Ontime)
Qua những bài viết đầu tiên em cũng đã hiểu 1 chút tuy nhiên vẫn còn lúng túng. Anh hướng dẫn giúp tình huống trên nhé.
Cảm ơn anh
Ý bạn là làm theo kiểu "Lazy loading"? Để đơn giản hơn thì bạn tạo một nút gọi nôm na là nút "Xem Thêm", bạn quy định đổ dữ liệu bao nhiêu dòng xuống sheet thì hiện cái nút đó phìa bên dưới của vùng dữ liệu, nếu người dùng thích thì click vào đó xem tiếp, đến khi đổ hết dữ liệu thì nút đó không hiện lên nữa.
 
Đoạn này không có tác dụng ghi dữ liệu xuống bảng tính ở sheet khác
Ghi xuống đâu thì mình ghi thôi. @@

'Người ta' ghi chú code đó có tác dụng gì rồi mà. Tức là nếu kết quả query trả về 99 dòng, thì chia 99 thành n phần, trong đó (n-1) phần = 20 dòng, phần n có 99 - 20*(n-1) dòng

1605236110713.png
 
Ghi xuống đâu thì mình ghi thôi. @@

'Người ta' ghi chú code đó có tác dụng gì rồi mà. Tức là nếu kết quả query trả về 99 dòng, thì chia 99 thành n phần, trong đó (n-1) phần = 20 dòng, phần n có 99 - 20*(n-1) dòng

View attachment 249238
Cảm ơn befaint, với OT thì những trao đổi liên quan đến lập trìn OT rất khó hiểu chỉ biết chạy code xem kết quả là cái gì bạn ạ.. hic hic
 
Ý bạn là làm theo kiểu "Lazy loading"?
Không phải rồi anh.
Tác giả có cái màn hình treo ở giữa lối đi, hiện chữ thật to, được 10 dòng.
Giờ muốn kết quả chạy trôi trôi theo phương thẳng đứng, trượt từng dòng một theo thời gian. Kiểu như trình diễn PowerPoint, như kiểu đoạn kết thúc bộ phim có chạy nội dung tác giả kịch bản, đạo diễn, diễn viên, kỹ thuật âm thanh/ sánh sáng ấy. :)
 
Không phải rồi anh.
Tác giả có cái màn hình treo ở giữa lối đi, hiện chữ thật to, được 10 dòng.
Giờ muốn kết quả chạy trôi trôi theo phương thẳng đứng, trượt từng dòng một theo thời gian. Kiểu như trình diễn PowerPoint, như kiểu đoạn kết thúc bộ phim có chạy nội dung tác giả kịch bản, đạo diễn, diễn viên, kỹ thuật âm thanh/ sánh sáng ấy. :)
Không khéo làm kiểu này chỉ khó chịu cho người dùng hơn và chưa chắc là thời gian đợi ít hơn so với thời gian đổ dữ liệu 1 lần.
 
Không khéo làm kiểu này chỉ khó chịu cho người dùng hơn và chưa chắc là thời gian đợi ít hơn so với thời gian đổ dữ liệu 1 lần.
Em chỉ diễn giải giúp tác giả thôi. :D

Tác giả cần làm vậy để cung cấp thông tin cho những người cần đọc nó. Kiểu như sàn chứng khoán đó anh.

Và tất nhiên không quan tâm lắm về thời gian đổ dữ liệu kia, chỉ quan tâm kết quả cuối cùng là dữ liệu chạy chạy trên màn hình thôi.

----
Phương án có thể là 30 phút, hay vài tiếng gì đó mới truy vấn 1 lần. Kết quả ghi vào sheet tạm hoặc biến tạm, sau đó mới đẩy ra màn hình theo ý tác giả.
 
Em chỉ diễn giải giúp tác giả thôi. :D

Tác giả cần làm vậy để cung cấp thông tin cho những người cần đọc nó. Kiểu như sàn chứng khoán đó anh.

Và tất nhiên không quan tâm lắm về thời gian đổ dữ liệu kia, chỉ quan tâm kết quả cuối cùng là dữ liệu chạy chạy trên màn hình thôi.

----
Phương án có thể là 30 phút, hay vài tiếng gì đó mới truy vấn 1 lần. Kết quả ghi vào sheet tạm hoặc biến tạm, sau đó mới đẩy ra màn hình theo ý tác giả.
Nếu có thời gian em thử giúp bạn ấy vấn đề này nhé :)
 
Cảm ơn befaint, với OT thì những trao đổi liên quan đến lập trìn OT rất khó hiểu chỉ biết chạy code xem kết quả là cái gì bạn ạ.. hic hic
Anh ghi dữ liệu xuống Sheet2 theo file mẫu bài 1 nhé

Mã:
Sub Page_HLMT_2()
    Dim intPage As Integer, i As Integer, intSq As Integer, intRecord As Integer
    With CreateObject("ADODB.Recordset")
        .Open "Select * from [Sheet1$]", "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1
        .PageSize = 20
        Sheet2.Cells.ClearContents
        For intPage = 1 To .PageCount
            For intRecord = 1 To .PageSize
                i = i + 1
                intSq = intSq + 1
                Sheet2.Range("A" & i) = intSq
                Sheet2.Range("B" & i) = !ID
                Sheet2.Range("C" & i) = !Code
                Sheet2.Range("D" & i) = !Price
                .MoveNext
                If .EOF Then Exit For
            Next
            i = i + 1
        Next
    End With
End Sub

Em có thể thêm dòng tổng cho mỗi trang và dòng tổng cộng của cột 'Price' cho toàn bộ trang qua code đơn giản trên để dễ hình dung.
 
Anh ghi dữ liệu xuống Sheet2 theo file mẫu bài 1 nhé

Mã:
Sub Page_HLMT_2()
    Dim intPage As Integer, i As Integer, intSq As Integer, intRecord As Integer
    With CreateObject("ADODB.Recordset")
        .Open "Select * from [Sheet1$]", "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1
        .PageSize = 20
        Sheet2.Cells.ClearContents
        For intPage = 1 To .PageCount
            For intRecord = 1 To .PageSize
                i = i + 1
                intSq = intSq + 1
                Sheet2.Range("A" & i) = intSq
                Sheet2.Range("B" & i) = !ID
                Sheet2.Range("C" & i) = !Code
                Sheet2.Range("D" & i) = !Price
                .MoveNext
                If .EOF Then Exit For
            Next
            i = i + 1
        Next
    End With
End Sub

Em có thể thêm dòng tổng cho mỗi trang và dòng tổng cộng của cột 'Price' cho toàn bộ trang qua code đơn giản trên để dễ hình dung.
Cảm ơn anh Hai Lúa, OT test thử thấy kết quả rồi , dữ liệu xen lẫn 1 dòng trống 20 dòng một bảng, như vậy mỗi dòng trống là ta có thể thêm dòng tổng hợp vào những dòng này phải không anh, cảm ơn anh Hai Lúa, OT đã hiểu ứng dụng như chắc muốn viết thêm dòng tổng cộng thì phải thêm 1 sub bằng VBA thôi ạ chứ chư biết cách thêm trong đoạn code ADO này của Anh, hihi
 
Anh ghi dữ liệu xuống Sheet2 theo file mẫu bài 1 nhé

Mã:
Sub Page_HLMT_2()
    Dim intPage As Integer, i As Integer, intSq As Integer, intRecord As Integer
    With CreateObject("ADODB.Recordset")
        .Open "Select * from [Sheet1$]", "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName, 1
        .PageSize = 20
        Sheet2.Cells.ClearContents
        For intPage = 1 To .PageCount
            For intRecord = 1 To .PageSize
                i = i + 1
                intSq = intSq + 1
                Sheet2.Range("A" & i) = intSq
                Sheet2.Range("B" & i) = !ID
                Sheet2.Range("C" & i) = !Code
                Sheet2.Range("D" & i) = !Price
                .MoveNext
                If .EOF Then Exit For
            Next
            i = i + 1
        Next
    End With
End Sub

Em có thể thêm dòng tổng cho mỗi trang và dòng tổng cộng của cột 'Price' cho toàn bộ trang qua code đơn giản trên để dễ hình dung.
Như vậy ngắn gọn hơn chứ anh Hai Lúa
Mã:
Sub Page_HLMT_2()
    With CreateObject("ADODB.Recordset")
        .Open ("Select * from [Sheet1$]"), "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0 Xml;Data Source=" & ThisWorkbook.FullName
        .pagesize = 20
        While Not .EOF
            Sheet2.Range("A" & Rows.Count).End(xlUp).Offset(2).CopyFromRecordset .DataSource, .pagesize
        Wend
    End With
End Sub
 

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

Back
Top Bottom