Tổng Hợp N + 1 Files Trong Folder Không Sử Dụng ADO, DAO và Workbooks.Open

Liên hệ QC

Kiều Mạnh

I don't program, I beat code into submission!!!
Tham gia
9/6/12
Bài viết
5,421
Được thích
4,036
Giới tính
Nam
Xuất phát từ ý tưởng ở 2 thớt sau:

http://www.giaiphapexcel.com/forum/...iệu-từ-nhiều-file-khác-nhau-vào-file-tổng-hợp

http://www.giaiphapexcel.com/forum/...-excel-đang-đóng-bằng-ADO&p=719556#post719556

Mạnh lập thớt này để nghiên cứu học tập thêm và sau đó là trả bài cho Bạn doveandrose
sau một thời gian mạnh Theo doveandrose hoc code ....


I/ Như tiều đề của thớt này ta sẻ tổng hợp tất cả các Files trong Folder mà không xác định tên File, tổng số File có bao nhiêu trong Folder chơi hêt ....*.xls, *.xlsb,*.xlsx ....

1/ Tên Sheets("THA") là tên Sheet cần tổng hợp

2/ Vùng dữ liệu cần tổng hợp là [A14:M100]

3/ Lấy hết lên gán lên File tổng hợp nối tiếp xuống

II/ Xong câu I ta chuyển qua câu II

1/ vẫn như tiêu đề ta sẻ tổng hợp file có Pass Open lấy dữ liệu của 1 Files mà biết:

1/ Tên Sheets("THA") là tên Sheet cần tổng hợp

2/ Vùng dữ liệu cần tổng hợp là [A14:M100]

3/ Pass Open là: 1

4/ lấy hết lên gán lên File tổng hợp

Câu này có 2 cách : 1 là nhập pass = tay , 2 là cho pass vào code luôn....Ai thích kiểu nào ta chơi kiểu đó ...

Xin mời các Bạn có nhả hứng tham gia một tí cho vui ....sau đó Mạnh sẻ úp đáp án trả Bài cho Thầy doveandrose ....Vì đã nghiên cứ từ những thuất toán của thầy ....
--=0|||||--=0!$@!!

Files giả lập kèm theo

