您好我正在编写一个宏来比较excel中不同工作表上的两列.宏如下:
Sub Main() Application.ScreenUpdating = False Dim stNow As Date stNow = Now Dim arr As Variant arr = Worksheets("Sheet2").Range("W3:W" & Range("W" & Rows.Count).End(xlUp).Row).Value Dim varr As Variant varr = Worksheets("Sheet3").Range("P3:P" & Range("P" & Rows.Count).End(xlUp).Row).Value Dim x, y, match As Boolean For Each x In arr match = False For Each y In varr If x = y Then match = True Next y If Not match Then Worksheets("Sheet1").Range("L" & Range("L" & Rows.Count).End(xlUp).Row + 1) = x End If Next Debug.Print DateDiff("s", stNow, Now) Application.ScreenUpdating = True End Sub
如果列在同一张纸上,并且代码中没有纸张参考,则它可以完美地工作.但现在它只复制Sheet3列W中的第一个单元格,尽管此值已存在于Sheet3上的P列中.
正如您所注意到的,当没有工作表引用时,它可以正常工作.
你需要时刻资格Range()
,Rows.
并且Columns.
,否则将使用无论ActiveSheet
是.
以下内容适合您.
Sub Main() Application.ScreenUpdating = False Dim stNow As Date stNow = Now Dim arr As Variant With Worksheets("Sheet2") arr = .Range("W3:W" & .Range("W" & .Rows.Count).End(xlUp).Row).Value End With Dim varr As Variant With Worksheets("Sheet3") varr = .Range("P3:P" & .Range("P" & .Rows.Count).End(xlUp).Row).Value End With Dim x, y, match As Boolean For Each x In arr match = False For Each y In varr If x = y Then match = True Exit For End If Next y If Not match Then With Worksheets("Sheet1") .Range("L" & .Range("L" & .Rows.Count).End(xlUp).Row + 1) = x End With End If Next Debug.Print DateDiff("s", stNow, Now) Application.ScreenUpdating = True End Sub
注意:我添加了With
语句来减少使用的重复性.Worksheets("Sheetx").
另外If x = y
,根据@ ScottCraner的评论更新了语句.
另外我看到你有一些未声明的变量.我建议添加Option Explicit
到开头(之前Sub Main()
)并声明所有变量.
在@BruceWayne回答之后,您可以替换代码的中间部分,而不是使用2个x For
循环扫描每个数组中的所有元素,您只能有1个For
循环,而另一个将使用该Application.Match
函数来查找之间的匹配阵列.
在比较大型数组时,这应该可以节省大量的代码运行时间.
注意:我用match
变量替换了变量isMatch
,match
不是变量的最佳名称(因为有一个同名的函数)
编辑1:删除isMatch
变量,因为它不需要.
子码
Dim x For Each x In arr If IsError(Application.Match(x, varr, 0)) Then '<-- no match between elements inside arrays With Worksheets("Sheet1") .Range("L" & .Range("L" & .Rows.Count).End(xlUp).Row + 1) = x End With Else '<-- there is a match between arrays ' do nothing , raise a "MsgBox" End If Next x