Cách truy vấn dữ liệu trên cùng file không mở kết nối (ADODB.Connection)

Liên hệ QC
Anh giới thiệu thêm ứng dụng của truy vấn này được không?
Vì nếu để lọc dữ liệu thì AdvanceFilter có vẻ đơn giản, dễ áp dụng, dù nó có chậm 1 chút.
Em test AdvanceFilter 10k dòng thì thời gian cũng tương đương, còn 120k dòng thì đúng là không bằng cách truy vấn trên.
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Tg As Long
Tg = Timer()
If Target.Address = "$F$2" Then
   [A1:D150000].AdvancedFilter 2, [F1:F2], [H1:J1]
End If
MsgBox Timer - Tg
End Sub
Thảo thử với 1 triệu dòng mới thấy sự khác biệt.
 
Sắp xếp và lọc duy nhất:

Mã:
Sub LocDL_HLMT()
    Dim rst As Object, vArray As Variant, i As Long, thoigian As Long 'Khai bao bien
    Dim strID As String, strMatID As String, strDup As String
    Set rst = CreateObject("ADODB.Recordset") ' Khoi tao Recordset
    vArray = Sheet1.Range("A2:D10001").Value ' Du lieu nguon vao mang
    thoigian = Timer()
    With rst
        'Khai bao va mo Recorset
        .Fields.Append "ID", 3
        .Fields.Append "MatID", 200, 10
        .Fields.Append "Balance", 3
        .Open
        'Dua du lieu nguon tu mang da set vao Recordset
        For i = LBound(vArray) To UBound(vArray)
            .AddNew
            .Fields("ID").Value = vArray(i, LBound(vArray))
            .Fields("MatID").Value = vArray(i, LBound(vArray) + 1)
            .Fields("Balance").Value = vArray(i, LBound(vArray) + 3)
            .Update
        Next
        'Loc du lieu trong Recordset
        .Filter = "Balance " & Sheet2.Range("B1")
        .Sort = "ID desc" 'Sap xep
        .MoveFirst
        strDup = ""
        Do Until .EOF
            strID = .Fields.Item("ID")
            strMatID = .Fields.Item("MatID")
            If (strDup = strID & "-" & strMatID) Then
                .Delete
            End If
            strDup = strID & "-" & strMatID
            .Update
            .MoveNext
        Loop
        .MoveFirst
    End With
    Sheet2.Range("A2:D11000").ClearContents 'Xoa vung du lieu
    Sheet2.Range("A4").CopyFromRecordset rst   'Do du lieu tu Recordset da loc xuong sheet
    MsgBox Timer - thoigian
    rst.Close
    Set rst = Nothing
End Sub
 

File đính kèm

  • LocDL_KhongMoKetNoi_LocDuyNhat.xlsm
    215.5 KB · Đọc: 72
Lần chỉnh sửa cuối:
Lọc, sắp xếp, tính tổng

Mã:
Sub LocDL_HLMT()
    Dim rst As Object, vArray As Variant, i As Long, thoigian As Long 'Khai bao bien
    Dim strID As String, strMatID As String, strDup As String
    Dim intTotal As Integer
    Set rst = CreateObject("ADODB.Recordset") ' Khoi tao Recordset
    vArray = Sheet1.Range("A2:D10001").Value ' Du lieu nguon vao mang
    thoigian = Timer()
    With rst
        'Khai bao va mo Recorset
        .Fields.Append "ID", 3
        .Fields.Append "MatID", 200, 10
        .Fields.Append "Balance", 3
        .Open
        'Dua du lieu nguon tu mang da set vao Recordset
        For i = LBound(vArray) To UBound(vArray)
            .AddNew
            .Fields("ID").Value = vArray(i, LBound(vArray))
            .Fields("MatID").Value = vArray(i, LBound(vArray) + 1)
            .Fields("Balance").Value = vArray(i, LBound(vArray) + 3)
            .Update
        Next
        'Loc du lieu trong Recordset
        .Filter = "Balance " & Sheet2.Range("B1")
        .Sort = "ID" 'Sap xep
        .MoveFirst
        strDup= ""
        Do Until .EOF
            strID = .Fields.Item("ID")
            strMatID = .Fields.Item("MatID")
            intTotal = 0
            If (strDup = strID & "-" & strMatID) Then
                intTotal = intTotal + .Fields.Item("Balance")
                .MovePrevious
                .Fields.Item("Balance") = intTotal + .Fields.Item("Balance")
                .MoveNext
                .Delete
            End If
            strDup = strID & "-" & strMatID
            .Update
            .MoveNext
        Loop
        .MoveFirst
    End With
    Sheet2.Range("A2:D11000").ClearContents 'Xoa vung du lieu
    Sheet2.Range("A4").CopyFromRecordset rst   'Do du lieu tu Recordset da loc xuong sheet
    MsgBox Timer - thoigian
    rst.Close
    Set rst = Nothing
