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

时间:2011-04-15 21:40:05

标签: excel vba excel-vba

我正在尝试在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  

所有Debug.Print语句都返回有意义且正确的字符串,并检查“Reimbursements”是否存在返回true。方法调用在一行上。这是ImportSet对象代码:

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

函数体看起来像这样:

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

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

3 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:2)

重要的一点是你希望函数返回值以及传递变量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

答案 2 :(得分:1)

此问答被用作重复的目标,但没有一个答案能说明整个故事。

首先,此行为与Excel版本或主机应用程序无关:它只是标准VBA语法,并且规则在20多年来一直是相同的-JavaScriptPerl也有各自的特点,就像以前制作的每种编程语言一样

当括号定界argument list时,VBE会在调用的函数之后紧跟着左括号:

foo = MsgBox("test")
           ^^^

当括号被解释为第一个参数(即parenthesized expression)的一部分时,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)