在 VBA 中传递 Variant 参数 ByRef 时出现编译错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9376002/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Compilation-error while passing Variant argument ByRef in VBA
提问by adrien.pain
I've got a "compilation" error in Excel VBA, which I don't understand...
我在 Excel VBA 中有一个“编译”错误,我不明白...
I've got a method like that :
我有一个这样的方法:
Public Sub SomeMethod(ByRef argument As SomeClass)
... <- 'argument' must be called ByRef because I have to modify it
End Sub
If I define a variable like :
如果我定义一个变量,如:
Dim var As SomeClass
No problem, I can call :
没问题,我可以打电话:
SomeMethod var
and it's working.
它正在工作。
BUT, if I define a Variant variable like :
但是,如果我定义一个 Variant 变量,如:
Dim var as Variant
Set var = New SomeClass
It doesn't work.
它不起作用。
If I call :
如果我打电话:
SomeMethod var
VB pops-up a message : 'ByRef argument type mismatch'
VB 弹出一条消息:'ByRef 参数类型不匹配'
If I call :
如果我打电话:
SomeMethod (var)
it "compiles", but var is then passed ByVar and it gave me a runtime-error message : 'Object doesn't support this property or method'
它“编译”,但随后通过 ByVar 传递了 var 并给了我一条运行时错误消息:“对象不支持此属性或方法”
So I basically just want to tell VBA that my Variant variable 'var' is in fact a 'SomeClass' object (in debugger, VBA says so), but I don't know how to do that...
所以我基本上只是想告诉 VBA,我的 Variant 变量“var”实际上是一个“SomeClass”对象(在调试器中,VBA 是这样说的),但我不知道该怎么做……
Could someone please help me ?
有人可以帮我吗?
回答by Alex K.
Decorate the argument with ByVal
用 ByVal
Public Sub SomeMethod(ByVal argument As someclass)
then you can pass a variant;
然后你可以传递一个变体;
SomeMethod var
This works because the ByVal argument
is received as a local copyof a reference to a Variant[someclass]
which means VB can freely perform a type-conversion (to convert the Variant[someclass]->someclass
).
这是有效的,因为ByVal argument
是作为对 a 的引用的本地副本接收的,Variant[someclass]
这意味着 VB 可以自由执行类型转换(以转换Variant[someclass]->someclass
)。
It wont work when passed as ByRef
because any changes to argument
would also affect the calling object reference variable outside the current procedure.
传递时它不会工作,ByRef
因为任何更改argument
也会影响当前过程之外的调用对象引用变量。
If you pass As Object
you don't need the ByVal
.
如果通过As Object
,则不需要ByVal
.
If your doing this a lot with custom classes VBA supports interfaces; function foo(obj as IOneOfMyWidgets)
如果您经常使用自定义类 VBA 支持接口; function foo(obj as IOneOfMyWidgets)
回答by Jean-Fran?ois Corbett
Two things:
两件事情:
Proper way to call a Sub
调用 Sub 的正确方法
In VBA, to call a Sub, you can either write this
在 VBA 中,要调用 Sub,你可以这样写
SomeSub var
without parentheses or this
没有括号或这个
Call SomeSub(var)
This: SomeSub (var)
doesn't do what you think it does.
这:SomeSub (var)
不会做你认为它会做的事情。
Casting Variant to class or data type
将 Variant 转换为类或数据类型
As I was writing this, Alex K's answer came in, so I will just supplement by showing that the type mismatch isn't restricted to objects, but also affects primitive data types contained in a Variant:
在我写这篇文章的时候,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
回答by mvanle
You could also explicitly cast to a type:
您还可以显式转换为类型:
'/* Factory */
Select Case TypeName(var)
Case "SomeClass":
Dim cast As SomeClass
Set cast = var
SomeMethod cast
End Select