End Sub
 

File đính kèm

  • LocDL_KhongMoKetNoi_TinhTong.xlsm
    220.7 KB · Đọc: 67
Lần chỉnh sửa cuối:
Em cũng đang nghiên cứu giải pháp xu lý dữ liệu cho nhanh ma chưa có hướng xử lý lý đây
 
Tôi cũng mới ngâm cứu học hỏi VBA của excel nên cũng chưa rành lắm. Có một thắc mắc là phần lớn tôi thấy mọi người dùng mảng nhiều hơn là dùng đối tượng Recordset trong excel. Mảng xử lý nhanh hơn, linh động hơn trong ứng dụng Excel?
 
Tôi cũng mới ngâm cứu học hỏi VBA của excel nên cũng chưa rành lắm. Có một thắc mắc là phần lớn tôi thấy mọi người dùng mảng nhiều hơn là dùng đối tượng Recordset trong excel. Mảng xử lý nhanh hơn, linh động hơn trong ứng dụng Excel?
Theo mình nghĩ chắc mãng linh động dễ hình dung, dễ khai báo, dễ gán dữ liệu, có thể dễ xử lý hơn Recordset
 
Tôi cũng mới ngâm cứu học hỏi VBA của excel nên cũng chưa rành lắm. Có một thắc mắc là phần lớn tôi thấy mọi người dùng mảng nhiều hơn là dùng đối tượng Recordset trong excel. Mảng xử lý nhanh hơn, linh động hơn trong ứng dụng Excel?

Tùy vào tính huống mà ta lựa chọn khi nào dùng SQL, khi nào dùng Array. Ví dụ bạn muốn tạo công thức cho phép người dùng đặt điều kiện lọc tùy ý trên một mảng thì dùng như bài #1 topic này sẽ dễ dàng hơn. Nếu bạn có thể viết lọc trơn trên VBA nhưng (không dùng chức năng Advanced Filter) thì bạn phải có giải thuật rất tốt mới cho phép người sử dụng tùy biến đặt điều kiện. Nếu bạn cần dùng truy vấn chuẩn CSDL, các bảng quan hệ vào nhau, gộp dữ liệu với các hàm, đặt điều kiện với các hàm thống kê thì phải dùng SQL. Vấn đề nữa là file data nguồn nằm ở máy tính trong mạng thì cũng cần phải dùng SQL, vì dùng Array luôn phải mở file Excel nguồn,...
 
1/ Mạnh nghỉ trên cùng 1 File xài mảng đi cho gọn và nhanh ... trừ khi lấy dữ liệu từ 1 file đóng

2/ Mà xài ADO trong trường hợp này dễ gì nhanh hơn cái Mảng trên Sheet ?????????????

Mảng chỉ là... mảng, một cấu trúc căn bản.
Để mảng có thể làm những việc khác, ngừoi ta lồng nó vào các hình thức khác, điển hình là ArrayList trong dot net. Với ArrayList, ta có thể sort.

Ở đây, adodb.recordset được dùng như là một dạng Table (table của Excel, không phải Access)
Trong thớt này, tác giả giới thiệu cách lợi dụng hai thủ tục của ado recordset để filter và sort.
Muốn làm được việc này, code sử dụng array căn bản phải gọi hai hàm nào đó. Nếu hàm chưa có sẵn trong thư viện, bạn phải import chúng.

Cách của HLMT trình bày trên là đẩy mảng dữ liệu từ sheet vào recodset, từ đây dùng Filter - lọc. Nếu bài toán của người dùng là trích lọc dữ liệu trên sheet thì hoàn toàn ok. Tuy nhiên đây không phải SQL nên sẽ gặp phải các cấn đề sau:
- Mất thời gian lưu array vào recordset ban đầu. Mảng data có thể lấy từ sheet, còn lấy từ csdl khác như Access thì nên lấy bằng SQL luôn chứ không dùng Array vì sẽ mất hai lần làm không cần thiết (câu hỏi của a Hoàng Trọng Nghĩa)
- Chỉ áp dụng cho bài toán Filter trên data nguồn đưa vào dạng đơn lẻ không quan hệ. Vì không phải cách SQL nên không thực hiện được việc ORDER BY, GROUP BY, HAVING, các kết nối bảng với INNER JOIN, LEFT JOIN,...