Sau đó nữa nếu nổi gió lên ta chơi tiếp các kiểu ..._+)(9 -.,\;

Xin cảm ơn
 

File đính kèm

  • TongHop.rar
    33.8 KB · Đọc: 60
Làm vầy cũng không vi phạm điều kiện. Nhưng dữ liệu lớn thì không ổn.
PHP:
Sub GetData()
Const ExcelExtension As String = "|xls|xlsb|xlsm|xlsx|"
Dim i As Long, sFolder As String, iFile As Object
With CreateObject("Scripting.FileSystemObject")
    sFolder = .GetParentFolderName(ThisWorkbook.FullName)
    For Each iFile In .GetFolder(sFolder).Files
        If InStr(ExcelExtension, "|" & .GetExtensionName(iFile.Path) & "|") > 0 Then
            If iFile.Path <> ThisWorkbook.FullName And Left(iFile.Name, 2) <> "~$" Then
                With Sheets(1).Cells(i * 87 + 1, 1).Resize(87, 13)
                    .FormulaArray = "='" & sFolder & "\[" & iFile.Name & "]THA'!A14:M100"
                    .Value = .Value
                End With
                i = i + 1
            End If
        End If
    Next
End With
End Sub
 
Upvote 0
Làm vầy cũng không vi phạm điều kiện. Nhưng dữ liệu lớn thì không ổn.
PHP:
Sub GetData()
Const ExcelExtension As String = "|xls|xlsb|xlsm|xlsx|"
Dim i As Long, sFolder As String, iFile As Object
With CreateObject("Scripting.FileSystemObject")
    sFolder = .GetParentFolderName(ThisWorkbook.FullName)
    For Each iFile In .GetFolder(sFolder).Files
        If InStr(ExcelExtension, "|" & .GetExtensionName(iFile.Path) & "|") > 0 Then
            If iFile.Path <> ThisWorkbook.FullName And Left(iFile.Name, 2) <> "~$" Then
                With Sheets(1).Cells(i * 87 + 1, 1).Resize(87, 13)
                    .FormulaArray = "='" & sFolder & "\[" & iFile.Name & "]THA'!A14:M100"
                    .Value = .Value
                End With
                i = i + 1
            End If
        End If
    Next
End With
End Sub
Đây là link file. Hi
Bác làm luôn câu 2 đi ạ. Để em học hỏi ạ.
 
Upvote 0
Làm vầy cũng không vi phạm điều kiện. Nhưng dữ liệu lớn thì không ổn.
PHP:
Sub GetData()
Const ExcelExtension As String = "|xls|xlsb|xlsm|xlsx|"
Dim i As Long, sFolder As String, iFile As Object
With CreateObject("Scripting.FileSystemObject")
    sFolder = .GetParentFolderName(ThisWorkbook.FullName)
    For Each iFile In .GetFolder(sFolder).Files
        If InStr(ExcelExtension, "|" & .GetExtensionName(iFile.Path) & "|") > 0 Then
            If iFile.Path <> ThisWorkbook.FullName And Left(iFile.Name, 2) <> "~$" Then
                With Sheets(1).Cells(i * 87 + 1, 1).Resize(87, 13)
                    .FormulaArray = "='" & sFolder & "\[" & iFile.Name & "]THA'!A14:M100"
                    .Value = .Value
                End With
                i = i + 1
            End If
        End If
    Next
End With
End Sub
sao mình chạy code nó không thấy nhúc nhíc là sao ta...
 
Upvote 0
sao mình chạy code nó không thấy nhúc nhíc là sao ta...

Tác giả thớt xem code trên gán dữ liệu vào sheets thứ mấy vậy...và file tổng hợp của tác giả thớt này có mấy sheets vậy nhỉ?....có cái sheet siêu ẩn ẩn ẩn...í--=0--=0--=0 Nhưng mà code trên vẫn chưa làm được cái bạn Kiều Mạnh mong muốn...
 
Upvote 0
Mình sửa lại code của bạn huuthang_bd ở #2 một chút xem có được không bác kieumanh. Mong cách khác của bác kieumanh.
Mã:
Sub GetData()
Const ExcelExtension As String = "|xls|xlsb|xlsm|xlsx|"
Dim i As Long, sFolder As String, iFile As Object
With CreateObject("Scripting.FileSystemObject")
    sFolder = .GetParentFolderName(ThisWorkbook.FullName)
    For Each iFile In .GetFolder(sFolder).Files
        If InStr(ExcelExtension, "|" & .GetExtensionName(iFile.Path) & "|") > 0 Then
            If iFile.Path <> ThisWorkbook.FullName And Left(iFile.Name, 2) <> "~$" Then
                With Sheet1.Range("A" & (i * 10 + 1) & ":M" & (i * 10 + 10))
                   .FormulaArray = "='" & sFolder & "\[" & iFile.Name & "]THA'!A4:M13"
                   .Value = .Value
                End With
                i = i + 1
            End If
        End If
    Next
End With
End Sub
 
Upvote 0
Mình sửa lại code của bạn huuthang_bd ở #2 một chút xem có được không bác kieumanh. Mong cách khác của bác kieumanh.
Mã:
Sub GetData()
Const ExcelExtension As String = "|xls|xlsb|xlsm|xlsx|"
Dim i As Long, sFolder As String, iFile As Object
With CreateObject("Scripting.FileSystemObject")
    sFolder = .GetParentFolderName(ThisWorkbook.FullName)
    For Each iFile In .GetFolder(sFolder).Files
        If InStr(ExcelExtension, "|" & .GetExtensionName(iFile.Path) & "|") > 0 Then
            If iFile.Path <> ThisWorkbook.FullName And Left(iFile.Name, 2) <> "~$" Then
                With Sheet1.Range("A" & (i * 10 + 1) & ":M" & (i * 10 + 10))
                   .FormulaArray = "='" & sFolder & "\[" & iFile.Name & "]THA'!A4:M13"
                   .Value = .Value
                End With
                i = i + 1
            End If
        End If
    Next
End With
End Sub

Lỡ như dữ liệu không liên tục & hàng cuối bất kỳ thì sao nhỉ? Sửa lại theo cái mà anh Kiều Mạnh nói học được từ thầy "Chim Hồng" nè...haha.........Kiều Mạnh mà không biết chiu này của anh "Chim Hồng" thì mình ...luôn
Mã:
Sub GetData()
Const ExcelExtension As String = "|xls|xlsb|xlsm|xlsx|"
Dim i As Long, sFolder As String, iFile As Object, FullPath As String
With CreateObject("Scripting.FileSystemObject")
    sFolder = .GetParentFolderName(ThisWorkbook.FullName)
    i = 4
    Sheets("TongHop").UsedRange.Clear
    For Each iFile In .GetFolder(sFolder).Files
        If InStr(ExcelExtension, "|" & .GetExtensionName(iFile.Path) & "|") > 0 Then
            If iFile.Path <> ThisWorkbook.FullName And Left(iFile.Name, 2) <> "~$" Then
            FullPath = "'" & sFolder & "\[" & iFile.Name & "]THA'!"
                With Sheets("TongHop")
                    .[A1] = "=IFERROR(LOOKUP(2,1/(" & FullPath & "A1:A10000<>""""),ROW(1:10000)),0)"
                    lr = .[A1]
                    If lr > 3 Then
                        .Range("A" & i).Resize(lr - 3, 13).FormulaArray = "=if(" & FullPath & _
                        "A4:M" & lr & "="""",""""," & FullPath & "A4:M" & lr & ")"
                        .Range("A" & i).Resize(lr - 3, 13).Value = .Range("A" & i).Resize(lr - 3, 13).Value
                        i = i + lr - 3
                    End If
                End With
            End If
        End If
    Next
    Sheets("TongHop").[A1].ClearContents
End With
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Lỡ như dữ liệu không liên tục & hàng cuối bất kỳ thì sao nhỉ? Sửa lại theo cái mà anh Kiều Mạnh nói học được từ thầy "Chim Hồng" nè...haha.........Kiều Mạnh mà không biết chiu này của anh "Chim Hồng" thì mình ...luôn
Mã:
Sub GetData()
Const ExcelExtension As String = "|xls|xlsb|xlsm|xlsx|"
Dim i As Long, sFolder As String, iFile As Object, FullPath As String
With CreateObject("Scripting.FileSystemObject")
    sFolder = .GetParentFolderName(ThisWorkbook.FullName)
    i = 4
    Sheets("TongHop").UsedRange.Clear
    For Each iFile In .GetFolder(sFolder).Files
        If InStr(ExcelExtension, "|" & .GetExtensionName(iFile.Path) & "|") > 0 Then
            If iFile.Path <> ThisWorkbook.FullName And Left(iFile.Name, 2) <> "~$" Then
            FullPath = "'" & sFolder & "\[" & iFile.Name & "]THA'!"
                With Sheets("TongHop")
                    .[A1] = "=IFERROR(LOOKUP(2,1/(" & FullPath & "A1:A10000<>""""),ROW(1:10000)),0)"
                    lr = .[A1]
                    If lr > 3 Then
                        .Range("A" & i).Resize(lr - 3, 13).FormulaArray = "=if(" & FullPath & _
                        "A4:M" & lr & "="""",""""," & FullPath & "A4:M" & lr & ")"
                        .Range("A" & i).Resize(lr - 3, 13).Value = .Range("A" & i).Resize(lr - 3, 13).Value
                        i = i + lr - 3
                    End If
                End With
            End If
        End If
    Next
    Sheets("TongHop").[A1].ClearContents
End With
End Sub
Cách này hay thật ... xài hàm tại [A1] nó sẻ khắc phục được số dòng rỗng khi lấy dữ liệu sẻ cho tốc độ nhanh
Tùy biến vùng gán dữ liệu ngay tren Sheet không phát sinh lỗi
Cảm ơn Bạn Mạnh hoc thêm 1 cái hay
 
Upvote 0
Cách này hay thật ... xài hàm tại [A1] nó sẻ khắc phục được số dòng rỗng khi lấy dữ liệu sẻ cho tốc độ nhanh
Tùy biến vùng gán dữ liệu ngay tren Sheet không phát sinh lỗi
Cảm ơn Bạn Mạnh hoc thêm 1 cái hay

Ủa. Tôi thấy yêu cầu là lấy dữ liệu vùng A14:M100 chứ có nói gì đến dòng trống đâu nhỉ?
 
Upvote 0
Còn đây là cách của Mình .... mình sẻ cải tiến theo [A1] của hpkhuong nữa thì sẻ cho tốc độ nhanh hơn khi vùng dữ liệu cho trước dư thừa quá nhiều so với thực tế....

Mã:
Private Sub GetDataFile(strPath As String, SheetName As String, _
                         DataRange As String, Col As Long, Target As Range)
                         
    Static Fso As Object, ObjFile As Object
    Dim Arr(), sFile(), Res(), x As Long, k As Long, s  As Long
    Dim FilePath As String, Sht As String, i As Long, j As Long
    If Excel4MacroSheets.Count = 0 Then
        Application.Excel4MacroSheets.Add.Name = "Temp"
        Sheets("Temp").Visible = 2
    End If
    If Fso Is Nothing Then Set Fso = CreateObject("Scripting.FileSystemObject")
    For Each ObjFile In Fso.GetFolder(strPath).Files
        If Fso.GetExtensionName(ObjFile) Like "xls*" Then
            If Left(ObjFile.Name, 2) <> "~$" Then
                If ObjFile.Name <> ThisWorkbook.Name Then
                    x = x + 1
                    ReDim Preserve sFile(1 To x)
                    sFile(x) = ObjFile
                    For s = 1 To UBound(sFile)
                        Sht = SheetName & "'!" & DataRange
                        FilePath = "='" & Fso.GetParentFolderName(sFile(s)) _
                                 & "\[" & Fso.GetFileName(sFile(s)) & "]" & Sht
                    Next
                    With Sheets("Temp").Range(DataRange)
                         .FormulaArray = FilePath
                         .Value = .Value
                         Res = .Value
                        .ClearContents
                    End With
                    ReDim Preserve Arr(1 To UBound(Res, 1), 1 To UBound(Res, 2))
                    For i = 1 To UBound(Res, 1)
                        If Res(i, Col) <> Empty Then
                            k = k + 1
                            For j = 1 To UBound(Res, 2)
                                Arr(k, j) = Res(i, j)
                            Next
                        End If
                    Next
                    If k Then Target.Resize(k, UBound(Res, 2)).Value = Arr
                End If
            End If
        End If
    Next
    Set Fso = Nothing
End Sub


Public Sub Main()
    Dim Path As String, Sht As String, Data As String
    Path = ThisWorkbook.Path                    ''duong dan tong hop File
    Sht = "THA"                                 ''Ten Sheet can Tong Hop
    Data = ("A4:M100")                          ''Vung du lieu can lay
    ActiveSheet.UsedRange.ClearContents
    GetDataFile Path, Sht, Data, 2, [A5]        ''2 = Cot Loc theo dieu kien co du lieu
End Sub
 
Upvote 0
Còn đây là cách của Mình .... mình sẻ cải tiến theo [A1] của hpkhuong nữa thì sẻ cho tốc độ nhanh hơn khi vùng dữ liệu cho trước dư thừa quá nhiều so với thực tế....

Mã:
Private Sub GetDataFile(strPath As String, SheetName As String, _
                         DataRange As String, Col As Long, Target As Range)
                         
    Static Fso As Object, ObjFile As Object
    Dim Arr(), sFile(), Res(), x As Long, k As Long, s  As Long
    Dim FilePath As String, Sht As String, i As Long, j As Long
    If Excel4MacroSheets.Count = 0 Then
        Application.Excel4MacroSheets.Add.Name = "Temp"
        Sheets("Temp").Visible = 2
    End If
    If Fso Is Nothing Then Set Fso = CreateObject("Scripting.FileSystemObject")
    For Each ObjFile In Fso.GetFolder(strPath).Files
        If Fso.GetExtensionName(ObjFile) Like "xls*" Then
            If Left(ObjFile.Name, 2) <> "~$" Then
                If ObjFile.Name <> ThisWorkbook.Name Then
                    x = x + 1
                    ReDim Preserve sFile(1 To x)
                    sFile(x) = ObjFile
                    For s = 1 To UBound(sFile)
                        Sht = SheetName & "'!" & DataRange
                        FilePath = "='" & Fso.GetParentFolderName(sFile(s)) _
                                 & "\[" & Fso.GetFileName(sFile(s)) & "]" & Sht
                    Next
                    With Sheets("Temp").Range(DataRange)
                         .FormulaArray = FilePath
                         .Value = .Value
                         Res = .Value
                        .ClearContents
                    End With
                    ReDim Preserve Arr(1 To UBound(Res, 1), 1 To UBound(Res, 2))
                    For i = 1 To UBound(Res, 1)
                        If Res(i, Col) <> Empty Then
                            k = k + 1
                            For j = 1 To UBound(Res, 2)
                                Arr(k, j) = Res(i, j)
                            Next
                        End If
                    Next
                    If k Then Target.Resize(k, UBound(Res, 2)).Value = Arr
                End If
            End If
        End If
    Next
    Set Fso = Nothing
End Sub


Public Sub Main()
    Dim Path As String, Sht As String, Data As String
    Path = ThisWorkbook.Path                    ''duong dan tong hop File
    Sht = "THA"                                 ''Ten Sheet can Tong Hop
    Data = ("A4:M100")                          ''Vung du lieu can lay
    ActiveSheet.UsedRange.ClearContents
    GetDataFile Path, Sht, Data, 2, [A5]        ''2 = Cot Loc theo dieu kien co du lieu
End Sub
Cái mảng sFile để làm gì nhỉ?
 
Upvote 0
Cái mảng sFile để làm gì nhỉ?
Cảm ơn bạn viết vậy hơi thừa ...từ từ ta điều chỉnh lại
Cắt bớt như sau
Mã:
Private Sub GetDataFile(strPath As String, SheetName As String, _
                         DataRange As String, Col As Long, Target As Range)
                         
    Static Fso As Object, ObjFile As Object
    Dim Arr(), Res(), i As Long, j As Long, k As Long
    Dim FilePath As String, Sht As String
    If Excel4MacroSheets.Count = 0 Then
        Application.Excel4MacroSheets.Add.Name = "Temp"
        Sheets("Temp").Visible = 2
    End If
    If Fso Is Nothing Then Set Fso = CreateObject("Scripting.FileSystemObject")
    For Each ObjFile In Fso.GetFolder(strPath).Files
        If Fso.GetExtensionName(ObjFile) Like "xls*" Then
            If Left(ObjFile.Name, 2) <> "~$" Then
                If ObjFile.Name <> ThisWorkbook.Name Then
                    Sht = SheetName & "'!" & DataRange
                    FilePath = "='" & Fso.GetParentFolderName(ObjFile) _
                             & "\[" & Fso.GetFileName(ObjFile) & "]" & Sht
                    With Sheets("Temp").Range(DataRange)
                         .FormulaArray = FilePath
                         .Value = .Value
                         Res = .Value
                        .ClearContents
                    End With
                    ReDim Preserve Arr(1 To UBound(Res, 1), 1 To UBound(Res, 2))
                    For i = 1 To UBound(Res, 1)
                        If Res(i, Col) <> Empty Then
                            k = k + 1
                            For j = 1 To UBound(Res, 2)
                                Arr(k, j) = Res(i, j)
                            Next
                        End If
                    Next
                    If k Then Target.Resize(k, UBound(Res, 2)).Value = Arr
                End If
            End If
        End If
    Next
    Set Fso = Nothing
End Sub
 
Upvote 0
Lỡ như dữ liệu không liên tục & hàng cuối bất kỳ thì sao nhỉ? Sửa lại theo cái mà anh Kiều Mạnh nói học được từ thầy "Chim Hồng" nè...haha.........Kiều Mạnh mà không biết chiu này của anh "Chim Hồng" thì mình ...luôn
Mã:
Sub GetData()
Const ExcelExtension As String = "|xls|xlsb|xlsm|xlsx|"
Dim i As Long, sFolder As String, iFile As Object, FullPath As String
With CreateObject("Scripting.FileSystemObject")
    sFolder = .GetParentFolderName(ThisWorkbook.FullName)
    i = 4
    Sheets("TongHop").UsedRange.Clear
    For Each iFile In .GetFolder(sFolder).Files
        If InStr(ExcelExtension, "|" & .GetExtensionName(iFile.Path) & "|") > 0 Then
            If iFile.Path <> ThisWorkbook.FullName And Left(iFile.Name, 2) <> "~$" Then
            FullPath = "'" & sFolder & "\[" & iFile.Name & "]THA'!"
                With Sheets("TongHop")
                    .[A1] = "=IFERROR(LOOKUP(2,1/(" & FullPath & "A1:A10000<>""""),ROW(1:10000)),0)"
                    [SIZE=3][COLOR=#ff0000]lr[/COLOR][/SIZE] = .[A1]
                    If lr > 3 Then
                        .Range("A" & i).Resize(lr - 3, 13).FormulaArray = "=if(" & FullPath & _
                        "A4:M" & lr & "="""",""""," & FullPath & "A4:M" & lr & ")"
                        .Range("A" & i).Resize(lr - 3, 13).Value = .Range("A" & i).Resize(lr - 3, 13).Value
                        i = i + lr - 3
                    End If
                End With
            End If
        End If
    Next
    Sheets("TongHop").[A1].ClearContents
End With
End Sub
HÌNH NHƯ THIẾU BIẾN lr MÁY TÔI CHẠY BỊ LỖI NHÉ+-+-+-+
 
Upvote 0
Cảm ơn bạn viết vậy hơi thừa ...từ từ ta điều chỉnh lại
Cắt bớt như sau
Mã:
Private Sub GetDataFile(strPath As String, SheetName As String, _
                         DataRange As String, Col As Long, Target As Range)
                         
    Static Fso As Object, ObjFile As Object
    Dim Arr(), Res(), i As Long, j As Long, k As Long
    Dim FilePath As String, Sht As String
    If Excel4MacroSheets.Count = 0 Then
        Application.Excel4MacroSheets.Add.Name = "Temp"
        Sheets("Temp").Visible = 2
    End If
    If Fso Is Nothing Then Set Fso = CreateObject("Scripting.FileSystemObject")
    For Each ObjFile In Fso.GetFolder(strPath).Files
        If Fso.GetExtensionName(ObjFile) Like "xls*" Then
            If Left(ObjFile.Name, 2) <> "~$" Then
                If ObjFile.Name <> ThisWorkbook.Name Then
                    Sht = SheetName & "'!" & DataRange
                    FilePath = "='" & Fso.GetParentFolderName(ObjFile) _
                             & "\[" & Fso.GetFileName(ObjFile) & "]" & Sht
                    With Sheets("Temp").Range(DataRange)
                         .FormulaArray = FilePath
                         .Value = .Value
                         Res = .Value
                        .ClearContents
                    End With
                    ReDim Preserve Arr(1 To UBound(Res, 1), 1 To UBound(Res, 2))
                    For i = 1 To UBound(Res, 1)
                        If Res(i, Col) <> Empty Then
                            k = k + 1
                            For j = 1 To UBound(Res, 2)
                                Arr(k, j) = Res(i, j)
                            Next
                        End If
                    Next
                    If k Then Target.Resize(k, UBound(Res, 2)).Value = Arr
                End If
            End If
        End If
    Next
    Set Fso = Nothing
End Sub
Chắc cần sửa nữa --=0
Dòng FilePath nên đưa lên trước vòng lặp. Dòng gán kết quả nên đưa ra sau vòng lặp.
 
Upvote 0
Web KT
Back
Top Bottom