[英]VBA multi-parameter function call Syntax Error
我正在尝试在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
我在函数调用中遇到了红色突出显示的语法错误(在第一个代码段中)。 我可能错过了一些愚蠢的东西。 它是什么?
我没有在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多年来已经相同--JavaScript和Perl也有各自的问题就像每一种编程语言一样 。
当括号分隔参数列表时 ,VBE会在调用函数之后立即放置左括号:
foo = MsgBox("test")
^^^
当括号被解释为第一个参数的一部分(即带括号的表达式 )时,VBE在调用的过程和其参数列表之间放置一个空格:
MsgBox ("test")
^^^
此代码无法编译:
MsgBox ("test", vbInformation)
^^^
因为整个带括号的表达式是第一个参数 ,并且没有办法("test", vbInformation)
可以被评估为值 - 这是一个语法错误,就像在OP中一样。
如果表达式可以作为值计算,则该值将按值 ( ByVal
) 传递, 而不管调用过程的签名是否将该参数指定为ByRef
- 请参阅5.3.1.11过程调用参数处理 , 运行时语义 :
- 如果参数没有映射到它的参数,参数是ByVal, 或者参数是ByRef,并且映射的参数的表达式被分类为值 ,函数,属性或未绑定成员,则在过程中使用过程范围定义局部变量使用相同的名称值和声明的类型作为参数[...]调用
正如其他人总结的那样,解决方案是在进行过程调用时删除括号:
MsgBox "test", vbInformation
...或者始终如一地使用过时的显式调用语法 :
Call MsgBox("test", vbInformation)
只有在进行函数调用时 (即将返回值捕获到局部变量中时)才需要括号:
Dim result As vbMsgBoxResult
result = MsgBox("test", vbInformation Or vbOkCancel)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.