Như vậy bài toán trên nên dùng trong phạm vi dữ liệu nguồn là Excel, một bảng nguồn không quan hệ. Bài toán gọi là lọc dữ liệu trong mảng.

ADODB chỉ là một API. Không thể so sánh với SQL là một ngôn ngữ tiêu chuẩn, truy vấn qua bộ máy của CSDL (Access, SQL Server, vv...)

@Thớt:
Nếu tôi nhớ không lầm thì có thể đưa dữ liệu vào recordset bằng cách ngắn hơn như sau:
'Dua du lieu nguon tu mang da set vao Recordset
Dim fArray
fArray = Array("ID", "MatID", "Balance") ' hoặc Array(0, 1, 2)
For i = LBound(vArray) To UBound(vArray)
.AddNew fArray, Array(vArray(i, 1), vArray(i, 2), vArray(i,4))
Next
.Update
 
ADODB chỉ là một API. Không thể so sánh với SQL là một ngôn ngữ tiêu chuẩn, truy vấn qua bộ máy của CSDL (Access, SQL Server, vv...)
Kiến thức Array và SQL thì em không lạ gì mà anh. Trên là em chỉ ra tùy vào tình huống để sử dụng thôi.
 
Cũng xin góp vui với đề tài này. :)
Tôi demo một cách dùng khác của Recordset nhưng có tạo Connection.
Theo cách của anh HLMT là tạo một table ảo (ADO recordset) trên bộ nhớ và xử lý Filter, Sort. Cách này theo tôi có một điểm yếu đó là nó sẽ tải toàn bộ dữ liệu lên Recordset (10.000 dòng trong ví dụ này). Điều này sẽ ảnh hưởng đến bộ nhớ rõ rệt nếu số lượng record lên hàng triệu.
Cách của tôi đang làm thì do không rành về mảng nên chỉ thuần tuý dùng Recordset và name range của Excel để gán dữ liệu vào recordset. Dữ liệu được chọn lọc trước khi ghi lên Recordset nên về mặt bộ nhớ sẽ giảm áp lực hơn.
Các bạn tham khảo góp ý nhé.

- Cách làm này phải tốn thêm một bước là tạo cái Name range và cập nhật nó mỗi khi có thay đổi thêm số dòng vào dữ liệu.
- Tôi có viết cái hàm để cập nhật lại name range.

Mã:
Option Explicit

Function createDynamicNamedRange() As Boolean
'--------------------------------------------------------------------------------------
'# Áp dung khi da xac dinh so cot cua range, hàm chi cap nhat dong cho so dòng cua range
'--------------------------------------------------------------------------------------

    Dim sht                     As Worksheet
    Dim lngFirstRowRng          As Long
    Dim lngLastRowRng           As Long
    Dim lngFirstColRng          As Long
    Dim lngLastColRng           As Long
    Dim myDynamicNamedRange     As Range
    Dim sRngName                As String

    Set sht = ThisWorkbook.Worksheets("Sheet1")

    'Khai bao dòng/côt dau tiên cua Range
    lngFirstRowRng = 1
    lngFirstColRng = 1

    'dat ten Name range tuy ý
    sRngName = "TonKhoVT"

    With sht.Cells
        lngLastRowRng = sht.Cells(Rows.Count, "D").End(xlUp).Row
        lngLastColRng = .Find(What:="*", LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
        Set myDynamicNamedRange = .Range(.Cells(lngFirstRowRng, lngFirstColRng), .Cells(lngLastRowRng, lngLastColRng))
    End With

    ThisWorkbook.Names.Add Name:=sRngName, RefersTo:=myDynamicNamedRange

End Function


- Code cho Sub lọc dữ liệu:

Mã:
Sub LocRst()
On Error GoTo LocRst_Err
    Dim oCnn As Object
    Dim oRst As Object
    Dim sRngName As String, fileExcel As String
    Dim s, s1, s2, s3 As String     'Chuoi dieu kien loc
    Dim thoigian As Long

    Const adOpenStatic = 3
    Const adLockOptimistic = 3
    Const adCmdText = &H1

    Set oCnn = CreateObject("ADODB.Connection")
    Set oRst = CreateObject("ADODB.Recordset")

    thoigian = Timer()

    fileExcel = ThisWorkbook.FullName
    With oCnn
        Select Case CLng(Application.Version)
        Case 11   'Excel 2003
            .Provider = "Microsoft.Jet.OLEDB.4.0"
            .ConnectionString = "Data Source=" & fileExcel & ";" & _
                                "Extended Properties=""Excel 8.0;HDR=Yes;"";"
        Case Is >= 12    'Excel 2007 tro lên"
            .Provider = "Microsoft.ACE.OLEDB.12.0"
            .ConnectionString = "Data Source=" & fileExcel & ";" & _
                                "Extended Properties=""Excel 12.0 Xml;HDR=Yes;"";"
        End Select
        .Open
    End With

    sRngName = "TonKhoVT"

    'Tong hop dieu kien loc
    s = "SELECT * FROM [" & sRngName & "] WHERE 1=1"
    s1 = " AND [" & Sheet3.Range("A1") & "]" & Sheet3.Range("B1")                   'Balance
    s2 = " AND [" & Sheet3.Range("A2") & "] =" & Sheet3.Range("B2")                 'ID
    s3 = " AND [" & Sheet3.Range("A3") & "] ='" & Sheet3.Range("B3") & "'"    'Remark
    If Not IsEmpty(Sheet3.Range("B1")) Then
        s = s & s1
    End If
    If Not IsEmpty(Sheet3.Range("B2")) Then
        s = s & s2
    End If
    If Not IsEmpty(Sheet3.Range("B3")) Then
        s = s & s3
    End If
    s = s & " ORDER BY [ID]"
    'Debug.Print s

    oRst.Open s, oCnn, adOpenStatic, adLockOptimistic, adCmdText

    Sheet3.Range("A7:D11000").ClearContents    'Xoa vung du lieu
    Sheet3.Range("A7").CopyFromRecordset oRst   'Do du lieu tu Recordset da loc xuong sheet
    Sheet3.Range("A5") = "Tong so record tim thay: " & oRst.RecordCount
    MsgBox Timer - thoigian

LocRst_Exit:
    oRst.Close
    Set oRst = Nothing
    If Not oCnn Is Nothing Then
        oCnn.Close
        Set oCnn = Nothing
    End If
    Exit Sub

LocRst_Err:
    Select Case Err.Number
    Case -2147217900
        MsgBox "Sai dieu kien loc du lieu!" & vbNewLine & vbNewLine & Err.Description, vbCritical, "Thông báo"
        Exit Sub
    Case Else
        MsgBox "Loi: " & Err.Number & vbNewLine & "Noi dung loi: " & Err.Description, vbExclamation, "Thông báo"
        Exit Sub
End Select

End Sub
 

File đính kèm

  • LocDL_KhongMoKetNoi_LocDuyNhat(v1).xlsm
    225.8 KB · Đọc: 58
Lần chỉnh sửa cuối:
Mảng chỉ là... mảng, một cấu trúc căn bản.
Để mảng có thể làm những việc khác, ngừoi ta lồng nó vào các hình thức khác, điển hình là ArrayList trong dot net. Với ArrayList, ta có thể sort.

Ở đây, adodb.recordset được dùng như là một dạng Table (table của Excel, không phải Access)
Trong thớt này, tác giả giới thiệu cách lợi dụng hai thủ tục của ado recordset để filter và sort.
Muốn làm được việc này, code sử dụng array căn bản phải gọi hai hàm nào đó. Nếu hàm chưa có sẵn trong thư viện, bạn phải import chúng.



ADODB chỉ là một API. Không thể so sánh với SQL là một ngôn ngữ tiêu chuẩn, truy vấn qua bộ máy của CSDL (Access, SQL Server, vv...)

@Thớt:
Nếu tôi nhớ không lầm thì có thể đưa dữ liệu vào recordset bằng cách ngắn hơn như sau:
'Dua du lieu nguon tu mang da set vao Recordset
Dim fArray
fArray = Array("ID", "MatID", "Balance") ' hoặc Array(0, 1, 2)
For i = LBound(vArray) To UBound(vArray)
.AddNew fArray, Array(vArray(i, 1), vArray(i, 2), vArray(i,4))
Next
.Update
Vì chưa thấy có trên GPE nên em muốn giới thiệu cho anh em phát triển thêm đó anh. Càng chi tiết càng dễ hình dung, sau này anh em quen và hiểu rõ rồi thì tùy biến mà dùng anh.
Cũng xin góp vui với đề tài này. :)
Tôi demo một cách dùng khác của Recordset nhưng có tạo Connection.
Theo cách của anh HLMT là tạo một table ảo (ADO recordset) trên bộ nhớ và xử lý Filter, Sort. Cách này theo tôi có một điểm yếu đó là nó sẽ tải toàn bộ dữ liệu lên Recordset (10.000 dòng trong ví dụ này). Điều này sẽ ảnh hưởng đến bộ nhớ rõ rệt nếu số lượng record lên hàng triệu.
Cách của tôi đang làm thì do không rành về mảng nên chỉ thuần tuý dùng Recordset và name range của Excel để gán dữ liệu vào recordset. Dữ liệu được chọn lọc trước khi ghi lên Recordset nên về mặt bộ nhớ sẽ giảm áp lực hơn.
Các bạn tham khảo góp ý nhé.

