给定以下 VBA 代码,假设 Something
只是一个 VBA 类模块....
Public Type Foo
SomeThing As Something
End Type
Public Sub TestFoo()
Dim x As Foo
With x
'Correct way to do it
Set .someThing = New Something
End With
With x
'This is wrong but realized only as a RTE
'438: Object doesn't support this property or method
.SomeThing = New Something
End With
End Sub
相反,如果您将类型更改为
VBA.Collection
如下:Public Type Foo
SomeThing As VBA.Collection
End Type
Public Sub TestFoo()
Dim x As Foo
With x
.SomeThing = New VBA.Collection
End With
End Sub
现在这是一个编译错误,带有
Argument Not Optional
.这显然是错误的,但为什么它只是 VBA.Collection
的编译时错误? ?
最佳答案
这在 VBA 语言规范中进行了解释。 With
中赋值的语义 block 由语句是否为 Set
驱动。声明或 Let
陈述。在这种情况下,它是 Let
陈述:
With x
.SomeThing = New Something
End With
请注意,在 VBA 语法中,关键字
Let
是可选的(已过时):let-statement = ["Let"] l-expression "=" expression
在
Set
声明,Set
关键字是必需的:set-statement = "Set" l-expression "=" expression
With
的内部 block ,l-expression
基本上是 UDT 成员,但如果 x
也适用完全相同的行为是直接使用的。在评估
Let
时表达式,语义在 section 5.4.3.8 中描述:Static Semantics.
This statement is invalid if any of the following is true:
- <expression> cannot be evaluated to a simple data value (section 5.6.2.2 ).
之后到 5.6.2.2 (Evaluation to a simple data value) ,以下运行时语义适用(仅适用规则):
Runtime semantics.
At runtime, the simple data value’s value and value type are determined based on the classification of the expression, as follows:
If the expression’s value type is a specific class:
If the source object has a public default Property Get or a public default function, and this default member’s parameter list is compatible with an argument list containing 0 parameters, the simple data value’s value is the result of evaluating this default member as a simple data value.
Otherwise, if the source object does not have a public default Property Get or a public default function, runtime error 438 (Object doesn’t support this property or method) is raised.
因此
SomeThing As Something
的运行时错误 438 .与
Collection
, Let
静态语义仍然适用,但它失败了 静态 5.6.2.2 的语义(给出编译错误)。同样,省略了前面不适用的语义:Static semantics. The following types of expressions can be evaluated to produce a simple data value:
An expression classified as a value expression may be evaluated as a simple data value based on the following rules:
If the declared type of the expression is a specific class:
If this class has a public default Property Get or function and this default member’s parameter list is compatible with an argument list containing 0 parameters, simple data value evaluation restarts as if this default member was the expression.
Collection
的默认成员是一个函数 ( .Item
),它采用单个参数 Index
.在这段代码中,没有提供参数,所以参数列表是不兼容的:With x
.SomeThing = New VBA.Collection
End With
因此
Argument Not Optional
编译错误。
关于vba - 为什么某些类型缺少 `Set` 是运行时错误而不是编译错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52089215/