Tổng hợp dữ liệu từ file đang đóng và ghép dữ liệu theo cột

Liên hệ QC

kokano90

Thành viên hoạt động
Tham gia
10/8/19
Bài viết
117
Được thích
25
Chào các thầy cô ạ
Hiện tại em đang muốn ghép dữ liệu từ những file đang đóng
Kết quả mong muốn như hình
1592054533225.png
em có sử dụng và chắp vá code của thầy@HieuCD tại topic này nhưng không thành.

Hiện giờ em chỉ có ý tưởng là:
Kích chọn những file đang đóng.
Sau đó tạo ra mảng dữ liệu từ những file đang đóng ấy.
Em có viết thử đoạn này rồi chạy thư nhưng bị lỗi ngay từ đoạn này
Mã:
Sub XYZ()
    Dim sArr(), Arr(), Res(), sh
    Dim Dic As Object, iKey$
    Dim k&, iR&, n&, i&, j&, sRow&, sCol&, jC&
sFile = Application.GetOpenFilename(FileFilter:="Excel Files (*.xls*),*.xlsx", _
                                        Title:="Select File", MultiSelect:=True)
  If VarType(sFile) = vbBoolean Then MsgBox ("Chua chon File du lieu"): Exit Sub
  Set cn = CreateObject("adodb.connection")
  For Each oFile In sFile
    If Val(Application.Version) < 12 Then
      cn.Open ("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & oFile & ";Extended Properties=""Excel 8.0;HDR=No"";")
    Else
      cn.Open ("provider=Microsoft.ACE.OLEDB.12.0;data source=" & oFile & ";mode=Read;extended properties=""Excel 12.0;hdr=no"";")
    End If
    Set rs = cn.Execute("select * from [Data$B4:AAA65000] where f2 is not null")
    If Not rs.EOF() Then
      sArr = rs.GetRows
End If
Sau đó lọc duy nhất theo Mã và trả lần lượt dữ liệu vào các dòng tương ứng với Mã
Mong các thầy cô chỉ giúp làm thế nào để em tạo được mảng dữ liệu.
Chẳng hạn em chọn 2 file thì sẽ tạo được 2 mảng sArr.
Dữ liệu các file con có thể nhiều hơn cả về số dòng và cột
Em cám ơn nhiều ạ
 

File đính kèm

  • Bang 2.xlsb
    11.6 KB · Đọc: 19
  • GhepDL.xlsm
    20.2 KB · Đọc: 8
  • Bang 3.xlsx
    9.7 KB · Đọc: 17
  • Bang tinh 1.xlsx
    10.3 KB · Đọc: 16
Chào các thầy cô ạ
Hiện tại em đang muốn ghép dữ liệu từ những file đang đóng
Kết quả mong muốn như hình
View attachment 239236
em có sử dụng và chắp vá code của thầy@HieuCD tại topic này nhưng không thành.

Hiện giờ em chỉ có ý tưởng là:
Kích chọn những file đang đóng.
Sau đó tạo ra mảng dữ liệu từ những file đang đóng ấy.
Em có viết thử đoạn này rồi chạy thư nhưng bị lỗi ngay từ đoạn này
Mã:
Sub XYZ()
    Dim sArr(), Arr(), Res(), sh
    Dim Dic As Object, iKey$
    Dim k&, iR&, n&, i&, j&, sRow&, sCol&, jC&
sFile = Application.GetOpenFilename(FileFilter:="Excel Files (*.xls*),*.xlsx", _
                                        Title:="Select File", MultiSelect:=True)
  If VarType(sFile) = vbBoolean Then MsgBox ("Chua chon File du lieu"): Exit Sub
  Set cn = CreateObject("adodb.connection")
  For Each oFile In sFile
    If Val(Application.Version) < 12 Then
      cn.Open ("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & oFile & ";Extended Properties=""Excel 8.0;HDR=No"";")
    Else
      cn.Open ("provider=Microsoft.ACE.OLEDB.12.0;data source=" & oFile & ";mode=Read;extended properties=""Excel 12.0;hdr=no"";")
    End If
    Set rs = cn.Execute("select * from [Data$B4:AAA65000] where f2 is not null")
    If Not rs.EOF() Then
      sArr = rs.GetRows
End If
Sau đó lọc duy nhất theo Mã và trả lần lượt dữ liệu vào các dòng tương ứng với Mã
Mong các thầy cô chỉ giúp làm thế nào để em tạo được mảng dữ liệu.
Chẳng hạn em chọn 2 file thì sẽ tạo được 2 mảng sArr.
Dữ liệu các file con có thể nhiều hơn cả về số dòng và cột
Em cám ơn nhiều ạ
Mã:
....
  For Each oFile In sFile
    cn.Open ("provider=Microsoft.ACE.OLEDB.12.0;data source=" & oFile & ";mode=Read;extended properties=""Excel 12.0;hdr=no"";")
    Set rs = cn.Execute("select * from [Data$B4:E65000] where f1 is not null")
    If Not rs.EOF() Then
      sArr = rs.GetRows
      'Xu ly tiep ...
      '...
    End If
    rs.Close: cn.Close
  Next
  Set rs = Nothing: cn = Nothing
  ...
 
Upvote 0
@HieuCD cám ơn thầy ạ. Trong đoạn code thầy ghi chú xử lý tiếp ấy. Tại em đọc topic trước thầy hỗ trợ. Sẽ đưa dư liệu thành mảng sArr(0), sArr(1). Còn thấy thầy ...xử lý tiếp trong vòng lặp thế làm em bỡ ngỡ. Trong modul em có chắp vá. Nhưng không rõ sử dụng dic thế nào. Thầy có thể coi giúp em phải xử lý thế nào không ạ
 
Upvote 0
@HieuCD cám ơn thầy ạ. Trong đoạn code thầy ghi chú xử lý tiếp ấy. Tại em đọc topic trước thầy hỗ trợ. Sẽ đưa dư liệu thành mảng sArr(0), sArr(1). Còn thấy thầy ...xử lý tiếp trong vòng lặp thế làm em bỡ ngỡ. Trong modul em có chắp vá. Nhưng không rõ sử dụng dic thế nào. Thầy có thể coi giúp em phải xử lý thế nào không ạ
Kết quả chuẩn như thế nào?
 
Upvote 0
Kết quả chuẩn như thế nào?
Kết quả chuẩn như hình và trong file thầy ạ
Mục đích là em muốn lọc ra mã duy nhất trong tất cả các file con được chọn gán vào 1 cột. Sau đó dữ liệu còn lại của các file con. Sẽ được dò với mã. Gán vào các cột tiếp tuơng ứng với dòng và có mã đó như toppic bữa trước thầy giúp ạ. Nhưng gà mờ quá. Em không làm được.
Mong thầy và mọi người giúp đỡ
 
Lần chỉnh sửa cuối:
Upvote 0
Kết quả chuẩn như hình và trong file thầy ạ
Mục đích là em muốn lọc ra mã duy nhất trong tất cả các file con được chọn gán vào 1 cột. Sau đó dữ liệu còn lại của các file con. Sẽ được dò với mã. Gán vào các cột tiếp tuơng ứng với dòng và có mã đó như toppic bữa trước thầy giúp ạ. Nhưng gà mờ quá. Em không làm được.
Mong thầy và mọi người giúp đỡ
Tự viết phần cuối
Mã:
Sub XYZ()
  Dim sArr(), Arr, aMa(), Res()
  Dim Dic As Object, iKey$
  Dim k&, iR&, n&, i&, j&, sRow&, sCol&, jC&

  Set Dic = CreateObject("scripting.dictionary")
  Dic.CompareMode = vbTextCompare
 
  sFile = Application.GetOpenFilename(FileFilter:="Excel Files (*.xls*),*.xlsx", _
                                        Title:="Select File", MultiSelect:=True)
  If VarType(sFile) = vbBoolean Then MsgBox ("Chua chon File du lieu"): Exit Sub
  ReDim sArr(0 To 1, 1 To UBound(sFile))
  Set cn = CreateObject("adodb.connection")
  sRow = 1: sCol = 1
  For Each ofile In sFile
    cn.Open ("provider=Microsoft.ACE.OLEDB.12.0;data source=" & ofile & ";mode=Read;extended properties=""Excel 12.0;hdr=no"";")
    Set rs = cn.Execute("select * from [Data$B3:E65000] where f1 is not null")
    If Not rs.EOF() Then
      n = n + 1
      Arr = Split(ofile, "\")
      sArr(0, n) = Arr(UBound(Arr)) 'Ten File
      sArr(1, n) = rs.GetRows 'Du lieu file, dòng và cot dao nguoc voi Range
      sRow = sRow + UBound(sArr(1, n), 2) + 1
      sCol = sCol + UBound(sArr(1, n), 1)
    End If
    rs.Close: cn.Close
  Next
  Set rs = Nothing: Set cn = Nothing
  ReDim Res(1 To sRow, 1 To sCol)
  'Tu viet tiep
  '...
End Sub
 
Upvote 0
Tự viết phần cuối
Mã:
Sub XYZ()
  Dim sArr(), Arr, aMa(), Res()
  Dim Dic As Object, iKey$
  Dim k&, iR&, n&, i&, j&, sRow&, sCol&, jC&

  Set Dic = CreateObject("scripting.dictionary")
  Dic.CompareMode = vbTextCompare
 
  sFile = Application.GetOpenFilename(FileFilter:="Excel Files (*.xls*),*.xlsx", _
                                        Title:="Select File", MultiSelect:=True)
  If VarType(sFile) = vbBoolean Then MsgBox ("Chua chon File du lieu"): Exit Sub
  ReDim sArr(0 To 1, 1 To UBound(sFile))
  Set cn = CreateObject("adodb.connection")
  sRow = 1: sCol = 1
  For Each ofile In sFile
    cn.Open ("provider=Microsoft.ACE.OLEDB.12.0;data source=" & ofile & ";mode=Read;extended properties=""Excel 12.0;hdr=no"";")
    Set rs = cn.Execute("select * from [Data$B3:E65000] where f1 is not null")
    If Not rs.EOF() Then
      n = n + 1
      Arr = Split(ofile, "\")
      sArr(0, n) = Arr(UBound(Arr)) 'Ten File
      sArr(1, n) = rs.GetRows 'Du lieu file, dòng và cot dao nguoc voi Range
      sRow = sRow + UBound(sArr(1, n), 2) + 1
      sCol = sCol + UBound(sArr(1, n), 1)
    End If
    rs.Close: cn.Close
  Next
  Set rs = Nothing: Set cn = Nothing
  ReDim Res(1 To sRow, 1 To sCol)
  'Tu viet tiep
  '...
End Sub
Cám ơn thầy. Phần còn lại em sẽ làm nốt. Khúc mắc chỗ nào. Em sẽ hỏi lại. Mong các thầy cô giúp đỡ. Em cám ơn
 
Upvote 0
1592129505254.png
Thầy @HieuCD cho em hỏi chút ạ. Em tạo tiêu đề. khi vào xem Local. Thấy dữ liệu lấy bằng ADO thấy cột tiền khi lấy dữ liệu. Tiêu đề của nó lại bằng Null thế kia ạ? Cái này có ảnh hưởng gì không ạ?
Ngồi mò mẫm theo code của bài trước. Mà thấy mảng dữ liệu đầu vào của bài này nó ngược so với bài kia sao ấy.( Thấy thầy cũng comment) thành ra cứ báo lỗi mà mãi mới hiểu
 
Upvote 0
Cám ơn thầy. Phần còn lại em sẽ làm nốt. Khúc mắc chỗ nào. Em sẽ hỏi lại. Mong các thầy cô giúp đỡ. Em cám ơn
View attachment 239262
Thầy @HieuCD cho em hỏi chút ạ. Em tạo tiêu đề. khi vào xem Local. Thấy dữ liệu lấy bằng ADO thấy cột tiền khi lấy dữ liệu. Tiêu đề của nó lại bằng Null thế kia ạ? Cái này có ảnh hưởng gì không ạ?
Ngồi mò mẫm theo code của bài trước. Mà thấy mảng dữ liệu đầu vào của bài này nó ngược so với bài kia sao ấy.( Thấy thầy cũng comment) thành ra cứ báo lỗi mà mãi mới hiểu
Do dạng dữ liệu tiêu đề cột khác với dạng dữ liệu các dòng dưới
Code mới tách tiêu đề thành mảng riêng
Mã:
Sub XYZ()
  Dim sArr(), aMa(), Res(), aTmp, Arr
  Dim Dic As Object, iKey$, strRng$
  Dim k&, iR&, n&, i&, j&, sRow&, sCol&, jC&

  Set Dic = CreateObject("scripting.dictionary")
  Dic.CompareMode = vbTextCompare
 
  sFile = Application.GetOpenFilename(FileFilter:="Excel Files (*.xls*),*.xlsx", _
                                        Title:="Select File", MultiSelect:=True)
  If VarType(sFile) = vbBoolean Then MsgBox ("Chua chon File du lieu"): Exit Sub
  ReDim sArr(0 To 2, 1 To UBound(sFile))
  Set cn = CreateObject("adodb.connection")
  sRow = 2: sCol = 1
  For Each ofile In sFile
    cn.Open ("provider=Microsoft.ACE.OLEDB.12.0;data source=" & ofile & ";mode=Read;extended properties=""Excel 12.0;hdr=no"";")
    Set rs = cn.Execute("select * from [Data$B3:AAA3] ")
    If Not rs.EOF() Then
      n = n + 1
      Arr = Split(ofile, "\")
      sArr(0, n) = Arr(UBound(Arr)) 'Ten File
      
      aTmp = rs.GetRows 'Mang tam, Tieu de cot
      strRng = Empty
      For i = UBound(aTmp) To 0 Step -1
        If strRng = Empty Then
          If aTmp(i, 0) <> Empty Then
            strRng = "[Data$B4:" & Cells(65000, i + 2).Address(0, 0) & "]"
            ReDim Arr(0 To i, 0 To 0)
          End If
        End If
        If strRng <> Empty Then
          Arr(i, 0) = aTmp(i, 0)
        End If
      Next i
      sArr(1, n) = Arr 'Tieu de cot
      sCol = sCol + UBound(Arr)
      rs.Close
      
      Set rs = cn.Execute("select * from " & strRng & " where f1 is not null")
      sArr(2, n) = rs.GetRows 'Du lieu file, dòng và cot dao nguoc voi Range
      sRow = sRow + UBound(sArr(2, n), 2) + 1
    End If
    rs.Close: cn.Close
  Next
  Set rs = Nothing: Set cn = Nothing
  ReDim Res(1 To sRow, 1 To sCol)
  'Tu viet tiep
  '...
End Sub
 
Upvote 0
Do dạng dữ liệu tiêu đề cột khác với dạng dữ liệu các dòng dưới
Code mới tách tiêu đề thành mảng riêng
Cám ơn thầy. Để em mò tiếp. Lấy dữ liệu bằng bằng ADO này sao mảng trong đấy rắc rối quá. Em cứ loạn hết cả lên.
Có gì không hiểu em sẽ hỏi thầy thêm được không ạ
 
Upvote 0
Cám ơn thầy. Để em mò tiếp. Lấy dữ liệu bằng bằng ADO này sao mảng trong đấy rắc rối quá. Em cứ loạn hết cả lên.
Có gì không hiểu em sẽ hỏi thầy thêm được không ạ
Tự bạn chưa quen, nên nhìn ADO + mảng "loạn hết cả lên" là đúng rồi, thực hành riết rồi cũng quen thôi
1/ duyệt qua các file trong thư mục
2/ Connect bằng ADO
3/ đưa record vào Array
 
Upvote 0
Tự bạn chưa quen, nên nhìn ADO + mảng "loạn hết cả lên" là đúng rồi, thực hành riết rồi cũng quen thôi
1/ duyệt qua các file trong thư mục
2/ Connect bằng ADO
3/ đưa record vào Array
Cám ơn anh hướng dẫn. Hihi. đang quen mảng là mảng kiểu bình thường. Giờ thấy mảng kiểu Arr(1,1)(1).....
Làm em không biết phải for next thế nào. Hỏi nhiều thì em sợ. Mà không hỏi thì không hiểu. Nhưng thực lòng em vẫn muốn hỏi.
 
Upvote 0
Gửi thầy @HieuCD. Phiền thầy giúp em được không ạ?
Càng ngồi mò càng thấy rối. Rõ ràng là nhìn bài bên kia thấy mảng nó ổn. Vậy mà sang đến bài bên này thấy mảng thầy tạo cho ban đầu càng nhìn càng rối. Ngồi cả ngày mà quanh quẩn cái tiêu đề vãn chưa làm được.Thực sự em không biết nên for next ở chỗ nào. Trong khi bài này thì vận dụng được.
Em cám ơn nhiều
 

File đính kèm

  • GhepDuLieu.xlsm
    27.5 KB · Đọc: 8
Upvote 0
Chào các thầy cô ạ
Hiện tại em đang muốn ghép dữ liệu từ những file đang đóng
Kết quả mong muốn như hình
View attachment 239236
em có sử dụng và chắp vá code của thầy@HieuCD tại topic này nhưng không thành.

Hiện giờ em chỉ có ý tưởng là:
Kích chọn những file đang đóng.
Sau đó tạo ra mảng dữ liệu từ những file đang đóng ấy.
Em có viết thử đoạn này rồi chạy thư nhưng bị lỗi ngay từ đoạn này
Mã:
Sub XYZ()
    Dim sArr(), Arr(), Res(), sh
    Dim Dic As Object, iKey$
    Dim k&, iR&, n&, i&, j&, sRow&, sCol&, jC&
sFile = Application.GetOpenFilename(FileFilter:="Excel Files (*.xls*),*.xlsx", _
                                        Title:="Select File", MultiSelect:=True)
  If VarType(sFile) = vbBoolean Then MsgBox ("Chua chon File du lieu"): Exit Sub
  Set cn = CreateObject("adodb.connection")
  For Each oFile In sFile
    If Val(Application.Version) < 12 Then
      cn.Open ("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & oFile & ";Extended Properties=""Excel 8.0;HDR=No"";")
    Else
      cn.Open ("provider=Microsoft.ACE.OLEDB.12.0;data source=" & oFile & ";mode=Read;extended properties=""Excel 12.0;hdr=no"";")
    End If
    Set rs = cn.Execute("select * from [Data$B4:AAA65000] where f2 is not null")
    If Not rs.EOF() Then
      sArr = rs.GetRows
End If
Sau đó lọc duy nhất theo Mã và trả lần lượt dữ liệu vào các dòng tương ứng với Mã
Mong các thầy cô chỉ giúp làm thế nào để em tạo được mảng dữ liệu.
Chẳng hạn em chọn 2 file thì sẽ tạo được 2 mảng sArr.
Dữ liệu các file con có thể nhiều hơn cả về số dòng và cột
Em cám ơn nhiều ạ
Chạy code
Mã:
Sub XYZ()
  Dim sArr(), aMa(), Res(), aTmp, Arr
  Dim Dic As Object, iKey$, strRng$
  Dim k&, ik&, n&, i&, j&, sRow&, sCol&, jC&, dj&

  Set Dic = CreateObject("scripting.dictionary")
  Dic.CompareMode = vbTextCompare
 
  sFile = Application.GetOpenFilename(FileFilter:="Excel Files (*.xls*),*.xlsx", _
                                        Title:="Select File", MultiSelect:=True)
  If VarType(sFile) = vbBoolean Then MsgBox ("Chua chon File du lieu"): Exit Sub
  ReDim sArr(0 To 2, 1 To UBound(sFile))
  Set cn = CreateObject("adodb.connection")
  sRow = 2: sCol = 1
  For Each ofile In sFile
    cn.Open ("provider=Microsoft.ACE.OLEDB.12.0;data source=" & ofile & ";mode=Read;extended properties=""Excel 12.0;hdr=no"";")
    Set rs = cn.Execute("select * from [Data$B3:AAA3] ")
    If Not rs.EOF() Then
      n = n + 1
      Arr = Split(ofile, "\")
      sArr(0, n) = Arr(UBound(Arr)) 'Ten File
      
      aTmp = rs.GetRows 'Mang tam, Tieu de cot
      strRng = Empty
      For i = UBound(aTmp) To 0 Step -1
        If strRng = Empty Then
          If aTmp(i, 0) <> Empty Then
            strRng = "[Data$B4:" & Cells(65000, i + 2).Address(0, 0) & "]"
            ReDim Arr(0 To i, 0 To 0)
          End If
        End If
        If strRng <> Empty Then
          Arr(i, 0) = aTmp(i, 0)
        End If
      Next i
      sArr(1, n) = Arr 'Tieu de cot
      sCol = sCol + UBound(Arr)
      rs.Close
      
      Set rs = cn.Execute("select * from " & strRng & " where f1 is not null")
      sArr(2, n) = rs.GetRows 'Du lieu file, dòng và cot dao nguoc voi Range
      sRow = sRow + UBound(sArr(2, n), 2) + 1
    End If
    rs.Close: cn.Close
  Next
  Set rs = Nothing: Set cn = Nothing
 
  ReDim Res(1 To sRow, 1 To sCol)
  jC = 1: k = 2
  Res(k, jC) = sArr(1, 1)(0, 0) 'Tieu de "Ma"
 
  For r = 1 To n
    Res(1, jC + 1) = sArr(0, r) 'Ten File
    aTmp = sArr(1, r)
    Arr = sArr(2, r)
    dj = jC  'Chenh lech jc và j
    For j = 1 To UBound(aTmp)
      jC = jC + 1 'Cot ket qua
      Res(2, jC) = aTmp(j, 0) 'Tieu de cot
    Next j
    For i = 0 To UBound(Arr, 2) 'Dòng ket qua, cot mang Arr
      iKey = Arr(0, i)
      If Dic.exists(iKey) = False Then
        k = k + 1 'Dong ket qua
        Res(k, 1) = iKey
        Dic.Add iKey, k
      End If
      ik = Dic.Item(iKey)
      For j = 1 To UBound(Arr) 'Cot ket qua, dòng mang Arr
        Res(ik, j + dj) = Arr(j, i) 'Du lieu ket qua
      Next j
    Next i
  Next r
  With Sheets("Data_Ngang")
    .UsedRange.ClearContents
    If k > 2 Then .Range("B2").Resize(k, sCol) = Res
  End With
End Sub
 

File đính kèm

  • GhepDL.xlsm
    21 KB · Đọc: 24
Upvote 0
Giờ thấy mảng kiểu Arr(1,1)(1).....

Cái này là truy xuất phần tử Mãng trong Mãng

Ví dụ
Mã:
Sub TestArray()
    Dim a(), b()
        a = Range("A1:D10").Value
        a(1, 1) = Range("E1:K10").Value
            Debug.Print a(1, 1)(1, 2)
        
        b = Array(Array(1, 2, 3), Array(4, 5, 6))
        Debug.Print b(0)(0)
End Sub
b(0)(0) - Return là: 1
b(0)(1) - Return là: 2
b(0)(2) - Return là: 3

b(1)(0) - Return là: 4
b(1)(1) - Return là: 5
b(1)(2) - Return là: 6
 
Upvote 0
Web KT

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

Back
Top Bottom