VBA使用方法或調用函數/過程時傳遞參數,加不加括號的問題

1 問題:在VBA裏使用對象的方法時,傳遞參數是否應該帶括號?

1.1 情形1:只傳遞1個參數時,帶不帶括號效果差不多

  • 比如下面兩種寫法都可以
  • ThisWorkbook.SaveCopyAs Filename:=ThisWorkbook.Path & "\" & ActiveSheet.Name & ".xlsm"
  • ThisWorkbook.SaveCopyAs (ThisWorkbook.Path & "\" & ActiveSheet.Name & ".xlsm")
  • 也就是說,如果使用對象的方法時,如果只有1參數,可以加括號,或不加括號。

 

  • 這種寫法卻是錯誤的
  • ThisWorkbook.SaveCopyAs (Filename:=ThisWorkbook.Path & "\" & ActiveSheet.Name & ".xlsm")
  • 也就是說,調用方法帶了括號,且是單個參數就不能帶形參的名字。。。
Sub test132()
ThisWorkbook.SaveCopyAs Filename:=ThisWorkbook.Path & "\" & ActiveSheet.Name & ".xlsm"
End Sub
 
Sub test133()
'ThisWorkbook.SaveCopyAs (filename:=ThisWorkbook.Path & "\" & ActiveSheet.Name & ".xlsm") '如果這樣寫語法報錯
ThisWorkbook.SaveCopyAs (ThisWorkbook.Path & "\" & ActiveSheet.Name & ".xlsm")
End Sub

 

1.2 情形2:如果方法帶括號,且傳遞了多個參數卻會報錯

1.2.1 使用對象的方法帶括號時,傳遞多個參數,不能是獨立一個語句。

  • 如果方法帶了k多個參數,不管是否帶參數名,如果是一條獨立的語句,都會報錯
  • 報錯:語法錯誤,或者說缺少=
  • 但如果結合 =  或其他方法等組合爲一條新的語句使用,卻是可以的。
Sub test1212()
Application.DisplayAlerts = False
Dim wb1 As Object
Dim w1                     'txt這種文件還不能定義爲object
Set wb1 = Workbooks.Add

'wb1.SaveAs(Filename:="123.txt", FileFormat:=xlUnicodeText)          '會報語法錯誤,顯示缺少=
'wb1.SaveAs("123.txt", xlUnicodeText)                                '這樣也報錯
w1 = wb1.SaveAs(Filename:="123.txt", FileFormat:=xlUnicodeText)      '函數的寫法--調用的寫法
wb1.Close

Application.DisplayAlerts = True
End Sub

 

1.2.2 使用對象的方法不帶括號時,傳遞多個參數可以是獨立的語句

  • 如果使用方法時,不帶括號,傳遞多個參數
  • 參數是否帶參數名都可以,符合參數本身的調用規則就行
  • 下面3個例子都可以
Sub test1208()
Set wb1 = Workbooks.Add
wb1.SaveAs "123.txt", FileFormat:=xlUnicodeText
wb1.Close
End Sub


Sub test1209()
Set wb1 = Workbooks.Add
wb1.SaveAs FileFormat:=xlUnicodeText, Filename:="123.txt"
wb1.Close
End Sub


Sub test1210()
Set wb1 = Workbooks.Add
wb1.SaveAs "123.txt", xlUnicodeText
wb1.Close
End Sub

 

2 使用對象的方法傳遞參數時,是否帶括號的原則

2.1 第1種解釋:帶括號的大原則:帶括號是爲了返回值,而不帶括號只是爲了過程

  • 這個原則是我是百度EH等EXCEL論壇的大神總結的
  • 大原則的思想是這樣的:方法參數用()就是表示返回的值,沒有()表示方法操作。
  • 如果希望  把1個函數或1個方法得到的結果,用在其他地方,那麼使用時應該帶括號
  • 如果使用1個函數或1個方法時,只是爲了處理過程,是一個操作,那麼應該不帶括號。
  • 我覺得這個還是非常深刻的。

 

  • 我的理解
  • 帶括號是爲了返回值, 也就是重視結果,就像調用函數的(VBA裏函數可以有返回值,sub不能)
  • 一般是把調用函數的結果賦值給了其他變量
  • 這也就解釋了,爲什麼加上括號,沒有表達式的話,VBE系統提示缺少= 
  • 而不帶括號只是爲了處理,也就是一個過程,很像語句的感覺
Sub test1211()

Set wb1 = Workbooks.Add
wb1.SaveAs Filename:="123", FileFormat:=xlUnicodeText      '類方法的寫法,像語句
wb1.Close

End Sub
Sub test1212()
Application.DisplayAlerts = False
Dim w1                  'txt這種文件還不能定義爲object
Dim wb1 As Object

Set wb1 = Workbooks.Add

'wb1.SaveAs(Filename:="123.txt", FileFormat:=xlUnicodeText)          '會報語法錯誤,顯示缺少=
w1 = wb1.SaveAs(Filename:="123.txt", FileFormat:=xlUnicodeText)      '類函數的寫法--調用的寫法

wb1.Close

Application.DisplayAlerts = True
End Sub

 

2.2  第2種解釋:有個關於參數順序這個解釋,我驗證了不對

  • 我驗證了這個說法是不對的
  • 因爲參數的傳遞,本身是有套規則的,不違背那個就可以了,不應該還和括號有關係。
  • 下面這個例子,用了括號,而且不是按參數次序寫的,可以運行
Sub test1214()
Application.DisplayAlerts = False
Dim w1                  'txt這種文件還不能定義爲object
Dim wb1 As Object

Set wb1 = Workbooks.Add

'wb1.SaveAs(Filename:="123.txt", FileFormat:=xlUnicodeText)          '會報語法錯誤,顯示缺少=
w1 = wb1.SaveAs(FileFormat:=xlUnicodeText, Filename:="123.txt")      '函數的寫法--調用的寫法

wb1.Close

Application.DisplayAlerts = True
End Sub

 

2.3 第3種解釋:總結了大原則和小例外,這個是正確的

  • 我的測試結果是對的
  • 只有1個參數的時候,可以帶括號,也可以不帶括號。如果帶括號,則1個參數不能帶參數名。
  • 除了這個奇怪的設定!其他都符合大原則,這也解釋了我最開始測試提出的問題。
  • 如果傳遞多個參數的(無論是否帶參數名),如果不帶括號,沒有問題
  • 如果傳遞多個參數的(無論是否帶參數名),如果帶了括號,不能單獨成語句,必須寫成賦值等被調用的寫法纔行。
Sub test1209()

Set wb1 = Workbooks.Add
'wb1.SaveAs (Filename:="123.txt", FileFormat:=xlUnicodeText)  '這麼寫報錯
wb1.SaveAs Filename:="123.txt", FileFormat:=xlUnicodeText
wb1.Close

End Sub


Sub test1210()

Set wb1 = Workbooks.Add
'wb1.SaveAs ("123.txt", xlUnicodeText)     '這麼寫報錯
wb1.SaveAs "123.txt", xlUnicodeText
wb1.Close

End Sub
Sub test1213()
Application.DisplayAlerts = False
Dim w1                  'txt這種文件還不能定義爲object
Dim wb1 As Object

Set wb1 = Workbooks.Add

'wb1.SaveAs(Filename:="123.txt", FileFormat:=xlUnicodeText)          '會報語法錯誤,顯示缺少=
w1 = wb1.SaveAs("123.txt", xlUnicodeText)                            '函數的寫法--調用的寫法

wb1.Close

Application.DisplayAlerts = True
End Sub

 

3 不同函數和方法本身帶有一定傾向性,比如find() 和 replace()

  • 有的函數和方法,目的就是取得返回值,注重返回值,這個結果。
  • 而有的函數方法,目的只是進行一個操作,注重過程。
  • 使用時,先天就帶有一定傾向性。

 

3.1 find()

  • 語法
  • Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)
  • find()一般是爲了查詢結果,返回的是找到的對象 range
Sub test301()
Dim a As Object   'find返回的應該是 range對象
Set a = ActiveWorkbook.ActiveSheet.UsedRange.Find(what:=2, LookIn:=xlValues)
Debug.Print a.Address

'這句話語法上OK,但因爲find() 本身的目的,不返回find()的值,這麼寫顯得很奇怪
'ActiveSheet.UsedRange.Find(what:=2, LookIn:=xlValues)  '這樣會報錯
ActiveSheet.UsedRange.Find what:=2, LookIn:=xlValues

End Sub

 

3.2 replace() 

  • 語法
  • Selection.Replace What:="¥", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ReplaceFormat:=False
  • replace() 返回的是 bool,除了做if判斷等,一般很少調用,做替換操作纔行。
Sub test302()

'ActiveSheet.UsedRange.Replace what:=6, replacemeent:=666
Range("a1:d10").Replace what:=6, replacement:=666
'這個是模糊查找,不是精確查找,所以替換可能不是想要的,比如66會變成666666

'replace()也有返回值,是布爾值,除了做判斷可能調用其返還值,一般執行操作就可以
a = Range("a1:d10").Replace(what:=6, replacement:=666)
Debug.Print a

End Sub

 

4 調用函數時,加call的用法

  • 函數調用時,可以用加call
  • 如果加call 語句的話,需要加()
  • 如果使用call 調用sub/function等,一般是單獨成句

 

5 用自定義函數驗證上述內容

  • 如果是多個參數的,可以不帶括號,如果帶括號,一般需要用call 
  • 如果是是帶括號的,一般是需要調用 函數的值。
  • call sub/function 是種單獨的用法,一般單獨使用
Sub test201()

'調用sub過程
test202 a:=1, b:=2
test202 1, 2
'test202(1,2)          '這句會報錯

Call test202(1, 2)
Call test202(a:=1, b:=2)
Debug.Print

'調用function 函數
test203 a:=4, b:=5
test203 4, 5
'test203 (4,5)        '這句會報錯


Call test203(4, 5)
Call test203(a:=4, b:=5)
'n=call test203(4,5)              '這句會報錯,call 語句不能被調用,沒有返回值
'debug.Print call test203(4,5)    '兩個方法操作了,也不行

m = test203(4, 5)
Debug.Print m
Debug.Print test203(a:=4, b:=5)

End Sub

Sub test202(a As Integer, b As Integer)
Debug.Print a + b
End Sub


Function test203(a As Integer, b As Integer) As Integer
Debug.Print 2 * a * b
test203 = 2 * a * b
End Function

 

6 一些特殊的時間函數

6.1 date  而不是date(),會自動去掉()

  • date 函數比較特殊
  • 寫了 date() 也會被VBE自動變成date
Sub test509()

Debug.Print Date

End Sub

6.2 time() 很正常

 


Sub test510()

Debug.Print Time()

End Sub

6.3 now()  很正常

Sub test511()

Debug.Print Now()

End Sub

 

7 回顧VBA調用方法或函數時,參數的傳遞形式

  • 和python的語法很像
  • 不帶參數名的調用,必須按次序,留出位置來
  • 帶參數的調用,可以不按次序
  • 如果混用,帶參數名的必須放在後面

 

8 總結

  • 大原則
  • 如果目的是爲了調用,使用函數或方法的返回值的時候,需要加括號,這個語句一般會加上其他方法或表達式等。
  • 如果目的只是爲了處理動作,是一個過程,是一個操作,調用方法或函數傳遞參數時,一般不要加括號。

 

  • 具體用法:調用函數或方法時
  • 如果帶括號,一般需要和其他方法,賦值等組合爲新語句,不能單獨成語句
  • (如果用了call 來調用,一般就是用call 單獨使用。)
  • 如果不帶括號,只能單獨成句

 

  • 特例:
  • 如果是隻傳遞1個參數,帶不帶括號都可以,單獨如果帶了括號,傳遞參數時不能帶參數名
  • 如果使用call 調用sub/function等,一般是單獨成句

 

9 參考文檔

爲了搞清楚這個,查了不少文檔,感謝前輩們的經驗

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章