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