可以在VBA中实现真正的ByRef吗?

mir*_*lav 5 vba pass-by-reference

在最近使用PDF打印机进行测试后,我发现VBA ByRef并没有像预期的那样真正地传递对变量的引用:asychnronously变量的值在通过引用传递时永远不会更新.

在以下简化示例中,ByRef Variable参数永远不会更改其值:

'--- definition ---

Private Sub WaitUntilEqual(ByRef Variable As Variant, ByVal Value As Variant)
    Dim PollingInterval as Integer = 200
    Do While Variable <> Value 
        TimeSpent = TimeSpent + PollingInterval
        Sleep PollingInterval
    Loop
End Sub

'--- usage (initializations omitted) ---

PdfCreator.cPrint "filename1"
PdfCreator.cPrint "filename2"
PdfCreator.cPrint "filename3"
'at this point, PdfCreator.cCountOfPrintjobs is 0 and needs few seconds to raise to 3
WaitUntilEqual PdfCreator.cCountOfPrintjobs, 3  'this will stick forever - it shouldn't
Run Code Online (Sandbox Code Playgroud)

这是VBA的限制吗?这可以被规避吗?

我需要这个方法3-4次(它还包括额外的功能,如超时等...)所以我不想通过复制粘贴重复整个等待循环.

小智 4

不确定这在多大程度上适用于 VBA,但 MSDN 说调用代码可以强制ByVal如果输出值没有“地址”,即不是变量,而是求值或函数调用的结果,则,或者立即常数等

\n\n

假设cCountOfPrintjobsProperty Get对象 的a PdfCreator。这意味着实际上有一个函数可以检查对象的内部结构,计算出有多少打印作业,并返回该值。该值“在堆栈上”返回,它没有固定的“地址”可供代码轮询。为了避免读取无效/未设置的内存区域,VBA 会将调用更改为ByVal,因此您的代码会挂起,因为没有任何内容可以更改参数值。

\n\n

稍后编辑

\n\n

z\xcc\xab\xcd\x8b已经在评论部分给出了答案...

\n

  • 如果该值不是“左值”,VBA 将复制该值,并且您将获得对该值的引用。左值只是意味着一个可以 byref 的表达式......属性 get 实际上是一个伪装的函数调用而不是变量,所以它不能是 byref。 (3认同)
  • @CST-Link [此处](http://msdn.microsoft.com/en-us/library/ee156838.aspx) VBA 规范:`如果 [...] 参数是 ByRef 并且映射参数的表达式被分类作为值、函数、属性或未绑定成员,局部变量在使用与参数相同的名称值和声明类型调用的过程中使用过程范围进行定义,并按如下方式分配其值:[...]` (3认同)