使用和不使用Set关键字之间的类型差异

时间:2012-06-18 18:42:44

标签: vba

我刚刚解决了一个问题,我将“Set”关键字放在定义行中,但我想知道的是“为什么”?

基本上,我这样做:

Dim startCell, iCell as Range
For Each iCell in Range(whatever)
    If iCell.value <>"" Then
        Set startCell = Cells(iCell.Row + 1, iCell.Column)
    End If
Next iCell

如果省略“Set”关键字,代码仍然编译正常,但在局部变量窗口中,我看到它的类型更改为“String”而不是“Variant / Object / Range”。为什么会这样?

3 个答案:

答案 0 :(得分:14)

这就是原因。当你这样说:

Dim startCell, iCell As Range

认为你做到了这一点:

Dim startCell As Range, iCell As Range

但你真正做的是:

Dim startCell 'As Variant, by default
Dim iCell As Range

这是典型的VBA错误。大多数VBA程序员已经做到了,这就是为什么大多数VBA程序员依赖于每Dim语句只声明一个变量(即每行一个)。否则很容易犯这个错误,之后很难发现它。

因此,对于Dim startCell,您已隐式将变量声明为Variant类型(相当于Dim startCell As Variant)。

当你说出来时:

Set startCell = Cells(iCell.Row + 1, iCell.Column)

Variant获取参考分配(Range)右侧的东西类型。但是,当你这样说时:

startCell = Cells(iCell.Row + 1, iCell.Column)

没有Set关键字,您没有为变量startCell分配引用,而是赋值,它现在获取右侧值的类型。那是什么类型的?好吧,Range对象的默认属性是Value,因此您将获得Cells(iCell.Row + 1, iCell.Column).Value的类型。如果该单元格包含字符串,那么您将获得一个字符串。

答案 1 :(得分:3)

Set用于指定对象的引用,Let(或简单赋值)以指定对象的值(如果有)

  Dim a As Variant
  Set a = ActiveSheet.Cells(1)
  'TypeName(a) = Range, a now contains reference to the cell's range
  a = ActiveSheet.Cells(1)
  'TypeName(a) = Double or String, whatever is in the Cell, a contains the cell's value

答案 2 :(得分:1)

将对象分配给变量时,必须使用 Set 关键字。 Cells(iCell.Row + 1, iCell.Column)正在返回范围对象,因此必须使用设置,否则您将获得所有人最喜欢的VBA错误:91: Object variable or With block variable not set

编辑:

Range对象也有一个默认的返回属性,即&#39; Value&#39;属性。如果您只是参考范围(&#34; A1&#34;),则需要使用范围&#39; Value&#39;作为变体的默认值。这就是为什么在提前知道数据类型时应避免使用变体的原因。