我在Excel VBA中遇到一个"编译"错误,我不理解。。。
我有一个这样的方法:
Public Sub SomeMethod(ByRef argument As SomeClass)
... <- 'argument' must be called ByRef because I have to modify it
End Sub
如果我定义一个变量,比如:
Dim var As SomeClass
没问题,我可以打电话给:
SomeMethod var
它正在发挥作用。
但是,如果我定义一个变量,比如:
Dim var as Variant
Set var = New SomeClass
它不起作用。
如果我打电话:
SomeMethod var
VB弹出一条消息:"ByRef参数类型不匹配"
如果我打电话:
SomeMethod (var)
它"编译"了,但var随后被ByVar传递,它给了我一个运行时错误消息:"对象不支持此属性或方法"
所以我基本上只是想告诉VBA,我的Variant变量"var"实际上是一个"SomeClass"对象(在调试器中,VBA是这么说的),但我不知道如何做到这一点。。。
有人能帮帮我吗?
用ByVal
装饰参数
Public Sub SomeMethod(ByVal argument As someclass)
然后你可以传递一个变体;
SomeMethod var
这是因为ByVal argument
被接收为对Variant[someclass]
的引用的本地副本,这意味着VB可以自由地执行类型转换(以转换Variant[someclass]->someclass
)。
当作为ByRef
传递时,它不会工作,因为对argument
的任何更改也会影响当前过程之外的调用对象引用变量。
如果你通过了As Object
,你就不需要ByVal
。
如果你经常使用自定义类VBA支持接口;function foo(obj as IOneOfMyWidgets)
两件事:
呼叫Sub的正确方式
在VBA中,要调用Sub,可以编写以下
SomeSub var
没有括号或这个
Call SomeSub(var)
这个:SomeSub (var)
不会做你认为它会做的事。
将变量转换为类或数据类型
在我写这篇文章的时候,Alex K给出了答案,所以我只想补充一下,类型不匹配不仅限于对象,还会影响Variant中包含的原始数据类型:
Sub tester()
Dim v As Variant
v = 1.234567 ' v is now type Variant/Double
dothis v ' No problem.
dothat v ' Compile error: ByRef argument type mismatch.
End Sub
Sub dothis(ByVal d As Double)
'stuff
End Sub
Sub dothat(ByRef d As Double)
'stuff
End Sub
您也可以显式转换为类型:
'/* Factory */
Select Case TypeName(var)
Case "SomeClass":
Dim cast As SomeClass
Set cast = var
SomeMethod cast
End Select