VBA函数 -> 调用,传参,返回值
函数和过程在VBA里面是很重要的概念。
之前的案例都有涉及到函数和过程的使用。今天系统给大家讲讲VBA函数。
本文主要分享有参和无参函数的创建和使用。
VBA内置了大量的函数供用户使用。但是我们也可以根据需求自定义函数。我们可以用VBA自己编写函数(Function)和过程(Procedure),两者不同之处在于函数有返回值,过程没有返回值。VBA函数也可以跟Excel内置函数一样调用。
创建不带参数的函数
要定义函数,我们需要定义好函数名和返回值。
函数可以返回一个固定的值,类似于常量。比如下面的函数,始终都返回50。
Function GetValue() As Integer
GetValue = 50
End Function
函数也可以返回VBA对象,这时我们需要用Set关键字设置返回值。
下面的案例,返回当前页签的A1:G4区域。
Function GetRange() as Range
Set GetRange = Range("A1:G4")
End Function
在过程里面调用函数
函数定义好之后,我们可以在任意位置调用他。
函数GetValue始终返回50。我们还可以在过程里面调用GetRange函数。
上面的案例中,在过程中调用GetRange函数,该函数把给定区域的字体设置成加粗。
创建函数
单个参数
函数可以带零个到多个参数。
Function ConvertKilosToPounds (dblKilo as Double) as Double
ConvertKiloToPounds = dblKilo*2.2
End Function
我们可以从子过程中调用上面的函数,来计算公斤和磅的转化。
同一个函数可以被多个子过程调用。这很有用,他避免了把同样的代码重复写很多遍,也可以把一长段代码拆分为很多小的函数,这样代码就看起来比较简洁,便于维护。
多个参数
函数也可以带多个参数。
Function CalculateDayDiff(Date1 as Date, Date2 as Date) as Double
CalculateDayDiff = Date2-Date1
End Function
上面的函数用来计算两个日期间隔天数。我们可以在子过程中调用这个函数。
可选参数
函数也可以带上可选参数,Optional。换句话说,有时候我们需要参数,有时候我们又不需要参数,取决于函数的具体使用场景。
Function CalculateDayDiff(Date1 as Date, Optional Date2 as Date) as Double
'如果Date2没有传值,就把当前日期赋值给Date2
If Date2=0 then Date2 = Date
'calculate difference
CalculateDayDiff = Date2-Date1
End Function
参数默认值
对于可选参数,我们可以在定义函数的时候设置对应的默认值。只要调用的时候没有传递可选参数,可选参数的值就自动赋值为默认值。
Function CalculateDayDiff(Date1 as Date, Optional Date2 as Date="06/02/2020") as Double
'计算时间间隔
CalculateDayDiff = Date2-Date1
End Function
传值ByVal 和传址ByRef
参数传递的时候,可以带上ByVal(传值),或者ByRef(传址,或者引用)。如果两个都不写,参数传递方式默认是ByRef传址引用
ByVal 意味着参数传递的是变量的副本, 而ByRef 意味着传递的是原来的变量自身。 ByVal传值方式下,变量的在值不会改变,即使变量的值在函数内部被修改了。而ByRef传址方式下,如果在函数内部修改了该变量参数,则原来的变量会跟着变化。
Function GetValue(ByRef intA As Integer) As Integer
intA = intA * 4
GetValue = intA
End Function
上面案例,ByRef可以省略,也可以起到传址引用的效果。
Function GetValue(intA As Integer) As Integer
intA = intA * 4
GetValue = intA
End Function
我们可以写一个测试用例来调用该函数。
Sub TestValues()
Dim intVal As Integer
'给变量赋值
intVal = 10
'调用函数,并打印结果
Debug.Print GetValue(intVal)
'调用函数后,再打印变量的值
Debug.Print intVal
End Sub
可以看到,两次打印的值都是40。变量IntVal传递给函数的时候,初始值为10,函数里面修改了该变量的值为40。使用ByRef关键字传参,修改了变量IntVal的值。通过窗口打印函数返回值,和调用函数后变量的值,不难发现这一点。
I如果不想改变参数原来的值,可以用ByVal关键字传递参数。
Function GetValue(ByVal intA As Integer) As Integer
intA = intA * 4
GetValue = intA
End Function
同样的,在测试用例调用该函数,然后打印调用前后变量的值,可以看到,ByVal传递参数的时候,变量的值保持不变。
退出函数
如果在函数里面有一个条件判断,一旦条件满足,立即返回函数值,此时可以加上Exit Function语句,立即退出函数,不继续执行后面的代码。
Function FindNumber(strSearch As String) As Integer
Dim i As Integer
'遍历字符串每个字符
For i = 1 To Len(strSearch)
'碰到数字,立即返回结果并退出函数执行
If IsNumeric(Mid(strSearch, i, 1)) Then
FindNumber= Mid(strSearch, i, 1)
'退出函数
Exit Function
End If
Next
FindNumber= 0
End Function
上面的案例,遍历字符串的每一个字符,直到找到数字并返回值。当找到一个数字的时候,立即返回值,并且退出函数。
下面的测试用例,演示了该函数的调用。
Sub CheckForNumber()
Dim NumIs as Integer
'解析文本
NumIs = FindNumber("Upper Floor, 8 Oak Lane, Texas")
'打印
Debug.Print NumIs
End Sub
在Excel页签使用函数
函数不仅可以在VBA里面调用,也可以在Excel页签里面是使用。默认情况下,用VBA创建的函数可以在Excel函数列表的用户自定义区域找到。
如下图所示,点击fx,会弹出插入函数对话框。从分类列表中选择 用户定义,就可以看到所有VBA自定义的函数(Function)。
从用户定义列表中选择你需要的函数即可。
或者直接在Excel单元格输入你需要的公式,也可以插入用户定义函数。
如果不想在Excel页签展示某个用户定义函数,可以在定义函数的时候在Function前面加上Private关键字。
Private Function CalculateDayDiff(Date1 as Date, Date2 as Date) as Double
CalculateDayDiff = Date2-Date1
End Function
再去Excel单元格输入该函数,发现已经找不到了。
有趣的是,尽管在Excel公式找不到Private定义的函数,但是仍然可以使用该函数。
如果某个参数定义为可选Optional,不管是在Excel,还是在VBA代码里面,使用的时候该参数可以不输入。
不带参数的自定义函数也可以在Excel使用。