为了重构和优化某些vba代码,我开始使用with
替换一系列重复引用单个对象的语句。
起初我以为
Object.operation1()
Object.operation2()
相当于
With Object
.operation1()
.operation2()
End With
并且差别在于第二个解决方案只是更快,因为我们只引用了一次对象。
然后我遇到了以下情况:
我有一张逐行填充的工作表,使用.End(xlDown)
查找最后一个空闲行,并且Offset(params)
感谢访问单元格:
案例1
Sheets("Sheet1").Range("A1").End(xlDown).Offset(1, 0) = aValue
Sheets("Sheet1").Range("A1").End(xlDown).Offset(0, 1) = anOtherValue
结果:
XXX XXX XXX <- Old line
aValue anOtherValue <- New line
等同于
案例2
With Sheets("Sheet1").Range("A1").End(xlDown)
.Offset(1, 0) = aValue
.Offset(0, 1) = anOtherValue
End With
结果:
XXX anOtherValue XXX
aValue
但相当于
案例3
With Sheets("Sheet1").Range("A1").End(xlDown)
.Offset(1, 0) = aValue
.Offset(1, 1) = anOtherValue
End With
结果:
XXX XXX XXX
aValue anOtherValue
注意:通过&#34;等效&#34;我的意思是&#34;结果相同&#34;
我想,在With
设置值后,工作表就会更新,这就是为什么第二种情况第二种Offset()
认为没有新的单元格中已填充单元格(这就是为什么anOtherValue
不在右边单元格中的原因,因为当调用Offset(0,1)
时应该包含aValue
的单元格是空的)。
希望这很清楚......
所以(最后)我的问题是:
有谁知道With
确切如何工作/行为?因为我没有在网上找到任何清晰的描述。我知道它只引用了一次该对象,但这是否意味着它在此过程中没有对该对象进行更新?
答案 0 :(得分:2)
With
只是获取并保存对指定对象的引用。该参考文献没有改变。 (你可以把它想象成一个隐含的变量)
由于显而易见的原因,您的end(xlDown)
代码第二次没有引用相同的范围,因此它不等同于您的With块。
假设您已选择A1,并运行此代码:
Sub foo()
With ActiveCell
ActiveCell.Offset(1).Select
MsgBox .Address
End With
End Sub
即使活动单元格现在为A2,您也会在消息中获得A1,因为这是With
行运行时的活动单元格。
同样,如果你选择A1并运行它:
Sub bar()
With ActiveCell
ActiveCell.Cut ActiveCell.Offset(1)
MsgBox .Address
End With
End Sub
即使活动单元格仍为A1,您也会在消息中看到A2,因为With
块引用的单元格已被移动。请注意,如果您复制它而不是剪切,则消息将显示A1,因为该单元格未被移动。