VBA多参数函数调用语法错误

VBA多参数函数调用语法错误,vba,excel,Vba,Excel,我试图调用Excel VBA(2007)中的函数,但在调用时收到语法错误。我有一个名为ImportSets的数据结构数组,其中包含工作表和字符串,我正在尝试将该数组中的项的成员传递给一个名为Import的函数 调用代码如下所示: For n = 1 To 7 Debug.Print ("Destsheet: " & ImportSets(n).DestSheet.name) Debug.Print ("Sourcesheet: " & ImportSets

我试图调用Excel VBA(2007)中的函数,但在调用时收到语法错误。我有一个名为ImportSets的数据结构数组,其中包含工作表和字符串,我正在尝试将该数组中的项的成员传递给一个名为Import的函数

调用代码如下所示:

For n = 1 To 7  
    Debug.Print ("Destsheet: " & ImportSets(n).DestSheet.name)  
    Debug.Print ("Sourcesheet: " & ImportSets(n).SourceSheet.name)  
    Debug.Print ("Sourcecolumn: " & ImportSets(n).SourceColumn)  
    Import(CostAnalysisWorksheet.Sheets("Reimbursements"), ImportSets(n).DestSheet, ImportSets(n).SourceSheet, ImportSets(n).SourceColumn)  
Next n  
Function Import(ByRef ReimbursementSheet As Worksheet, ByRef DestSheet As Worksheet, ByRef ImportSheet As Worksheet, ByRef ImportSheetPriceColumn As String) As String  
    ....code here .....  
End Function
所有Debug.Print语句都返回有意义且正确的字符串,并检查是否存在“报销”返回true。方法调用在一行上。以下是ImportSet对象代码:

Public Type ImportSet
    DestSheet As Worksheet
    SourceSheet As Worksheet
    SourceColumn As String
    ...other code...
End Type
函数体如下所示:

For n = 1 To 7  
    Debug.Print ("Destsheet: " & ImportSets(n).DestSheet.name)  
    Debug.Print ("Sourcesheet: " & ImportSets(n).SourceSheet.name)  
    Debug.Print ("Sourcecolumn: " & ImportSets(n).SourceColumn)  
    Import(CostAnalysisWorksheet.Sheets("Reimbursements"), ImportSets(n).DestSheet, ImportSets(n).SourceSheet, ImportSets(n).SourceColumn)  
Next n  
Function Import(ByRef ReimbursementSheet As Worksheet, ByRef DestSheet As Worksheet, ByRef ImportSheet As Worksheet, ByRef ImportSheetPriceColumn As String) As String  
    ....code here .....  
End Function

在函数调用中(在第一个代码段中)出现了一个红色突出显示的语法错误。我可能错过了一些愚蠢的事情。这是什么?

我没有在Excel 2007中使用VBA,但旧版本只允许在将返回值赋给变量时,在函数调用参数周围加括号。试试这个:

Import CostAnalysisWorksheet.Sheets("Reimbursements"), ImportSets(n).DestSheet, ImportSets(n).SourceSheet, ImportSets(n).SourceColumn

重要的一点是您希望函数如何返回值,以及您传递的变量是ByVal还是ByRef。ByRef允许函数更改变量ByVal表示函数无法更改变量

这两个示例基本上做了相同的事情,但请注意操作变量ByRef和从函数返回变量的微妙之处

Sub test()
Dim lngX As Long, lngY As Long, Product As Long

   lngY = 10
   lngX = 5
   Product = multiply(lngX, lngY)
   MsgBox (Product)
End Sub

Function multiply(ByVal lngX As Long, ByVal lngY As Long) As Long
   multiply = lngY * lngX
End Function
或者,通过ByRef传递变量并使用函数进行操作

Sub test()
Dim lngX As Long, lngY As Long, Product As Long

   lngY = 10
   lngX = 5
   Product = 0
   multiply lngX, lngY, Product
   MsgBox (Product)

End Sub

Function multiply(ByVal lngX As Long, ByVal lngY As Long, ByRef Product As Long)
  Product = lngY * lngX
End Function

这个例子很简单,但通常一个对象、数组等可能需要传递给一个函数来处理ByRef,而不是提供一个答案ByVal。这个问答被用作一个重复的目标,但没有一个答案能说明全部情况

首先,这种行为与Excel版本或任何宿主应用程序无关:它只是标准的VBA语法,规则已经保持了20多年,并且有各自的纠结,每一种编程语言都是如此

当括号用于分隔时,VBE会将左括号放在所调用函数的后面:

foo = MsgBox("test")
           ^^^
当括号被解释为第一个参数(即a)的一部分时,VBE在被调用的过程及其参数列表之间放置一个空格:

MsgBox ("test")
     ^^^
此代码无法编译:

MsgBox ("test", vbInformation)
     ^^^
因为整个括号内的表达式是第一个参数,并且
(“test”,vbInformation)
无法作为值计算-这是一个语法错误,就像在OP中一样

如果表达式可以作为一个值进行计算,则该值将通过值传递(
ByVal
,而不考虑调用过程的签名将该参数指定为
ByRef
-请参阅运行时语义:

  • 如果参数没有映射到它的参数,则参数为ByVal、或参数为ByRef,并且映射参数的表达式被分类为值、函数、属性或未绑定成员,使用与参数[…]相同的名称值和声明类型调用的过程中的过程范围定义局部变量
正如其他人总结的那样,解决方案是在进行过程调用时去掉括号:

…或一致使用过时的显式调用语法:

只有在进行函数调用时(即将返回值捕获到局部变量中时),才需要括号:


在我看来,这是VBA的有线语法,要在参数周围使用括号,必须在过程前面使用“Call”,或者在函数前面使用赋值。这真是太令人吃惊了!
Dim result As vbMsgBoxResult
result = MsgBox("test", vbInformation Or vbOkCancel)