- Cách làm này phải tốn thêm một bước là tạo cái Name range và cập nhật nó mỗi khi có thay đổi thêm số dòng vào dữ liệu.
- Tôi có viết cái hàm để cập nhật lại name range.

Mã:
Option Explicit

Function createDynamicNamedRange() As Boolean
'--------------------------------------------------------------------------------------
'# Áp dung khi da xac dinh so cot cua range, hàm chi cap nhat dong cho so dòng cua range
'--------------------------------------------------------------------------------------

    Dim sht                     As Worksheet
    Dim lngFirstRowRng          As Long
    Dim lngLastRowRng           As Long
    Dim lngFirstColRng          As Long
    Dim lngLastColRng           As Long
    Dim myDynamicNamedRange     As Range
    Dim sRngName                As String

    Set sht = ThisWorkbook.Worksheets("Sheet1")

    'Khai bao dòng/côt dau tiên cua Range
    lngFirstRowRng = 1
    lngFirstColRng = 1

    'dat ten Name range tuy ý
    sRngName = "TonKhoVT"

    With sht.Cells
        lngLastRowRng = sht.Cells(Rows.Count, "D").End(xlUp).Row
        lngLastColRng = .Find(What:="*", LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
        Set myDynamicNamedRange = .Range(.Cells(lngFirstRowRng, lngFirstColRng), .Cells(lngLastRowRng, lngLastColRng))
    End With

    ThisWorkbook.Names.Add Name:=sRngName, RefersTo:=myDynamicNamedRange

End Function


- Code cho Sub lọc dữ liệu:

Mã:
Sub LocRst()
On Error GoTo LocRst_Err
    Dim oCnn As Object
    Dim oRst As Object
    Dim sRngName As String, fileExcel As String
    Dim s, s1, s2, s3 As String     'Chuoi dieu kien loc
    Dim thoigian As Long

    Const adOpenStatic = 3
    Const adLockOptimistic = 3
    Const adCmdText = &H1

    Set oCnn = CreateObject("ADODB.Connection")
    Set oRst = CreateObject("ADODB.Recordset")

    thoigian = Timer()

    fileExcel = ThisWorkbook.FullName
    With oCnn
        Select Case CLng(Application.Version)
        Case 11   'Excel 2003
            .Provider = "Microsoft.Jet.OLEDB.4.0"
            .ConnectionString = "Data Source=" & fileExcel & ";" & _
                                "Extended Properties=""Excel 8.0;HDR=Yes;"";"
        Case Is >= 12    'Excel 2007 tro lên"
            .Provider = "Microsoft.ACE.OLEDB.12.0"
            .ConnectionString = "Data Source=" & fileExcel & ";" & _
                                "Extended Properties=""Excel 12.0 Xml;HDR=Yes;"";"
        End Select
        .Open
    End With

    sRngName = "TonKhoVT"

    'Tong hop dieu kien loc
    s = "SELECT * FROM [" & sRngName & "] WHERE 1=1"
    s1 = " AND [" & Sheet3.Range("A1") & "]" & Sheet3.Range("B1")                   'Balance
    s2 = " AND [" & Sheet3.Range("A2") & "] =" & Sheet3.Range("B2")                 'ID
    s3 = " AND [" & Sheet3.Range("A3") & "] ='" & Sheet3.Range("B3") & "'"    'Remark
    If Not IsEmpty(Sheet3.Range("B1")) Then
        s = s & s1
    End If
    If Not IsEmpty(Sheet3.Range("B2")) Then
        s = s & s2
    End If
    If Not IsEmpty(Sheet3.Range("B3")) Then
        s = s & s3
    End If
    s = s & " ORDER BY [ID]"
    'Debug.Print s

    oRst.Open s, oCnn, adOpenStatic, adLockOptimistic, adCmdText

    Sheet3.Range("A7:D11000").ClearContents    'Xoa vung du lieu
    Sheet3.Range("A7").CopyFromRecordset oRst   'Do du lieu tu Recordset da loc xuong sheet
    Sheet3.Range("A5") = "Tong so record tim thay: " & oRst.RecordCount
    MsgBox Timer - thoigian

LocRst_Exit:
    oRst.Close
    Set oRst = Nothing
    If Not oCnn Is Nothing Then
        oCnn.Close
        Set oCnn = Nothing
    End If
    Exit Sub

LocRst_Err:
    Select Case Err.Number
    Case -2147217900
        MsgBox "Sai dieu kien loc du lieu!" & vbNewLine & vbNewLine & Err.Description, vbCritical, "Thông báo"
        Exit Sub
    Case Else
        MsgBox "Loi: " & Err.Number & vbNewLine & "Noi dung loi: " & Err.Description, vbExclamation, "Thông báo"
        Exit Sub
End Select

End Sub
Cách của bạn tôi đã có đề cập trên diễn đàn này rồi. Như đề bài này thì tôi mở ra là dùng những phương pháp mà mình không mở kết nối đó bạn.

Tốc độ hàm của em chắc cũng không thua đâu
Bạn hãy thử với 1 triệu dòng xem sao nhé.
 
Vì chưa thấy có trên GPE nên em muốn giới thiệu cho anh em phát triển thêm đó anh. Càng chi tiết càng dễ hình dung, sau này anh em quen và hiểu rõ rồi thì tùy biến mà dùng anh.

Cách của bạn tôi đã có đề cập trên diễn đàn này rồi. Như đề bài này thì tôi mở ra là dùng những phương pháp mà mình không mở kết nối đó bạn.


Bạn hãy thử với 1 triệu dòng xem sao nhé.
Anh co cai file gởi lên di, em test thử với
 
Hichic em đang tạo 1.000.000 row test không mà máy còn chạy không muốn nổi sao mà Test đây
 
Hình như em thắng Tốc độ của anh chắc luôn rồi
Code trên Delphi à ???
Mạnh cảm giác thấy cũng code như nhau mà khi code trong Delphi thấy nó chạy có vẻ nhanh hơn hay sao ý ?

nhất là mấy Hàm khai báo sự kiện Viết COM cho Excel (từ ngữ dùng có thể sai ai đó thấy sai sửa lại cho chuẩn he ???!!!)
 
Code trên Delphi à ???
Mạnh cảm giác thấy cũng code như nhau mà khi code trong Delphi thấy nó chạy có vẻ nhanh hơn hay sao ý ?

nhất là mấy Hàm khai báo sự kiện Viết COM cho Excel (từ ngữ dùng có thể sai ai đó thấy sai sửa lại cho chuẩn he ???!!!)
Em cũng không rành vụ này. Code này trên delphi, còn có thể nâng cấp tốc độ lên nữa nhưng có thể ngoài kiến thức của em....
 
Bạn hãy thử với 1 triệu dòng xem sao nhé.

Khi thử với 1 triệu dòng thì tôi mới biết là cái Name Range khai báo với số dòng không được vượt quá 65.536 dòng. Khi tôi khai báo Name: =Sheet1!$A$1:$D$1000000 là Excel báo lỗi không tìm thấy name range ngay. Sau đó tôi phải đổi lại là: =Sheet1!$A:$D thì mới hết báo lỗi.


Hình như em thắng Tốc độ của anh chắc luôn rồi

Cái hàm của bạn xử lý nhanh thật. Cái cách tiếp cận mà Delphi dùng để thao tác, xử lý dữ liệu này là gì vậy bạn?
 
Lần chỉnh sửa cuối:
Cái hàm của bạn xử lý nhanh thật. Cái cách tiếp cận mà Delphi dùng để thao tác, xử lý dữ liệu này là gì vậy bạn?

Bạn theo dõi chuỗi bài biết của tôi về Delphi trên GPE và trên Youtube bạn sẽ. Học đc mức cơ bản.

Bộ bài giảng học lập trình Delphi cơ bản
 
Web KT
Back
Top Bottom