【问题标题】:Macro Merge file with different header具有不同标题的宏合并文件
【发布时间】:2017-09-12 22:59:29
【问题描述】:

我正在处理两张不同的工作表,即 Sheet1 和 Sheet2。

现在,如果两个文件中的列标题相同,我已经成功地合并了 2 张工作表。那么如何合并到选择特定列的组合文件中。

我现在遇到的问题是 2 张表之间的标题不同,因此我很难合并 2 个不同的标题,但它包含相同类型的数据。例如,Sheet1 使用 First Name 作为其列标题,Sheet2 使用 Nickname 作为其列标题。

我也不希望它复制整个列,因为它包含要合并的无关紧要的列。

我附上预期的结果以供参考。

Sub Combine()
Dim J As Integer
On Error Resume Next
Sheets(1).Select
Worksheets.Add
Sheets(1).Name = "Combined"
Sheets(2).Activate
Range("A1").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1")
For J = 2 To Sheets.Count
Sheets(J).Activate
Range("A1").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
Next
End Sub

【问题讨论】:

  • @YowE3k 感谢您的编辑。我希望你能帮助我解决这个问题。
  • 仅仅因为我可以整理你的问题并不意味着我就能回答它。 (我真的不知道如何编写代码来猜测一张表中的哪个列标题与另一张表中的哪个列标题匹配 - 如果我正在这样做,我只会硬编码那种事情。)但希望有人会出现一些在不久的将来的时间并提出建议。

标签: vba excel


【解决方案1】:

如果您知道数据所在的列,那么您可以使用简单的“直到循环”来处理表格/列

查看示例 / 并查看代码注释

Option Explicit
Public Sub Example()
    Dim B As Range, _
        C As Range, _
        D As Range, _
        E As Range, _
        F As Range, _
        G As Range ' Columns on Sheet1 & Sheet2

    Dim i%, x% ' Dim as long

    Dim Sht As Worksheet  ' Every Sheet on This Workbook
    Dim Comb As Worksheet ' Combine Sheet

    Set Comb = ThisWorkbook.Worksheets("Combine")

    i = 2 ' Start on row 2 - Sheet1 & Sheet2
    x = 2 ' Start on row 2 - Combine sheet

    'Looping through the worksheets in the workbook
    For Each Sht In ThisWorkbook.Worksheets
        ' ignore Sheet "Combine"
        If Sht.Name <> "Combine" Then
            Debug.Print Sht.Name ' Print on Immediate Window

            Set B = Sht.Columns(2)
            Set C = Sht.Columns(3)
            Set D = Sht.Columns(4)
            Set E = Sht.Columns(5)
            Set F = Sht.Columns(6)

            Do Until IsEmpty(B.Cells(i))

                Comb.Columns(1).Cells(x).Value = B.Cells(i).Value
                Comb.Columns(2).Cells(x).Value = C.Cells(i).Value
                Comb.Columns(3).Cells(x).Value = D.Cells(i).Value
                Comb.Columns(4).Cells(x).Value = E.Cells(i).Value
                Comb.Columns(5).Cells(x).Value = F.Cells(i).Value

                i = i + 1
                x = x + 1
            Loop

        End If

        i = 2 ' Reset 1st Loop

    Next

    ' Auto-Fit Rows & Columns
    With Comb.Cells
        .Rows.AutoFit
        .Columns.AutoFit
    End With
End Sub

参见copy/paste - values = values - PasteSpecial method上的示例

另见How to avoid using Select in Excel VBA macros

【讨论】:

    【解决方案2】:

    我已添加到您的代码中并对其进行了评论。我希望这会有所帮助。

    Sub Combine()
    
        Dim J As Integer
        Dim Rng As Range            ' specify a range to copy
        Dim R As Long               ' set a variable to calculate a row number
    
    '    On Error Resume Next       ' You want to see the errors and fix them
                                    ' therefore don't suppress them
    '    Sheets(1).Select           ' you don't need to "select" anything
    '    Worksheets.Add             ' instead of adding a sheet I suggest you
                                    ' you create a copy of Shhet(1)
    
        Sheets("Sheet1").Copy Before:=Sheets(1)
        ' the new sheet will now be the "ActiveSheet"
        With ActiveSheet
            .Name = "Combined"
            ' delete all the columns you don't want to keep, like:-
            .Columns("C:K").Delete      ' or .Columns("F").Delete
            ' if you delete individual columns, delete from right to left (!!)
        End With
    
        ' this part is already done
    '    Sheets(2).Activate         ' you don't need to select anything
    '    Range("A1").EntireRow.Select
    '    Selection.Copy Destination:=Sheets(1).Range("A1")
    
        ' Note that sheets are numbered 1 and up.
        ' Therefore the newly inserted sheet is now # 1
        ' and the previous #1 is now Sheet(2)
        For J = 3 To Sheets.Count
    '        Sheets(J).Activate      ' you don't need to activate anything
    '        Range("A1").Select      ' you don't need to select anything either
    '        Selection.CurrentRegion.Select     ' the Selection is already selected
            With Sheets(J)
                ' Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
                ' It appears that you want to select the range from A2 to lastrow in A -1
                R = .Cells(.Rows.Count, "A").End(xlUp).Row
                Set Rng = .Range(.Cells(2, "A"), .Cells(R - 1, "A"))
                ' avoid using the Selection object. Use Range object instead:-
                ' Selection.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
                Rng.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
            End With
        Next J
    End Sub
    

    请注意,您可以在一次操作中复制包含多列的范围。只需更改您复制的范围的定义。这将复制 A:E 列。

    Set Rng = .Range(.Cells(2, "A"), .Cells(R - 1, "E"))

    无需其他更改。

    【讨论】:

    • 如果我想从两张表中选择列怎么办。例如,我想要两张表中的 b、d 和 e 列。如果可以选择a:e可能会更容易。你能启发我吗?
    • 除非您的数据表非常大(超过 10K 行),否则我建议将 A:E 从所有工作表复制到“组合”工作表并在之后删除列 C 和 A(按此顺序)所有的复制都完成了。否则,您可以使用与上述相同的代码单独复制每一列,只需为每一列或一组相邻列再添加一个 Set RngRng.Copy Destination
    • 它没有像我预期的那样粘贴。它只是复制列 a 和 b。你能像我上面的图片一样运行它吗?
    • 也许我可以,也许我不能——更可能是后者,因为我没有数据。我认为你现在有一个新问题,你应该像处理一个新问题一样处理它。首先,研究代码并找出它在哪里做了与你想要的不同的事情。删除进程中所有不相关的 cmets。然后尝试解决问题。上述代码中的相关 cmets 将帮助您,该线程中的 cmets 也将帮助您。我认为您将能够解决问题,但如果您真的失败了,您将能够指出您需要帮助的确切代码行。
    猜你喜欢
    • 1970-01-01
    • 2016-03-20
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 2017-10-05
    • 1970-01-01
    • 2019-07-18
    • 2012-12-08
    相关资源
    最近更新 更多