使用或省略括号时调用方法的正确方法是什么?如果我正确理解我的Google搜索结果:将方法(或函数)的返回值分配给变量时,必须使用括号。以下是一些示例:
wbData.Sheets.Add '-> works
Set wsData = wbData.Sheets.Add '-> works
wbData.Sheets.Add(Before:=wbData.Sheets(wbData.Sheets.Count)) '-> syntax error
Set wsData = wbData.Sheets.Add(Before:=wbData.Sheets(wbData.Sheets.Count)) '-> works
wbData.Sheets.Add Before:=wbData.Worksheets(wbData.Worksheets.Count) '-> works
Set wsData = wbData.Sheets.Add Before:=wbData.Worksheets(wbData.Worksheets.Count) '-> syntax error
只是为了确保获得VBA逻辑:#3给我一个错误,因为VBA括号意味着返回值(=新工作表),但是没有变量分配给它?#6是相反的情况吗?
即使我的解释尝试是正确的,也有人可以向我解释为什么官方帮助页面上的示例对我不起作用:
ActiveWorkbook.Sheets.Add(Before:=Worksheets(Worksheets.Count))
Run Code Online (Sandbox Code Playgroud)
这给了我一个语法错误,与上面列表中的#3相同。对此我感到困惑。
该方法是否返回您需要的值?使用括号(但如果不将任何参数传递给方法,则是可选的,除非您在同一行中使用返回值)。
例如-下面RowRange返回一个Range对象,但是您不能再使用(2,1)对其直接索引,因为这被解释为将参数传递给RowRange(不带任何对象)
s = myPivotTable.RowRange(2, 1).Value 'fails with "too many parameters"
Run Code Online (Sandbox Code Playgroud)
添加括号可以清除:
s = myPivotTable.RowRange()(2, 1).Value 'OK
Run Code Online (Sandbox Code Playgroud)
使用通话?使用括号。但是Call通常被视为已弃用。
还要别的吗?不需要括号,并且可能会导致参数在传递之前被评估,从而产生意外结果。
需要注意的一件事是,Vb编辑器在方法名称和左括号之间放置一个空格-当发生这种情况时,这是一个标志,您可能根本不需要括号。
The "official help page" is on GitHub, it's actively maintained, and multiple changes are being merged every day. If there's an error in an example, open an issue for it, or better, submit a fix yourself!
The example is wrong, the parentheses either shouldn't be there, or the expression should be on the right-hand side of a Set assignment to some object variable.
you have to use parentheses when assigning the return value of a method (or function) to a variable
Correct.
When you don't capture the return value, you don't put the parentheses. If you do, the VBE gives you a hint. If you copied the example from the docs, it would look like this in the editor:
ActiveWorkbook.Sheets.Add (Before:=Worksheets(Worksheets.Count))
Run Code Online (Sandbox Code Playgroud)
Note the space. If you captured the return value:
Set newSheet = ActiveWorkbook.Sheets.Add(Before:=Worksheets(Worksheets.Count))
Run Code Online (Sandbox Code Playgroud)
No space.
Just to make sure I get the VBA logic: #3 gives me an error because the parentheses to VBA means the value (= the new worksheet) gets returned, but there's no variable to assign it to? And #6 is the opposite case?
There's more to it than that. Consider a simpler example:
MsgBox "hi", vbOkCancel
Run Code Online (Sandbox Code Playgroud)
If we wanted to capture or otherwise use the return value, we would need the parentheses:
If MsgBox("hi", vbOkCancel) = vbOk Then
Run Code Online (Sandbox Code Playgroud)
If we added parentheses without capturing/using the return value, we would have this:
MsgBox ("hi", vbOkCancel)
Run Code Online (Sandbox Code Playgroud)
So what does this space mean?
To the VBA compiler, it means "this isn't the argument list, it's the first argument, and this is a value expression: evaluate it, and send the result ByVal to the invoked procedure". The problem, of course, is that ("hi", vbOkCancel) isn't an expression, and can't be evaluated, and we have a compile error.
So back to the docs example: Before:=Worksheets(Worksheets.Count) isn't a legal expression either - it's an argument list consisting of one named argument... but syntactically it's not the argument list: parenthesized, it's an expression that, if it could be evaluated, would be passed to the first argument of the parameter list, ByVal - like so:
ActiveWorkbook.Sheets.Add Argument1:=(the result of the expression)
Run Code Online (Sandbox Code Playgroud)
The ByVal nature of the parenthesized argument is basically an accident: when VBA evaluates the expression, it gets a value... but that value is up in the air, there's no local reference to it - so even though the invoked procedure is accepting a ByRef argument, since the caller isn't holding a reference to that argument, it's discarded - effectively producing the exacty same result as if the function took the parameter ByVal.
Confusing? This should help:
Public Sub Test()
Dim foo As Long
DoSomething (foo) ' evaluates the expression, passes the result of that expression
Debug.Print foo ' prints 0
DoSomething foo ' passes a reference to the local variable
Debug.Print foo ' prints 42
End Sub
Private Sub DoSomething(ByRef value As Long)
value = 42
End Sub
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
89 次 |
| 最近记录: |