在VBA中声明和使用范围

6

我很新于VBA,今天开发宏时我注意到了一些有趣的事情。

像这样使用Range是可以工作的:

Dim rg As Range     
Set rg = ActiveSheet.Range("A1:B2")  

使用以下方式来操作Range是不起作用的,会导致错误"Object variable not set":

Dim rg As Range   
rg = ActiveSheet.Range("A1:B2")  

但是像这样使用 Range 是有效的:
Dim rg,rg2 As Range  
rg = ActiveSheet.Range("A1:B2")  

怎么可能呢?


3
我相信你会发现它并没有真正地起到作用,只是编译时不会触发编译器错误。例如,在结尾处添加Debug.Print rg.Address,只有在使用Set时才能起作用。 - Automate This
几乎是 http://stackoverflow.com/a/17877644/11683 的副本,加上了 http://stackoverflow.com/a/19234210/11683。 - GSerg
2个回答

11

你正在学习 Variant 和对象引用。

Range 是一个对象,而 Variant 可以是任何东西包括一个对象。

这是正确的方法:

Dim rg As Range     
Set rg = ActiveSheet.Range("A1:B2")  

原因是:

  1. 你明确声明了rg是一个Range对象。
  2. 你使用Set关键字正确地分配了对象引用。

如果你不使用Set关键字,而是使用VBA语法进行值分配,那么就会产生错误:

rg = ActiveSheet.Range("A1:B2") 

如果您在同一条指令中声明多个变量,并且仅为最后一个变量指定类型,则此处的rg是一个Variant

Dim rg,rg2 As Range  ' this is like doing Dim rg As Variant, rg2 As Range
rg = ActiveSheet.Range("A1:B2")  

同时,VBA可以让您将几乎任何内容分配给一个Variant,但是在运行时可能会出现问题。


3
为了确认你的推理,这里是一个指向cpearson网站的链接,滚动至“注意使用单一维语句声明的变量”(Pay Attention To Variables Declared With One Dim Statement)部分。 - Automate This
2
也许大家都知道,但无论如何...如果将rg声明为Variant,那么rg = ActiveSheet.Range("A1:B2")会将"A1:B2"的值分配给rg(不会出现错误)。然后,rg是一个变量数组(1 to 2, 1 to 2) - Daniel Dušek
@retailcoder 是的,它很有趣 :-). 我在对象浏览器中检查了一下,Value不是Range的默认属性...至少在我的Excel版本(2007)中不是。http://stackoverflow.com/questions/17877536/vba-when-one-should-use-set-e-g-for-specialcells-return-value/17877644#17877644 - Daniel Dušek
@MathieuGuindon 没错,让我重新措辞(我删除了我的上一条评论): 可以使用正确的语法在“同一条指令”中进行多个变量声明(包括类型定义)。我在另一个回答中对此进行了详细说明。 - Albin

2

在Mathieu Guidon的回答上进一步解释:

如果你想在同一条指令中指定两个对象(同一行),你应该使用以下语法:

Dim rg as Range, rg2 As Range

这将正确地将rgrg2都分配为范围对象。

使用Dim rg, rg2 As Range,只有rg2被分配为范围对象(rg变成了Variant),正如Mathieu Guidon所正确解释的那样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接