Kết nối dữ liệu bằng ADODB và xử lý dữ liệu trên mảng

Liên hệ QC

anhtuan2939

Thành viên hoạt động
Tham gia
5/7/16
Bài viết
165
Được thích
130
Xin chào các bạn.
Mình có 1 dòng code để lấy dữ liệu từ file Excel khác thông qua ADODB, sau khi lấy dữ liệu mình muốn xử lý luôn trên mảng rồi mới gán kết quả xuống Sheet, nhưng khi lấy được dữ liệu thông qua ADODB thì hình như mảng lấy được trên này bị đảo ngược hàng thành cột, cột thành hàng. Vậy cho mình hỏi có cách nào để đảo ngược lại mảng trên ADODB không ạ?

Mã:
Sub test()
    Dim cnn As Object, rst As Object
    Dim lsSQL As String, filename As String
    Dim sArr()
    
    filename = Sheet1.Range("B8").Value  'Duong dan va ten file
    
    Set cnn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")
    
    With cnn
        .Provider = "Microsoft.ACE.OLEDB.12.0"
        .ConnectionString = "Data Source=" & filename & ";" & _
                            "Extended Properties=""Excel 8.0;HDR=Yes;"";"
        .Open
    End With
    
    lsSQL = "SELECT * " & _
             "FROM [EXCEL 12.0;Database=" & filename & ";HDR=Yes].[KU-KU$A2:H800000] " & _
             "WHERE Tai_Khoan IS NOT NULL;"
            
    rst.Open lsSQL, cnn
    sArr = rst.GetRows
    
    rst.Close
    Set rst = Nothing
    cnn.Close
    Set cnn = Nothing
    
    'Code xu ly mang sArr
    
End Sub
 
Xin chào các bạn.
Mình có 1 dòng code để lấy dữ liệu từ file Excel khác thông qua ADODB, sau khi lấy dữ liệu mình muốn xử lý luôn trên mảng rồi mới gán kết quả xuống Sheet, nhưng khi lấy được dữ liệu thông qua ADODB thì hình như mảng lấy được trên này bị đảo ngược hàng thành cột, cột thành hàng. Vậy cho mình hỏi có cách nào để đảo ngược lại mảng trên ADODB không ạ?

Mã:
Sub test()
    Dim cnn As Object, rst As Object
    Dim lsSQL As String, filename As String
    Dim sArr()
   
    filename = Sheet1.Range("B8").Value  'Duong dan va ten file
   
    Set cnn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")
   
    With cnn
        .Provider = "Microsoft.ACE.OLEDB.12.0"
        .ConnectionString = "Data Source=" & filename & ";" & _
                            "Extended Properties=""Excel 8.0;HDR=Yes;"";"
        .Open
    End With
   
    lsSQL = "SELECT * " & _
             "FROM [EXCEL 12.0;Database=" & filename & ";HDR=Yes].[KU-KU$A2:H800000] " & _
             "WHERE Tai_Khoan IS NOT NULL;"
           
    rst.Open lsSQL, cnn
    sArr = rst.GetRows
   
    rst.Close
    Set rst = Nothing
    cnn.Close
    Set cnn = Nothing
   
    'Code xu ly mang sArr
   
End Sub
Bạn phải chuyển nó bằng hàm TRANSPOSE. Còn nếu dữ liệu lớn thì bạn phải viết hàm chuyển đổi. Hãy tìm trên diễn đàn này sẽ có cái bạn cần nhé.
 
Upvote 0
Upvote 0

File đính kèm

  • File Nguon.xlsb
    177.5 KB · Đọc: 13
  • File_chuyen_doi.xlsb
    23.5 KB · Đọc: 16
Upvote 0
Còn nếu dữ liệu lớn thì bạn phải viết hàm chuyển đổi. Hãy tìm trên diễn đàn này sẽ có cái bạn cần nhé.
Cám ơn thầy. Em dùng hàm của thầy viết chạy rất ok ạ. Thầy cho em hỏi mảng sau khi chuyển đổi thì khi duyệt phải duyệt từ 0 phải không ạ, bình thường em xét cột đầu tiên đều viết sArr(i,1) bây giờ phải lùi 1 giá trị thành sArr(i,0)?

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
 
Upvote 0
Dạ. Em có viết hàm TRANSPOSE nhưng nó vẫn thông báo lỗi.
sArr = Application.Transpose(rst.GetRows)
View attachment 249340

Dữ liệu của bạn có nhiều cột có giá trị NULL mà hàm Transpose của Excel không chấp nhận Array có giá trị NULL nên báo lỗi "Type mismatch".
Nếu bỏ giá trị NULL hoặc chuyển đổi các phần tử mảng thành kiểu Variant thì mới chạy. Do đó dùng các hàm chuyển đổi Array khác bên ngoài là OK.
 
Upvote 0
Vâng ạ. Thầy cho em hỏi "chuyển đổi các phần tử mảng thành kiểu Variant" là như thế nào ạ?

:) Tôi chưa làm thầy ai bao giờ, cứ xư hô bình thường thôi.
Cái hàm TranArrr() ở trên là đã chuyển các phần tử mảng thành Variant rồi đó nên code của bạn hoạt động không lỗi rồi đó.
Chủ yếu tôi giải thích thêm để bạn hiểu nguyên nhân thôi.
 
