简体   繁体   English

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

[英]VBA multi-parameter function call Syntax Error

I'm trying to call a function in Excel VBA (2007), and am recieving a syntax error on the call. 我正在尝试在Excel VBA(2007)中调用函数,并且在调用时收到语法错误。 I have an array of data structures called ImportSets, which contains worksheets and strings, and am trying to pass members of items in that array to a function, called Import. 我有一个名为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. 所有Debug.Print语句都返回有意义且正确的字符串,并检查“Reimbursements”是否存在返回true。 The method call is on one line. 方法调用在一行上。 Here is the ImportSet object code: 这是ImportSet对象代码:

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? 它是什么?

I haven't used VBA in Excel 2007 but older versions only allow you to put brackets around function call parameters if you're assigning the return value to a variable. 我没有在Excel 2007中使用过VBA,但是如果要将返回值赋给变量,旧版本只允许在函数调用参数周围放置括号。 Try this: 尝试这个:

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

The important point is how you want the function to return the value and whether your passing variables ByVal or ByRef. 重要的一点是你希望函数返回值以及传递变量ByVal或ByRef。 ByRef allows the function to change the variable ByVal means the function cannot change the variable. ByRef允许函数更改变量ByVal意味着函数不能更改变量。

These 2 examples essentially do the same thing but note the subtlety in manipulating a variable ByRef and returning a variable from a function. 这两个例子基本上做了同样的事情,但注意到操纵变量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

or alternatively pass the variables ByRef and manipulate with the 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

This example is quite trivial but often an object, array etc may need passed to a function for processing ByRef rather than to provide an answer ByVal 这个例子非常简单,但通常需要将一个对象,数组等传递给一个函数来处理ByRef,而不是提供一个回答ByVal

This Q&A is being used as a duplicate target, but none of the answers are telling the whole story. 此问答被用作重复目标,但没有一个答案能够讲述整个故事。

First, this behavior has nothing to do with the version of Excel or whatever the host application is: it's just standard VBA syntax, and the rules have been been the same for well over 20 years now - JavaScript and Perl have their respective kinks as well, as does every single programming language ever made . 首先,这种行为与Excel的版本或主机应用程序无关:它只是标准的VBA语法,规则在20多年来已经相同--JavaScriptPerl也有各自的问题就像每一种编程语言一样

When the parentheses are delimiting an argument list , the VBE puts the opening parenthesis immediately after the invoked function: 当括号分隔参数列表时 ,VBE会在调用函数之后立即放置左括号:

foo = MsgBox("test")
           ^^^

When the parentheses are interpreted as part of the first argument (ie a parenthesized expression ), the VBE puts a space between the invoked procedure and its argument list: 当括号被解释为第一个参数的一部分(即带括号的表达式 )时,VBE在调用的过程和其参数列表之间放置一个空格:

MsgBox ("test")
     ^^^

This code wouldn't compile: 此代码无法编译:

MsgBox ("test", vbInformation)
     ^^^

Because the entire parenthesized expression is the first argument , and there's no way ("test", vbInformation) can be evaluated as a value - it's a syntax error, like in the OP. 因为整个带括号的表达式是第一个参数 ,并且没有办法("test", vbInformation)可以被评估为值 - 这是一个语法错误,就像在OP中一样。

If the expression can be evaluated as a value, this value is then passed by value ( ByVal ) regardless of the invoked procedure's signature specifying that parameter as ByRef - see 5.3.1.11 Procedure Invocation Argument Processing , runtime semantics : 如果表达式可以作为值计算,则该值将按ByVal传递, 而不管调用过程的签名是否将该参数指定为ByRef - 请参阅5.3.1.11过程调用参数处理运行时语义

  • If the parameter has no argument mapped to it, the parameter is ByVal, or the parameter is ByRef and the mapped argument's expression is classified as a value , function, property or unbound member, a local variable is defined with procedure extent within the procedure being invoked with the same name value and declared type as the parameter [...] 如果参数没有映射到它的参数,参数是ByVal, 或者参数是ByRef,并且映射的参数的表达式被分类为值 ,函数,属性或未绑定成员,则在过程中使用过程范围定义局部变量使用相同的名称值和声明的类型作为参数[...]调用

The solution is, as others concluded, to drop the parentheses when making a procedure call : 正如其他人总结的那样,解决方案是在进行过程调用时删除括号:

MsgBox "test", vbInformation

...or to consistently use the obsolete explicit call syntax : ...或者始终如一地使用过时的显式调用语法

Call MsgBox("test", vbInformation)

Parentheses are only needed when making a function call (ie when capturing the return value into a local variable): 只有在进行函数调用时 (即将返回值捕获到局部变量中时)才需要括号:

Dim result As vbMsgBoxResult
result = MsgBox("test", vbInformation Or vbOkCancel)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM