【问题标题】:Combining a table from multiple workbooks into one master workbook将多个工作簿中的表合并到一个主工作簿中
【发布时间】:2021-01-24 04:17:39
【问题描述】:

我是 VBA 新手,正在尝试将多个工作簿中的表格组合起来并创建一个大型主工作簿。 基本思想是(到目前为止我所做的):

  1. 我创建了一个名为“Master”的空白工作簿,工作表名称为“total”,这是我要将提取的数据粘贴到的工作簿。我在此工作簿中创建了 VBA。
  2. 我有超过 100 个源文件,我想从中提取一个表。它们都在同一个目录中:“C:\Users\Documents\Test” 这些工作表被命名为“Sheet1”。
  3. 要创建主工作簿,我想找到最后一行并开始从下一个电子表格中复制新值,但我的代码目前不起作用。
  4. 另一个问题是来自不同工作簿的每个表都包含自己的标题(列名),我想跳过第二个文件中的标题。
  5. 表格位于每个工作簿的 A1:N53 中。

这是我当前的代码:

Private Sub Extraction()

Application.ScreenUpdating = False

Dim wkbDest As Workbook
Dim wkbSource As Workbook
Set wkbDest = ThisWorkbook
Dim LastRow As Long
Dim strExtension As String

Const strPath As String = "C:\Users\Documents\Test\"
strExtension = Dir(strPath & "*.xls*")

Do While strExtension <> ""
    Set wkbSource = Workbooks.Open(strExtension)
    With wkbSource
      LastRow = .Sheets("total").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
      .Sheets("Sheet1").Range("A1:N3" & LastRow).Copy wkbDest.Sheets("Master").Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
        .Close savechanges:=False
    End With
    strExtension = Dir
Loop
Application.ScreenUpdating = True

End Sub

我确实搞砸了它定位数据的位置并将其复制并粘贴到主工作簿。 如果有人可以帮助我修改我的代码行,我将不胜感激。

