【发布时间】: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" & 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) <> 0 Then -
如果我错了,请纠正我,但 UsedRange sht 中似乎没有范围。始终使用 mybaseworkbook.sheets(1).range(any).command 和 mywbtocopyfrom.sheets(1).range(any).command 它更容易管理,并且可以解决许多激活工作簿的问题
-
感谢您的提示。但是,在这种情况下,缺少
.Value并不重要。即使我将.Value添加到代码中,我也会得到与以前相同的错误。您能否建议对循环进行一些修改以支持 ws 对象? -
兰斯,谢谢你的回答。不过,这其实很好。 UsedRange 实际上不需要进一步的定义。问题始于目标工作簿上的循环。