20171113xlVba指定文件夹多簿多表分表合并150

'2017年11月13日
'Next_Seven
'功能:文件夹对话框指定文件夹下,合并(复制粘贴)每个Excel文件内的指定子表内容,
'在名为"设置"的工作表A列 输入汇总子表的名称  在B列输入汇总子表的表头行数
'C列自动输出 有效汇总的sheet个数
Public Sub 指定文件夹多簿多表分表合并()
    AppSettings True
    Dim StartTime As Variant
    Dim UsedTime As Variant
    StartTime = VBA.Timer
    
    Dim FolderPath As String, FileName As String, FilePath As String
    Dim Arr As Variant, dSht As Object, Sht As Worksheet, Wb As Workbook
    Dim EndRow As Long, EndCol As Long, Ar As Variant
    Dim i As Long, j As Long, HeadRow As Long, NextRow As Long
    Dim Key As String, NewSht As Worksheet, Rng As Range
    Dim OpenWb As Workbook, OpenSht As Worksheet
    
    Set dSht = CreateObject("Scripting.Dictionary")
    Set Wb = Application.ThisWorkbook
    Set Sht = Wb.Worksheets("设置")
    With Sht
        Application.Intersect(.Range("C:C"), .UsedRange.Offset(1)).ClearContents
        EndRow = .Cells(.Cells.Rows.Count, 1).End(xlUp).Row
        If EndRow <= 1 Then
            MsgBox "未设置工作表名称!", vbInformation, "AuthorQQ 84857038"
            Exit Sub
        End If
        For i = 2 To EndRow
            If Len(.Cells(i, 2).Value) = 0 Then
                HeadRow = 1
            Else
                HeadRow = .Cells(i, 2).Value
            End If
            Key = Trim(.Cells(i, 1).Text)
            dSht(Key) = Array(Key, HeadRow, 0)
        Next i
    End With
    
    '获取文件夹路径
    FolderPath = GetFolderPath(ThisWorkbook.Path)
    If Len(FolderPath) = 0 Then
        MsgBox "您没有选中任何文件夹,本次汇总中断!"
        Exit Sub
    End If
    
    '获取文件名列表
    Arr = FsoGetFiles(FolderPath, "*.xls*", "*" & ThisWorkbook.Name & "*")
    For i = LBound(Arr) To UBound(Arr)
        FilePath = CStr(Arr(i))
        Debug.Print FilePath
        
        Set OpenWb = Application.Workbooks.Open(FilePath)
        For Each OpenSht In OpenWb.Worksheets
            Key = OpenSht.Name
            If dSht.Exists(Key) Then
                Ar = dSht(Key)
                HeadRow = Ar(1)
                If Ar(2) = 0 Then
                    '创建新工作表
                    Set NewSht = AddWorksheet(Wb, Key, True)
                    If Application.WorksheetFunction.CountA(OpenSht.Cells) > 0 Then
                        OpenSht.UsedRange.Copy NewSht.Range("A1")
                        Ar(2) = Ar(2) + 1
                    End If
                Else
                    Set NewSht = Wb.Worksheets(Key)
                    If Application.WorksheetFunction.CountA(OpenSht.Cells) > 0 Then
                        With NewSht
                            NextRow = .Cells(.Cells.Rows.Count, 1).End(xlUp).Row + 1
                            OpenSht.UsedRange.Offset(HeadRow).Copy .Cells(NextRow, 1)
                        End With
                        Ar(2) = Ar(2) + 1
                    End If
                End If
                
                dSht(Key) = Ar
                
            End If
        Next OpenSht
        OpenWb.Close False
        
    Next i
    
    With Sht
        Set Rng = .Range("A2")
        Set Rng = Rng.Resize(dSht.Count, 3)
        Rng.Value = Application.Rept(dSht.Items, 1)
    End With
    
    
    Set dSht = Nothing
    Set Sht = Nothing
    Set NewSht = Nothing
    Set OpenWb = Nothing
    Set OpenSht = Nothing
    Set Rng = Nothing
    
    
    
    UsedTime = VBA.Timer - StartTime
    Debug.Print "UsedTime :" & Format(UsedTime, "#0.0000 Seconds")
    'MsgBox "UsedTime :" & Format(UsedTime, "#0.0000 Seconds")
    AppSettings False
    
    
