如何在VBA中将变体分配给变体? [英] How can I assign a Variant to a Variant in VBA?

查看:149
本文介绍了如何在VBA中将变体分配给变体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(警告:虽然乍看起来似乎是一个问题,但这不是不是初学者级的问题.如果您熟悉让我们强迫"一词,或者您曾经查看了VBA规范,请继续阅读.)

(Warning: Although it might look like one at first glance, this is not a beginner-level question. If you are familiar with the phrase "Let coercion" or you have ever looked into the VBA spec, please keep on reading.)

比方说,我有一个类型为Variant的表达式,我想将其分配给一个变量.听起来很简单,对吧?

Let's say I have an expression of type Variant, and I want to assign it to a variable. Sounds easy, right?

Dim v As Variant

v = SomeMethod()    ' SomeMethod has return type Variant

不幸的是,如果SomeMethod返回一个对象(即,具有vbObject的VarType的变体),则让我们强制使用,然后v包含对象的简单数据值".换句话说,如果SomeMethod返回对TextBox的引用,则v将包含一个字符串.

Unfortunately, if SomeMethod returns an Object (i.e., a Variant with a VarType of vbObject), Let coercion kicks in and v contains the "Simple data value" of the object. In other words, if SomeMethod returns a reference to a TextBox, v will contain a string.

显然,解决方案是使用Set:

Obviously, the solution is to use Set:

Dim v As Variant

Set v = SomeMethod()

不幸的是,如果SomeMethod不会返回一个对象,例如一个字符串,产生 Type Mismatch 错误.

This, unfortunately, fails if SomeMethod does not return an object, e.g. a string, yielding a Type Mismatch error.

到目前为止,我发现的唯一解决方案是:

So far, the only solution I have found is:

Dim v As Variant

If IsObject(SomeMethod()) Then
    Set v = SomeMethod()
Else
    v = SomeMethod()
End If

不幸的是,它有两次调用SomeMethod的副作用.

which has the unfortunate side effect of calling SomeMethod twice.

有没有一种解决方案,不是需要两次调用SomeMethod?

Is there a solution which does not require calling SomeMethod twice?

推荐答案

在VBA中,将Variant分配给您不知道它是对象还是基元的变量的唯一方法是将其传递为一个参数.

In VBA, the only way to assign a Variant to a variable where you don't know if it is an object or a primitive, is by passing it as a parameter.

如果您无法重构代码以使v作为参数传递给Sub,Function或Let属性(尽管Let这也适用于对象),则始终可以在模块中声明v范围,并有一个专门的Sub专门用于保存分配该变量的目的:

If you cannot refactor your code so that the v is passed as a parameter to a Sub, Function or Let Property (despite the Let this also works on objects), you could always declare v in module scope and have a dedicated Sub solely for the purpose of save-assigning that variable:

Private v As Variant

Private Sub SetV(ByVal var As Variant)
    If IsObject(var) Then
        Set v = var
    Else
        v = var
    End If
End Sub

和其他地方呼叫SetV SomeMethod().

不好看,但这是不两次调用SomeMethod()或不触及其内部功能的唯一方法.

Not pretty, but it's the only way without calling SomeMethod() twice or touching its inner workings.

好吧,我考虑了一下,我想我找到了一个更好的解决方案,它更接近您的想法:

Ok, I mulled over this and I think I found a better solution that comes closer to what you had in mind:

Public Sub LetSet(ByRef variable As Variant, ByVal value As Variant)
    If IsObject(value) Then
        Set variable = value
    Else
        variable = value
    End If
End Sub

[...]我想VBA中没有LetSet v = ...语句

[...] I guess there just is no LetSet v = ... statement in VBA

现在有:LetSet v, SomeMethod()

您并不需要根据变量的类型将LetSet的返回值传递给变量,而是通过引用将应该保留返回值的变量作为第一个参数传递给,以便Sub可以更改其值.

You don't have a return value that you need to Let or Set to a variable depending of its type, instead you pass the variable that should hold the return value as first parameter by reference so that the Sub can change its value.

这篇关于如何在VBA中将变体分配给变体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