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

6

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

The calling code looks like this:

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  

All of the Debug.Print statements return meaningful and correct strings, and check for the existence of "Reimbursements" returns true. The method call is on one line. Here is the ImportSet object code:

Public Type ImportSet
    DestSheet As Worksheet
    SourceSheet As Worksheet
    SourceColumn As String
    ...other code...
End Type

The function body looks like this:

Function Import(ByRef ReimbursementSheet As Worksheet, ByRef DestSheet As Worksheet, ByRef ImportSheet As Worksheet, ByRef ImportSheetPriceColumn As String) As String  
    ....code here .....  
End Function

I am getting a red-highlighted syntax error on the function call (in the first snippet). I am probably missing something stupid. What is it?

3个回答

9

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

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

3
我觉得,VBA的语法很奇怪,如果要在参数周围使用括号,必须在过程前面使用“Call”,或者对于函数使用赋值语句。这太让人惊讶了! - Yu Shen

2
重要的一点是你希望函数如何返回值以及你传递变量的方式是按值传递还是按引用传递。按引用传递允许函数更改变量,而按值传递意味着函数不能更改变量。
这两个示例本质上做相同的事情,但请注意在操作按引用传递的变量和从函数返回变量时的微妙差别。
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 的答案。


2
这个 Q&A 被用作重复目标,但是没有一个答案讲述了整个故事。
首先,这种行为与 Excel 的版本或宿主应用程序无关:这只是标准的 VBA 语法,规则已经保持不变超过 20 年了 - JavaScriptPerl 也有各自的问题,每一种编程语言都有
当括号限定一个 参数列表 时,VBE 将开括号放在调用的函数之后:
foo = MsgBox("test")
           ^^^

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

这段代码无法编译:
MsgBox ("test", vbInformation)
     ^^^

由于整个括号表达式是第一个参数,所以无法将 ("test", vbInformation) 作为值进行评估 - 这是一个语法错误,就像 OP 中的错误一样。
如果表达式可以作为值进行评估,则该值会被按值传递(ByVal),而不管被调用过程的签名指定该参数为 ByRef - 参见 5.3.1.11 Procedure Invocation Argument Processing,运行时语义:
“如果参数没有映射到任何参数,参数是 ByVal,或者参数是 ByRef 并且映射的参数表达式被分类为值、函数、属性或未绑定成员,则在被调用的过程中定义一个具有相同名称值和声明类型的本地变量,其过程范围与参数相同。”
解决方案就是,正如其他人得出的结论一样,在进行过程调用时省略括号:
MsgBox "test", vbInformation

"...或者始终使用过时的显式调用语法:"
Call MsgBox("test", vbInformation)

括号只有在进行函数调用时需要(即将返回值存储到本地变量中):
Dim result As vbMsgBoxResult
result = MsgBox("test", vbInformation Or vbOkCancel)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接