【问题标题】:VBA macro looping through multiple worksheets and returning exact matchesVBA 宏循环遍历多个工作表并返回完全匹配
【发布时间】:2015-11-10 10:54:18
【问题描述】:

我已经浏览了互联网上的相关主题,但是我找不到解决我遇到的问题的方法。我正在研究一个宏,它将一个工作簿中的相关数据复制到另一个工作簿中新创建的工作表中,然后遍历后者的剩余工作表,以找到与这个新创建工作表中的数据完全匹配的数据。我复制和粘贴数据的部分工作正常,但是,在循环工作表时会发生错误。

我研究了这个宏的多个版本,以查看不同的解决方案是否可行,但实际上似乎没有一个可行。在目标工作簿中,工作表在 A 列中包含数据代码(某种 id),在 B 列中包含数据相关性的度量,在 C 列中包含变量名称。

我想要做的是,在将数据复制并粘贴到新创建的工作表后 - 数据代码包含在 L 列中,循环遍历目标工作簿中的所有默认工作表以检查列中的代码新创建的工作表的 L 与剩余工作表的 A 列中的代码重叠,如果重叠,则将相关工作表 C 列中的变量名称复制到新创建的工作表列 M 中。新创建的工作表称为“设置” " 并且在第 1 行包含标题(它也包含大约 110 行),其余工作表不包含标题(最多有 70 行)。

宏如下所示:

Sub match1()

    Dim listwb As Workbook, mainwb As Workbook
    Dim FolderPath As String
    Dim fname As String
    Dim sht As Worksheet
    Dim ws As Worksheet, oput As Worksheet
    Dim oldRow As Integer
    Dim Rng As Range
    Dim ws2Row As Long

    Set mainwb = Application.ThisWorkbook
    With mainwb
        Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = "Settings"
        Set oput = Sheets("Settings")
    End With

    FolderPath = "C:\VBA\"

    fname = Dir(FolderPath & "spr.xlsx")


    With Application
        Set listwb = .Workbooks.Open(FolderPath & fname)
    End With

    Set sht = listwb.Worksheets(1)

    With sht
        .UsedRange.Copy
    End With

    mainwb.Activate

            With oput
                .Range("A1").PasteSpecial
            End With

            For Each ws In ActiveWorkbook.Worksheets
                If ws.Name <> "Settings" Then
                    ws2Row = ws.Range("A" & Rows.Count).End(xlUp).Row
                    Set Rng = ws.Range("A:C" & ws2Row)
                    For oldRow = 2 To 110
                        Worksheets("Settings").Cells(oldRow, 13) = Application.WorksheetFunction.IfError(Application.WorksheetFunction.VLookup(Worksheets("Settings").Cells(oldRow, 12), Rng, 3, False), "")
                    Next oldRow
                End If
            Next ws

End Sub

替代版本如下所示(跳过复制粘贴部分):

 mainwb.Activate

        With oput
            .Range("A1").PasteSpecial
        End With

        For Each ws In ActiveWorkbook.Worksheets
            If ws.Name <> "Settings" Then
                i = 1
                For oldRow = 2 To 110
                    For newRow = 1 To 70
                        If StrComp((Worksheets("Settings").Cells(oldRow, 12).Text), (ws.Cells(newRow, 1).Text), vbTextCompare) <> 0 Then
                            i = oldRow
                            Worksheets("Settings").Cells(i, 13) = " "
                            Else
                            Worksheets("Settings").Cells(i, 13) = ws.Cells(newRow, 3)
                            i = i + 1
                            Exit For
                        End If
                    Next newRow
                Next oldRow
            End If
        Next ws

当我启动宏的第一个版本时出现错误:

运行时错误“1004”:

对象“_Worksheet”的方法“范围”失败

调试高亮部分:

Set Rng = ws.Range("A:C" & ws2Row)

当我运行宏的第二个版本时,错误消息显示:

运行时错误'9':

下标超出范围

调试高亮部分:

If StrComp((Worksheets("Settings").Cells(oldRow, 12).Text), (ws.Cells(newRow, 1).Text), vbTextCompare) <> 0 Then

我怀疑问题出在 ws (Worksheet) 对象的定义和使用上。我现在很困惑,因为我经常使用 VBA,而且我完成的任务比这个更难。然而我仍然无法解决问题。您能否提出一些解决方案。我会感谢你的帮助。

【问题讨论】:

  • 第一个版本试试Set Rng= ws.Range("A1","C" &amp; ws2Row)
  • 另一件事:当你想覆盖一个单元格的值时,你需要使用.Value,所以在你的情况下它应该是这样的:Worksheets("Settings").Cells(i, 13).Value = " "Worksheets("Settings").Cells(i, 13).Value = ws.Cells(newRow, 3).Value。同样的逻辑,是替代代码中错误的原因,那里试试:If StrComp((Worksheets("Settings").Cells(oldRow, 12).Value), (ws.Cells(newRow, 1).Value), vbTextCompare) &lt;&gt; 0 Then
  • 如果我错了,请纠正我,但 UsedRange sht 中似乎没有范围。始终使用 mybaseworkbook.sheets(1).range(any).command 和 mywbtocopyfrom.sheets(1).range(any).command 它更容易管理,并且可以解决许多激活工作簿的问题
  • 感谢您的提示。但是,在这种情况下,缺少.Value 并不重要。即使我将.Value 添加到代码中,我也会得到与以前相同的错误。您能否建议对循环进行一些修改以支持 ws 对象?
  • 兰斯,谢谢你的回答。不过,这其实很好。 UsedRange 实际上不需要进一步的定义。问题始于目标工作簿上的循环。

标签: excel vba


【解决方案1】:

在此行中:Set Rng = ws.Range("A:C" &amp; ws2Row) 您没有为列A 指定行值。您的代码基本上是 Range("A:C110"),这对 Excel 没有任何意义。尝试将其更改为Range("A2:C" &amp; ws2Row)

这样能解决问题吗?

【讨论】:

  • 感谢您的回答。我在输入代码时没有注意到这个错误。但是,有趣的是,这仍然不能解决问题......
  • 我相信我找到了问题的一个根源。在Worksheets("Settings").Cells(oldRow, 13) = Application.WorksheetFunction.IfError(Application.WorksheetFunction.VLookup(Worksheets("Settings").Cells(oldRow, 12), Rng, 3, False), "") 行中的宏的第一个版本中,我用Application.VLookup 替换了Application.WorksheetFunction.VLookup 部分,它似乎可以工作。但是,现在宏仅循环 7 个工作表中的 1 个,它是“设置”之前的最后一个工作表 - 目标工作表。您对为什么会这样有什么建议吗?
猜你喜欢
  • 2017-11-26
  • 2014-11-15
  • 1970-01-01
  • 1970-01-01
  • 2023-01-19
  • 2017-03-24
  • 2018-01-05
  • 1970-01-01
  • 2023-03-23
相关资源
最近更新 更多