到目前为止,你已经创建了简单的可以执行具体任务的VBA过程,这些过程在它们运行前没有要求你提供额外的数据。然而,在现实生活中,过程(子程序和函数)经常需要参数。参数(自变量)是过程工作时需要的一个或多个数值。参数通常输入在括号之间,多个参数用逗号分割开来。使用Excel有一阵了,你已经知道Excel内置函数根据你提供的数据可能产生不同的结果。例如,如果单元格A4和A5分别含有数字5和10,加和公式=SUM(A4:A5)将会返回15,除非你更改单元格里面的数值。正如你可以传递数值给Excel内置函数,你也可以传递数值给自定义VBA过程。
现在,我们来看看如何从子程序传递数值给函数SumItUp。这个自定义函数目的是计算一个人的姓和名的字母数目。
1.在放置函数SumItUp的模块里输入下列子程序NumOfCharacters:
Sub NumOfCharacters()
Dim f As Integer
Dim l As Integer
f = Len(InputBox(“Enter first name:”))
l = Len(InputBox(“Enter last name:”))
MsgBox SumItUp(f,l)
End Sub
2. 将光标放在过程NumOfCharacters的任意地方并按下F5。VB将显示信息输入框问你名字,这个信息框由下面的函数产生:
InputBox(“Enter first name:”)
3. 输入任何名字,回车,VB接受你输入的文本并且将它作为一个参数传递给函数Len。函数Len计算提供的文本的字母数目。VB将函数Len的结果储存于变量f以供以后使用。这之后,VB显示下一个信息框,这次是问你的姓。
4. 输入任何姓,回车。VB将输入的姓传递给函数Len来获得姓的文本长度,然后数值储存于变量l。接下来发生什么呢?VB遇到了函数MsgBox,这个函数告诉VB显示函数SumItUp的结果。然而,因为这个结果还没有准备好,VB很快就跳到函数SumItUp里,使用变量f和l储存的数值来做计算。在函数内部,VB用变量f的值取代参数m和变量l值取代参数n。一旦取代工作完成,VB将两个数值加和起来,并且将结果返回给函数SumItUp。函数SumItUp内部没有其它的任务了,因此,VB又马上返回子程序并且将函数SumItUp的结果作为一个参数提供给函数MsgBox。现在这个信
息出现在屏幕上,显示了字母总数目。
5. 点击确定退出信息框,你可以多次运行过程NumOfCharacters,每次输入不同的姓名。我们来看看另外一个使用变量传递参数的例子:
1. 在工程MyFunctions (Chap04.xls)里添加一个新模块,并重命名为Sample2
2. 激活模块Sample2并且输入子程序EnterText:
Sub EnterText()
Dim m As String, n As String, r As String
m = InputBox (“Enter your first name:”)
n = InputBox(“Enter your last name:”)
r = JoinText(m, n)
MsgBox r
End Sub
3. 输入下述函数过程:
Function JoinText(k,o)
JoinText = k + ” ” + o
VB执行语句时,它收集用户输入的数据并且将这些数据储存在变量m和n上,然后传递这些数据到函数JoinText。VB将这些变量的值取代函数JoinText的参数,并且将结果赋到函数名称(JoinText)上。当VB返回过程EnterText时,函数的值储存于变量r。然后,函数MsgBox在信息框里显示变量r的内容。结果就是用户的完整姓名(姓和名用空格分开)。要从函数传递数值给子程序,需要将该值赋到函数名称,例如,下面的函数NumOfDays将值7传递到子程序DaysInAWeek:
NumOfDays = 7
End Function
Sub DaysInAWeek()
MsgBox “There are ” & NumOfDays & ” days in a week.”
End Sub
函数过程不能进行任何动作,例如,它们不能在工作表里做插入,删除或设置数据格式操作,不能打开文件,或改变屏幕显示样式
明确参数类型
果类型,只有在函数声明行后添加关键字As和你想要的类型即可。例如:
Dim num1 As Single
Dim num2 As Single
Dim result As Single
num1 = 45.33
num2 = 19.24
result = MultiplyIt(num1, num2)
MsgBox result
End Sub
MultiplyIt = num1 * num2
End Function
按地址和按值传递参数
Sub ThreeNumbers()
Dim num1 As Integer, num2 As Integer, num3 As Integer
num1 = 10
num2 = 20
num3 = 30
MsgBox MyAverage(num1,num2,num3)
MsgBox num1
MsgBox num2
MsgBox num3
End Sub
Function MyAverage(ByVal num1, ByVal num2, ByVal num3)
num1 = num1 + 1
MyAverage = (num1 + num2 + num3) / 3
End Function
因为每个要传递给函数过程(或子程序)的变量,都可能在接收时改变数值,所以知道如何来保护变量的原始数值是非常重要的。VB有两个关键字,提供或者否认改变变量内容的允许——ByRef和ByVal。VB默认地按地址(关键字ByRef)给函数过程(或子程序)传递信息,引用函数被调用时,函数参数明确的数据。因此,如果函数改变了参数值,原始的数值就被改变了。
改变原始数值,你不必专门在参数前加关键字ByRef,因为,变量数值的传递默认就是ByRef。当你在参数名称前使用关键字ByVal时,VB按值传递参数,这意味着VB复制一份原始数据,然后将复制值传递给函数,如果函数改变了参数的数值的话,原始数据依然不会变——只有复制值变化。这就是为什么函数MyAverage改变了变量num1的数值,而它的原始值还保持不变。
使用可选的参数
有时候,你也许要给函数提供额外的参数,例如,你有一个计算每个人膳食的函数。然而,有时你不希望函数进行相同的计算。在参数名称前面加上关键字Optional可以指明该参数不是必须的。可选参数在必须的参数之后,列在参数清单的最后;可选参数总是Variant数据类型,这意味着你不能使用关键字As来明确可选参数的类型。在前面部分,你创建了一个计算三个数值的平均值的函数,假设,你有时只想要计算两个数的均值,你就可以将第三个参数设置为可选的。为了不破坏原来的函数MyAverage,我们来创建一个新的函数Avg,来计算两个或三个数字的均值:
Dim totalNums As Integer
totalNums = 3
If IsMissing(num3) Then
num3 = 0
totalNums = totalNums –1
End If
Avg = (num1+num2+num3)/totalNums
End Function
?Avg(2,3)
?Avg(2,3,5)
可以编写一个子程序调用自定义函数,并且显示它的结果,看它是否能得到设计结果。除此之外,
该子过程还应该能显示参数的原始数据,这样,你才能很快知道参数数值是否改变了。如果该函数
使用了可选参数,你也需要检查不使用可选参数时候的情况。
作者:andy,如若转载,请注明出处:https://www.web176.com/vba/20266.html