Upvote 0
:) Tôi chưa làm thầy ai bao giờ, cứ xư hô bình thường thôi.
Cái hàm TranArrr() ở trên là đã chuyển các phần tử mảng thành Variant rồi đó nên code của bạn hoạt động không lỗi rồi đó.
Chủ yếu tôi giải thích thêm để bạn hiểu nguyên nhân thôi.
Vâng ạ. 1 chữ cũng là thầy, nửa chữ cũng là thầy. :)
 
Upvote 0
Cám ơn thầy. Em dùng hàm của thầy viết chạy rất ok ạ. Thầy cho em hỏi mảng sau khi chuyển đổi thì khi duyệt phải duyệt từ 0 phải không ạ, bình thường em xét cột đầu tiên đều viết sArr(i,1) bây giờ phải lùi 1 giá trị thành sArr(i,0)?

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
Đúng rồi bạn, theo mặc định là duyệt mảng từ 0 nhé.
 
Upvote 0
Cám ơn thầy. Em dùng hàm của thầy viết chạy rất ok ạ. Thầy cho em hỏi mảng sau khi chuyển đổi thì khi duyệt phải duyệt từ 0 phải không ạ, bình thường em xét cột đầu tiên đều viết sArr(i,1) bây giờ phải lùi 1 giá trị thành sArr(i,0)?

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

Mình làm như vậy không sợ gì nữa ráo... (cám ơn anh Kiều Mạnh nha...)

Mã:
Function TransposeArray2D(arr2D As Variant) As Variant
Dim X As Long, Y As Long
Dim arrTemp As Variant
    ReDim arrTemp(LBound(arr2D, 2) To UBound(arr2D, 2) - LBound(arr2D, 2) + 1, LBound(arr2D, 1) To UBound(arr2D, 1) - LBound(arr2D, 1) + 1)
    For X = LBound(arr2D, 2) To UBound(arr2D, 2)
        For Y = LBound(arr2D, 1) To UBound(arr2D, 1)
            arrTemp(X, Y) = arr2D(Y, X)
        Next Y
    Next X
    TransposeArray2D = arrTemp
End Function
 
Upvote 0
ReDim arrTemp(LBound(arr2D, 2) To UBound(arr2D, 2) - LBound(arr2D, 2) + 1, LBound(arr2D, 1) To UBound(arr2D, 1) - LBound(arr2D, 1) + 1)
Không đúng rồi.

ReDim arrTemp(LBound(arr2D, 2) To UBound(arr2D, 2) - LBound(arr2D, 2) + 1, LBound(arr2D, 1) To UBound(arr2D, 1) - LBound(arr2D, 1) + 1)

arr2D (2 To 5, 3 To 10)
=> arrTemp(3 To 10-3+1=8, 2 To 5-2+1=4)

arr2D (0 To 5, 0 To 10)
=> arrTemp(0 To 10-0+1=11, 0 To 5-0+1=6)
 
Upvote 0
Lấy nó vào Array= rst.GetRows duyệt tới đâu chuyển tới đó hay tính toán tới đó ===> bỏ được 2 dòng For khi xài hàm chuyển mảng ==> tốc độ nhanh hơn chút khi xài thêm Hàm chuyển mảng xong + tính toán lằng nhằng
 
Upvote 0
Lấy nó vào Array= rst.GetRows duyệt tới đâu chuyển tới đó hay tính toán tới đó ===> bỏ được 2 dòng For khi xài hàm chuyển mảng ==> tốc độ nhanh hơn chút khi xài thêm Hàm chuyển mảng xong + tính toán lằng nhằng
Nếu không chuyển mảng thì khi ghi kết quả xuống sheet thì nó sẽ ra như thế nào. Bạn giới thiệu cách không dùng hàm chuyển mảng nhé.
 
Upvote 0
Nếu không chuyển mảng thì khi ghi kết quả xuống sheet thì nó sẽ ra như thế nào. Bạn giới thiệu cách không dùng hàm chuyển mảng nhé.
Nếu không xài chuyển mảng thì nó ra như hình sau nhé ... cột còn rất nhiều đấy :

1607414669973.png

Còn nếu xài chuyển mảng thì nó ra như sau

1607414768419.png

vậy thôi cho các bạn mới học code hình dung nó ra như thế nào ???

nên khi lấy vào Arr từ ADODB tới đâu tính toán tới đó sẻ nhanh hơn lấy qua hàm chuyển mảng xong lại tính toán tiếp
nếu không cần thiết thì CopyFromRecordset Rst đi cho nó lẹ
 
Upvote 0
Nếu không xài chuyển mảng thì nó ra như hình sau nhé ... cột còn rất nhiều đấy :

View attachment 250814

Còn nếu xài chuyển mảng thì nó ra như sau

View attachment 250818

vậy thôi cho các bạn mới học code hình dung nó ra như thế nào ???

nên khi lấy vào Arr từ ADODB tới đâu tính toán tới đó sẻ nhanh hơn lấy qua hàm chuyển mảng xong lại tính toán tiếp
nếu không cần thiết thì CopyFromRecordset Rst đi cho nó lẹ
Nếu vậy ta không nên phát biểu câu trên để cho người mới đở phải phân vân.
 
Upvote 0
Web KT

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

Back
Top Bottom