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 參考文檔
爲了搞清楚這個,查了不少文檔,感謝前輩們的經驗
- http://club.excelhome.net/thread-844104-1-1.html
- http://www.accessoft.com/article-show.asp?id=8286
- http://club.excelhome.net/thread-1341060-1-1.html
- http://club.excelhome.net/thread-774772-1-1.html
- https://m.imooc.com/wenda/detail/604130