【问题标题】:Merge Excel Sheets Using VBA使用 VBA 合并 Excel 表格
【发布时间】:2010-09-18 16:53:50
【问题描述】:

我有一个 Excel 表(比如 OG.xls),其中已经有一些数据,其中有大约 5000 行,第一行有标题,最多有“AN”列。 这个行数(5000)一整年都不会改变。 现在我有 5 个 XL 文件(比如 A、B、C、D、E),这些文件中的数据每次都必须从第 5001 行开始附加到这个 OG 文件中。 这 5 个文件的列数不同,但与 OG 文件的列数相同。 我必须从这些文件中提取数据并将它们放在 OG 文件中。 从文件 A:A、B、C、D、E、F、G&H 列转到 OG.xls 文件的 F、G、T、U、V、W、X&Y 列。 同样,其他文件数据必须根据OG.xls的对应列提取

第二个文件数据必须附加在文件 A 结束的下一行的正下方。(假设从文件 A 填充数据后,现在 OG.xls 有 5110 行, 文件 B 数据必须从 OG.xls 的第 5111 行填充。 其他文件也是如此。 这5个文件的数据要逐行填写,但要与OG.xls的列匹配

每次通过填充 OG.xls 的第 5001 行的数据来重复相同的操作。为方便起见,我们可以将所有这些文件放在同一个文件夹中。

我们怎样才能做到这一点。

请帮帮我!!! 如有任何澄清,请告诉我。

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    如果您需要更准确的答案,您需要先尝试一些事情,然后在遇到困难的地方寻求帮助。我的建议是你开始; 1. 开始在 OG.XLS 中编写 VBA 脚本,第一步尝试访问文件 A.xls 并读取列并粘贴它们(它们最初可以以任何顺序位于任何位置)。 2. 一旦你能够做到这一点,下一步就是通过设置正确类型的变量并使用它们并增加它们来查看你是否将数据放在正确的列中(比如你的例子中的 5000)。 3. 您的下一步应该是阅读 A.XLS 中的列标题并找到它们 OG.XLS 并识别它们。最初你可以从做一个简单的字符串比较开始,稍后你可以改进它来做一个 VLOOKUP。 4.在此过程中,如果您遇到任何具体问题,请提出,以便您得到更好的答案。

    社区中很少有人愿意为您编写整个代码。

    【讨论】:

      【解决方案2】:

      为什么 A 列会出现在 F 列,而 C 会出现在 T 中?有没有这样的规则,比如第一行是一个标题,里面有相同的文本?

      也许一张图片可能会有所帮助。

      根据我的猜测,我会将每张工作表放入具有有意义字段名称的 RecordSet 中(您需要引用 Microsoft ActiveX Data Objects 2.8 Library)。完成后,将非常容易附加每个 RecordSet 并将它们放入单个工作表中。

      您需要能够找到每张工作表中的最后一列和最后一行才能干净地执行此操作,因此请查看 How can i find the last row...

      编辑...

      下面是一个经过整理的示例,说明如何在 VBA 中执行所需的操作。问题在于诸如空工作表、如何处理公式(这完全忽略它们)以及如何以适当的方式合并列(再次被忽略)等细节。

      这已在 Excel 2007 中进行了测试。

      Option Explicit
      Const MAX_CHARS = 1200
      
      
      
      Sub MergeAllSheets()
        Dim rs As Recordset
        Dim mergedRS As Recordset
        Dim sh As Worksheet
        Dim wb As Workbook
      
        Dim fieldList As New Collection
        Dim rsetList As New Collection
      
        Dim f As Variant
        Dim cols As Long
        Dim rows As Long
        Dim c As Long
        Dim r As Long
      
        Dim ref As String
        Dim fldName As String
        Dim sourceColumn As String
      
      
      
        Set wb = ActiveWorkbook
        For Each sh In wb.Worksheets
          Set rs = New Recordset
          ref = FindEndCell(sh)
          cols = sh.Range(ref).Column
          rows = sh.Range(ref).Row
      
          If ref <> "$A$1" Or sh.Range(ref).Value <> "" Then '' This is to catch empty sheet
            c = 1
            r = 1
            Do While c <= cols
              fldName = sh.Cells(r, c).Value
              rs.Fields.Append fldName, adVarChar, MAX_CHARS
              If Not InCollection(fieldList, fldName) Then
                fieldList.Add fldName, fldName
              End If
              c = c + 1
            Loop
            rs.Open
      
      
            r = 2
            Do While r <= rows
              rs.AddNew
              c = 1
              Do While c <= cols
                rs.Fields(c - 1) = CStr(sh.Cells(r, c).Value)
                c = c + 1
              Loop
              r = r + 1
              Debug.Print sh.Name & ": " & r & " of " & rows & ", " & c & " of " & cols
            Loop
            rsetList.Add rs, sh.Name
          End If
        Next
      
      
        Set mergedRS = New Recordset
        c = 1
        sourceColumn = "SourceSheet"
        Do While InCollection(fieldList, sourceColumn) '' Just in case you merge a merged sheet
          sourceColumn = "SourceSheet" & c
          c = c + 1
        Loop
        mergedRS.Fields.Append sourceColumn, adVarChar, MAX_CHARS
        For Each f In fieldList
          mergedRS.Fields.Append CStr(f), adVarChar, MAX_CHARS
        Next
        mergedRS.Open
      
        c = 1
        For Each rs In rsetList
          If rs.RecordCount >= 1 Then
            rs.MoveFirst
            Do Until rs.EOF
              mergedRS.AddNew
              mergedRS.Fields(sourceColumn) = "Sheet No. " & c
              For Each f In rs.Fields
                mergedRS.Fields(f.Name) = f.Value
              Next
              rs.MoveNext
            Loop
          End If
          c = c + 1
        Next
      
      
        Set sh = wb.Worksheets.Add
      
        mergedRS.MoveFirst
        r = 1
        c = 1
        For Each f In mergedRS.Fields
          sh.Cells(r, c).Formula = f.Name
          c = c + 1
        Next
      
        r = 2
        Do Until mergedRS.EOF
          c = 1
          For Each f In mergedRS.Fields
            sh.Cells(r, c).Value = f.Value
            c = c + 1
          Next
          r = r + 1
          mergedRS.MoveNext
        Loop
      End Sub
      
      Public Function InCollection(col As Collection, key As String) As Boolean
        Dim var As Variant
        Dim errNumber As Long
      
        InCollection = False
        Set var = Nothing
      
        Err.Clear
        On Error Resume Next
          var = col.Item(key)
          errNumber = CLng(Err.Number)
        On Error GoTo 0
      
        '5 is not in, 0 and 438 represent incollection
        If errNumber = 5 Then ' it is 5 if not in collection
          InCollection = False
        Else
          InCollection = True
        End If
      
      End Function
      
      
      Public Function FindEndCell(sh As Worksheet) As String
        Dim cols As Long
        Dim rows As Long
        Dim maxCols As Long
        Dim maxRows As Long
        Dim c As Long
        Dim r As Long
      
        maxRows = sh.rows.Count
        maxCols = sh.Columns.Count
      
        cols = sh.Range("A1").End(xlToRight).Column
        If cols >= maxCols Then
            cols = 1
        End If
      
      
        c = 1
        Do While c <= cols
      
          r = sh.Cells(1, c).End(xlDown).Row
          If r >= maxRows Then
            r = 1
          End If
      
          If r > rows Then
            rows = r
          End If
          c = c + 1
        Loop
      
        FindEndCell = sh.Cells(rows, cols).Address
      
      End Function
      

      【讨论】:

      • 是的,它是相同的列标题。数据必须逐行粘贴,但必须根据列标题进行匹配。我解释清楚了吗?
      • 完美,将每张工作表读入记录集中,第一行作为您的字段名称应该是轻而易举的事。合并它们也不应该太难。除非您在第一张工作表中指定,否则以正确的顺序获取列可能会很棘手。
      • 我试过你的代码 Mark 但它似乎缺少“FindEndCell”功能。不会编译。有什么地方可以找到这个吗?我正在 Excel 2010 上尝试这个。谢谢!
      猜你喜欢
      • 2021-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-23
      • 2016-06-09
      • 2021-06-14
      • 1970-01-01
      相关资源
      最近更新 更多