提前谢谢你。

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    对不起,我在旅途中写了这个脚本,所以我没有来测试它。

    它几乎符合您的要求。 从主文件执行脚本。它使用 DIR() 循环遍历目录内的所有文件并调用 Resize 子过程,以获取范围“A1:N53”中的值并将其传输到主文件中。

    DIR() 将遍历文件路径中的所有文件。对于每个文件,它将获取 sheet(1) range("A1:N53") 中的数据(如果您不希望包含标题,请将其更改为 range("A2:N53")。抱歉,解释有点模棱两可)

    一旦通过范围获取数据,脚本将简单地调整范围大小并根据最后一行数将值传输到 Sheets(master)。

    如果有效,请告诉我,无效,请跟进 cmets 并继续努力!

    谢谢,

    下面的脚本:

    Option Explicit
    
    Dim fpath As String
    Dim fname As String
    
    Dim wb As Workbook
    Dim twb As Workbook
    
    Dim rgSrc As Range
    Dim rgDest As Range
    
    Sub foo()
        
        Application.Calculation = xlCalculationAutomatic
        Application.ScreenUpdating = False
        Application.DisplayAlerts = False
    
    
      Set wb = ThisWorkbook
    
      fpath = "C:\Users\Documents\Test\"
    
      fname = Dir(fpath)
    
    
      Do While fname <> ""
    
          Set twb = Workbooks.Open(fpath & fname)
    
          Call Resize
    
          twb.Close
       
          fname = Dir()
        
      Loop
    
        Application.ScreenUpdating = True
        Application.DisplayAlerts = True
    
    
    End Sub
    
    
    Private Sub Resize()
    
    
        ' Get all the data in the current region?change it to "A2:N53" is you dont want header included from the files in filepath
        Set rgSrc = twb.Sheets(1).Range("A1:N53")
    
        'Get the range destination
        Set rgDest = wb.Sheets("Master").Cells(wb.Sheets("Master").Cells(Rows.Count, 1).End(xlUp).Row + 1, 1)
    
        Set rgDest = rgDest.Resize(rgSrc.Rows.Count, rgSrc.Columns.Count)
        
        rgDest.Value2 = rgSrc.Value2
    
    
    End Sub
    

    【讨论】:

    • 嗨@victor song,非常感谢你,但你能给我更多关于你代码最后一部分的细节吗?我遇到了一个错误,提示 crow = wbs.sheets(s).cells(rows.count,c).end(xlup).row 的“下标超出范围”。你能解释一下这条线的作用吗?
    • 更新完成——我已经删除了私有函数并直接将它写在行中,因为我只使用了一次。请让我知道脚本是否有效,或者是否需要一些调整。
    【解决方案2】:

    您可以尝试以下我已经使用了一段时间并且似乎工作正常的代码。提示框将要求您选择文件并将所有文件合并到一个堆叠的数据库中。它还将添加一个文件名,以便您可以识别从中选取数据的文件名。下面的代码 - 让我知道这是否有帮助 -

    Private Declare PtrSafe Function SetCurrentDirectoryA Lib _
        "kernel32" (ByVal lpPathName As String) As Long
    
    Sub ChDirNet(szPath As String)
        SetCurrentDirectoryA szPath
    End Sub
    
    
    Sub MergeSpecificWorkbooks()
        Dim MyPath As String
        Dim SourceRcount As Long, FNum As Long
        Dim mybook As Workbook, BaseWks As Worksheet
        Dim sourceRange As Range, destrange As Range
        Dim rnum As Long, CalcMode As Long
        Dim SaveDriveDir As String
        Dim FName As Variant
        Dim FirstCell As String
    
    
    
        ' Set application properties.
        With Application
            CalcMode = .Calculation
            .Calculation = xlCalculationManual
            .ScreenUpdating = False
            .EnableEvents = False
        End With
    
        SaveDriveDir = CurDir
        ' Change this to the path\folder location of the files.
        ChDirNet "C:\Users\nik\test"
    
        FName = Application.GetOpenFilename(FileFilter:="Excel Files (*.xl*), *.xl*", _
                                            MultiSelect:=True)
        If IsArray(FName) Then
    
            ' Add a new workbook with one sheet.
            Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
            rnum = 1
    
    
            ' Loop through all files in the myFiles array.
            For FNum = LBound(FName) To UBound(FName)
                Set mybook = Nothing
                On Error Resume Next
                Set mybook = Workbooks.Open(FName(FNum))
                On Error GoTo 0
    
                If Not mybook Is Nothing Then
    
                    On Error Resume Next
                    With mybook.Worksheets(1)
                       FirstCell = "A1"
                       Set sourceRange = .Range(FirstCell & ":" & RDB_Last(3, .Cells))
                       ' Test if the row of the last cell is equal to or greater than the row of the first cell.
                       If RDB_Last(1, .Cells) < .Range(FirstCell).Row Then
                          Set sourceRange = Nothing
                       End If
                    End With
    
    
    
                    If Err.Number > 0 Then
                        Err.Clear
                        Set sourceRange = Nothing
                    Else
                        ' If the source range uses all columns then
                        ' skip this file.
                        If sourceRange.Columns.Count >= BaseWks.Columns.Count Then
                            Set sourceRange = Nothing
                        End If
                    End If
                    On Error GoTo 0
    
                    If Not sourceRange Is Nothing Then
    
                        SourceRcount = sourceRange.Rows.Count
    
                        If rnum + SourceRcount >= BaseWks.Rows.Count Then
                            MsgBox "There are not enough rows in the target worksheet."
                            BaseWks.Columns.AutoFit
                            mybook.Close SaveChanges:=False
                            GoTo ExitTheSub
                        Else
    
                            ' Copy the file name in column A.
                            With sourceRange
                                BaseWks.Cells(rnum, "A"). _
                                        Resize(.Rows.Count).Value = FName(FNum)
                            End With
    
                            ' Set the destination range.
                            Set destrange = BaseWks.Range("B" & rnum)
    
                            ' Copy the values from the source range
                            ' to the destination range.
                            With sourceRange
                                Set destrange = destrange. _
                                                Resize(.Rows.Count, .Columns.Count)
                            End With
                            destrange.Value = sourceRange.Value
                            rnum = rnum + SourceRcount
                        End If
                    End If
                    mybook.Close SaveChanges:=False
                End If
    
            Next FNum
            BaseWks.Columns.AutoFit
        End If
    
    ExitTheSub:
        ' Restore the application properties.
        With Application
            .ScreenUpdating = True
            .EnableEvents = True
            .Calculation = CalcMode
        End With
        ChDirNet SaveDriveDir
    End Sub
    
    
    
    Function RDB_Last(choice As Integer, rng As Range)
    
    ' A choice of 1 = last row.
    ' A choice of 2 = last column.
    ' A choice of 3 = last cell.
       Dim lrw As Long
       Dim lcol As Integer
    
       Select Case choice
    
       Case 1:
          On Error Resume Next
          RDB_Last = rng.Find(What:="*", _
                              After:=rng.Cells(1), _
                              LookAt:=xlPart, _
                              LookIn:=xlFormulas, _
                              SearchOrder:=xlByRows, _
                              SearchDirection:=xlPrevious, _
                              MatchCase:=False).Row
          On Error GoTo 0
    
       Case 2:
          On Error Resume Next
          RDB_Last = rng.Find(What:="*", _
                              After:=rng.Cells(1), _
                              LookAt:=xlPart, _
                              LookIn:=xlFormulas, _
                              SearchOrder:=xlByColumns, _
                              SearchDirection:=xlPrevious, _
                              MatchCase:=False).Column
          On Error GoTo 0
    
       Case 3:
          On Error Resume Next
          lrw = rng.Find(What:="*", _
                        After:=rng.Cells(1), _
                        LookAt:=xlPart, _
                        LookIn:=xlFormulas, _
                        SearchOrder:=xlByRows, _
                        SearchDirection:=xlPrevious, _
                        MatchCase:=False).Row
          On Error GoTo 0
    
          On Error Resume Next
          lcol = rng.Find(What:="*", _
                         After:=rng.Cells(1), _
                         LookAt:=xlPart, _
                         LookIn:=xlFormulas, _
                         SearchOrder:=xlByColumns, _
                         SearchDirection:=xlPrevious, _
                         MatchCase:=False).Column
          On Error GoTo 0
    
          On Error Resume Next
          RDB_Last = rng.Parent.Cells(lrw, lcol).Address(False, False)
          If Err.Number > 0 Then
             RDB_Last = rng.Cells(1).Address(False, False)
             Err.Clear
          End If
          On Error GoTo 0
    
       End Select
    End Function
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-09
      • 1970-01-01
      相关资源
      最近更新 更多