End Sub

Private Function GetFolderPath(InitialPath) As String
    Dim FolderPath As String
    With Application.FileDialog(msoFileDialogFolderPicker)
        .InitialFileName = InitialPath
        .AllowMultiSelect = False
        .Title = "请选取Excel工作簿所在文件夹"
        If .Show = -1 Then
            FolderPath = .SelectedItems(1)
        Else
            GetFolderPath = ""
            'MsgBox "您没有选中任何文件夹,本次汇总中断!"
            Exit Function
        End If
    End With
    
    If Right(FolderPath, 1) <> Application.PathSeparator Then FolderPath = FolderPath & Application.PathSeparator
    GetFolderPath = FolderPath
End Function
Private Function FsoGetFiles(ByVal FolderPath As String, ByVal Pattern As String, Optional ComplementPattern As String = "") As String()
    Dim Arr() As String
    Dim FSO As Object
    Dim ThisFolder As Object
    Dim OneFile As Object
    ReDim Arr(1 To 1)
    Arr(1) = "None"
    Dim Index As Long
    Index = 0
    Set FSO = CreateObject("Scripting.FileSystemObject")
    On Error GoTo ErrorExit
    Set ThisFolder = FSO.getfolder(FolderPath)
    If Err.Number <> 0 Then Exit Function
    For Each OneFile In ThisFolder.Files
        If OneFile.Name Like Pattern Then
            If Len(ComplementPattern) > 0 Then
                If Not OneFile.Name Like ComplementPattern Then
                    Index = Index + 1
                    ReDim Preserve Arr(1 To Index)
                    Arr(Index) = OneFile.Path
                End If
            Else
                Index = Index + 1
                ReDim Preserve Arr(1 To Index)
                Arr(Index) = OneFile.Path
            End If
        End If
    Next OneFile
ErrorExit:
    FsoGetFiles = Arr
    Erase Arr
    Set FSO = Nothing
    Set ThisFolder = Nothing
    Set OneFile = Nothing
End Function
Private Function AddWorksheet(ByVal Wb As Workbook, ByVal ShtName As String, Optional ReplaceSymbol As Boolean = True) As Worksheet
    Dim Sht As Worksheet
    If Len(ShtName) = 0 Or Len(ShtName) > 31 Then
        Set AddWorksheet = Nothing
        MsgBox "Worksheet名称长度不符!", vbInformation, "AddWorksheet"
        Exit Function
    Else
        On Error Resume Next
        Set Sht = Wb.Worksheets(ShtName)
        If Err.Number = 9 Then
            Set Sht = Wb.Worksheets.Add(After:=Wb.Worksheets(Wb.Worksheets.Count))
            Err.Clear
            On Error GoTo 0
            On Error Resume Next
            Sht.Name = ShtName
            If Err.Number = 1004 Then
                Err.Clear
                On Error GoTo 0
                If ReplaceSymbol Then
                    Arr = Array("/", "\", "?", "*", "[", "]")
                    For i = LBound(Arr) To UBound(Arr)
                        ShtName = Replace(ShtName, Arr(i), "")
                    Next i
                    Set AddWorksheet = AddWorksheet(Wb, ShtName)    '再次调用
                Else
                    Set AddWorksheet = Nothing
                    MsgBox "Worksheet名称含有特殊符号!", vbInformation, "AddWorksheet"
                End If
            Else
                Set AddWorksheet = Sht
            End If
        ElseIf Err.Number = 0 Then
            Set AddWorksheet = Sht
        End If
    End If
End Function
Public Sub AppSettings(Optional IsStart As Boolean = True)
    Application.ScreenUpdating = IIf(IsStart, False, True)
    Application.DisplayAlerts = IIf(IsStart, False, True)
    Application.Calculation = IIf(IsStart, xlCalculationManual, xlCalculationAutomatic)
    Application.StatusBar = IIf(IsStart, ">>>>>>>>Macro Is Running>>>>>>>>", False)
End Sub

  

posted @ 2017-11-13 19:32  wangway  阅读(533)  评论(0编辑  收藏  举报