到目前为止,你已经创建了简单的可以执行具体任务的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

End Function

4.  运行过程EnterText

VB执行语句时,它收集用户输入的数据并且将这些数据储存在变量m和n上,然后传递这些数据到函数JoinText。VB将这些变量的值取代函数JoinText的参数,并且将结果赋到函数名称(JoinText)上。当VB返回过程EnterText时,函数的值储存于变量r。然后,函数MsgBox在信息框里显示变量r的内容。结果就是用户的完整姓名(姓和名用空格分开)。要从函数传递数值给子程序,需要将该值赋到函数名称,例如,下面的函数NumOfDays将值7传递到子程序DaysInAWeek:

Function NumOfDays()

NumOfDays = 7

End Function

Sub DaysInAWeek()

MsgBox "There are " & NumOfDays & " days in a week."

End Sub

技巧:函数过程不能做什么

函数过程不能进行任何动作,例如,它们不能在工作表里做插入,删除或设置数据格式操作,不能打开文件,或改变屏幕显示样式

明确参数类型

在前面的部分,你学习了函数根据它们自变量传递的值进行计算,当你声明函数时,你将参数名称列在一对括号里面。参数名称就像变量一样,每个参数名称在函数调用时,引用你提供的数值。当子程序调用函数过程时,它以变量形式传递参数。一旦函数做点什么,它就将结果赋给函数名称。注意,函数过程的名称当作变量来使用。

象变量一样,函数也有类型,函数的结果可以是字符串型,整型,长整型,等。要明确你函数的结

果类型,只有在函数声明行后添加关键字As和你想要的类型即可。例如:

Function MultiplyIt(num1, num2) As Integer

如果你不明确数据类型,VB将把你的函数结果设置为默认类型(Variant数据类型)。当你明确你的函数结果的数据类型时,就象你明确变量的数据类型那样有一些好处,你的程序将更有效地使用内存,因此它运行得也更快些。

我们来看看这个例子,尽管其参数在主调过程声明的是单精度浮点型,但是函数仍然返回整型数据:

1.  在工程MyFunctions (Chap04.xls)里添加一个新模块,重命名为Sample3

2.  激活模块Sample3并且输入子程序HowMuch,如下所示:

Sub HowMuch()

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

3.  在子程序HowMuch下面输入下列函数过程:

Function MultiplyIt(num1,num2) As Integer

MultiplyIt = num1 * num2

End Function

因为储存于变量num1和num2的数值不是整数,要确保它们相乘后的结果为整数,你就得将函数结果设置为整型。如果你不给函数MultiplyIt的结果设置数据类型,过程HowMuch将会将结果按变量,result声明的数据类型显示,相乘的结果将是872.1492,而不是872。

你可以在每次运行该过程时,提供它们不同的数值,来使得该函数更有用,你可以使用InputBox函数来输入数据,而不拘泥于程序代码给定的数值。你自己可以依照前面章节中的子程序EnterText,花几分钟来修改过程HowMuch。

按地址和按值传递参数

在一些过程中,当你将参数作为变量传递时,VB可能突然改变该变量的数值。要确保该被调函数不改变传递的参数值,你应该在函数声明行在参数名称之前加上关键字ByVal。我们来看看这个例子:

1.  在工程MyFunctions (Chap04.xls)里添加一新模块,命名为Sample4

2.  激活模块Sample4并输入下列代码:

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

使用关键字ByVal在参数名称前,可以防止函数改变参数值。子程序ThreeNumbers给三个变量赋值,再调用函数MyAverage来计算,最后计算该三个变量的平均值。函数的参数就是变量num1,num2和num3。注意,所有变量的前面都有关键字ByVal。同时,注意,在计算均值之前,函数MyAverage改变了变量num1的值,在函数内部,变量num1等于11(10+1),因此,当函数将计算的均值传递给过程ThreeNumbers时,函数MsgBox显示的结果是20.3333333333333而不是期望的20,接下来的三个函数显示每个变量的内容,变量储存的内容和它们开始被赋的值一致——10,20,30。

如果你在函数声明行忽略了参数num1前面的关键字ByVal,结果会怎样呢?函数的结果仍然相同,但是函数MsgBox显示的变量num1的内容现在是11了。函数MyAverage不但返回了出乎意料的结果(20.3333333333333而非20),而且改变了储存在变量num1里的原始数值。要避免VB永久地改变提供给函数的数值,就得使用关键字ByVal。

技巧:了解你的关键字:ByRef和ByVal

因为每个要传递给函数过程(或子程序)的变量,都可能在接收时改变数值,所以知道如何来保护变量的原始数值是非常重要的。VB有两个关键字,提供或者否认改变变量内容的允许——ByRef和ByVal。VB默认地按地址(关键字ByRef)给函数过程(或子程序)传递信息,引用函数被调用时,函数参数明确的数据。因此,如果函数改变了参数值,原始的数值就被改变了。

如果你在函数MyAverage声明参数num1的前面忽略了关键字ByVal时,你就会得到这种结果。如果你想要函数过程

改变原始数值,你不必专门在参数前加关键字ByRef,因为,变量数值的传递默认就是ByRef。当你在参数名称前使用关键字ByVal时,VB按值传递参数,这意味着VB复制一份原始数据,然后将复制值传递给函数,如果函数改变了参数的数值的话,原始数据依然不会变——只有复制值变化。这就是为什么函数MyAverage改变了变量num1的数值,而它的原始值还保持不变。

使用可选的参数有时候,你也许要给函数提供额外的参数,例如,你有一个计算每个人膳食的函数。然而,有时你不希望函数进行相同的计算。在参数名称前面加上关键字Optional可以指明该参数不是必须的。可选参数在必须的参数之后,列在参数清单的最后;可选参数总是Variant数据类型,这意味着你不能使用关键字As来明确可选参数的类型。在前面部分,你创建了一个计算三个数值的平均值的函数,假设,你有时只想要计算两个数的均值,你就可以将第三个参数设置为可选的。为了不破坏原来的函数MyAverage,我们来创建一个新的函数Avg,来计算两个或三个数字的均值:

1.  在工程MyFunctions (Chap04.xls)里添加一新模块,命名为Sample5

2.  激活模块Sample5并且输入下列函数:

Function Avg(num1, num2, Optional num3)

Dim totalNums As Integer

totalNums = 3

If IsMissing(num3) Then

num3 = 0

totalNums = totalNums –1

End If

Avg = (num1+num2+num3)/totalNums

End Function

3.  现在来从立即窗口调用该函数:

?Avg(2,3)

一旦你按下回车,VB就显示结果:2.5

?Avg(2,3,5)

这次结果为:3.3333333333333

你已经看到,函数Avg允许你计算两个或三个数字的平均值,你可以决定计算几个值的平均值。当你在立即窗口开始输入函数的参数时,VB将可选的参数显示在方括号里(方括号里的参数表示是可选的)

我们花几分钟来分析一下函数Avg。该函数最多可以用三个参数;参数num1和num2是必须的,而第三个参数num3是可选的。注意,可选参数以关键字Optional开头,可选参数列在参数清单的后面。因为参数num1,num2和num3的类型都没有声明,VB对待它们为Variant。函数内部,变量totalNums声明为整型,并且初始赋值为3。因为该函数必须能够处理两个或三个数字的平均值计算,有关很方便的内置函数IsMissing在检查参数的个数。如果第三个参数没有提供,函数IsMissing的值为0,同时变量totalNums的值被减去1,因此如果没有可选参数,totalNums为2。

接下来的代码根据提供的数据计算平均值,并且将结果传递到函数名称。

函数IsMissing用来检测可选参数是否提供,如果第三个参数没有提供,那么该函数返回逻辑值True,如果提供了第三个参数时,则返回False。在这里,函数IsMissing是和一个做判断的语句If…Then一起使用的(参见第五章有关该语句和VBA中其它判断语句信息)。如果没有参数num3(IsMissing),那么(Then)VB将num3设置为0,并且将变量totalNums减去1(totalNums=totalNums–1)。你还能使用别的方法来运行函数Avg吗?使用你自己的方法在工作表里运行该函数,确保你使用两个和三个参数来运行该函数。

技巧:测试函数过程

可以编写一个子程序调用自定义函数,并且显示它的结果,看它是否能得到设计结果。除此之外,

该子过程还应该能显示参数的原始数据,这样,你才能很快知道参数数值是否改变了。如果该函数

使用了可选参数,你也需要检查不使用可选参数时候的情况。

vba传值调用_VBA传递参数步骤相关推荐

  1. vba传值调用_VBA 过程和函数:传递参数教程和实例

    VBA 中,调用子过程或函数时,我们可以为它们传递参数.提供的参数可以在子过程或函数内部使用,让程序更动态和灵活.传递参数的前提是,先在子过程或函数定义阶段设置参数,后在调用时按正确的方式提供实际参数 ...

  2. vba传值调用_vba中OnAction属性指定宏名时如何传递参数?

    在vba中可以设置图形对象,菜单命令按钮的OnAction属性为指定的过程名,当单击图形对象或者菜单命令按钮时运行具体的代码. 如下所示的代码将在单元格鼠标右键快捷菜单中新建一个名为"计算两 ...

  3. vba传值调用_vba – 动态调用从形状OnAction属性传递参数的宏

    您可以为OnAction分配一个字符串,该字符串包含要调用的子句及其参数(请注意整个字符串用单引号括起来) 喜欢: Shape.OnAction = "'SubToCallOnAction ...

  4. pycharm中两个.py文件相互调用和传递参数

    在编写比较大的程序或团队协同工作时,常常会用到两个.py程序之间的相互调用和传递参数,我把自己理解的一个方法写一下. 首先要求pycharm已经安装了sys库,已知sys.argv是传递参数的核心. ...

  5. vba传值调用_小白关于VBA调用Sub传递参数之传值与传址的思考

    故事一: 从前,森林里有三个小房子,一个红房子,一个黄房子,一个蓝房子. 红房子里面放了一个苹果,黄房子里面放了两个苹果,蓝房子里面放了三个苹果. 有一天,外面来了三个小精灵,一个叫红精灵,一个叫黄精 ...

  6. vba传值调用_Access VBA如何使用Shell命令以及如何传递参数

    Access要调用第三方的Exe 执行程序,就需要用到Shell函数,那Access VBA如何 调用Shell 函数呢 使用非常简单 Shell "要执行命令的路径" 例如要打开 ...

  7. 解决SpringBoot+SpringCloud中feign调用服务传递参数为MultipartFile的问题

    文章目录 前言 一.前期说明 二.使用步骤 1.引入maven依赖 2.新建feign的配置类 2.feign客户端 3.被调用的服务的Controller 4.第三方服务远程调用主服务传递Multi ...

  8. iframe给php传值,向iframe传递参数

    有时候我们需要用到 iframe ,同时需要向 iframe 传递参数,那么我们需要如何去实现这一功能呢? 我们可以使用 JavaScript 来实现. 前端代码 JavaScript 代码 在同一页 ...

  9. 使用VBA调用jar传递参数,并获取返回值

    目录 ■VBA代码 ■Java代码 ■运行效果 Excel Log效果 (通过VBA调用jar后,运行,生成的Log) ■课题 ■课题原因(直接原因) ●log4j的配置 ■课题验证 ■课题解决(其他 ...

最新文章

  1. Linux之编译安装MySQL
  2. 利用TinyXML读取VOC2012数据集的XML标注文件裁剪出所有人体目标保存为文件
  3. css属性 background
  4. WinForm始终置顶并获取焦点
  5. python3.5安装scrapy_win7+Python3.5下scrapy的安装方法
  6. TypeScript,初次见面,请多指教 ?
  7. webpack debug
  8. purrr 0.2.0
  9. 使用双向链表构建二叉树_LeetCode-109 有序链表转换二叉搜索树
  10. g9008v android7,三星G9008V Android 4.4 (GALAXY S5 移动4G)图文刷机教程,最新教程,简单明了...
  11. axure 倒计时_Axure倒计时效果
  12. 58件女生想让男生知道的事情(男生必看)
  13. 安装打印机提示未能添加服务器,无法安装打印机解决方法
  14. 最简单的幻灯片制作,分分钟完成高逼格成片
  15. 太阳直射点纬度计算公式_高中地理——每日一讲(太阳直射点、太阳高度角、极昼、极夜)...
  16. 如何备份Chrome浏览器收藏夹
  17. 暗恋如烟花,绚烂也落寞
  18. 1 MySQL8绿色版
  19. 宁南高考成绩查询2021,宁南中学2021年统招分数线是多少?
  20. 英语外刊精读(Part 1):day1,泛读;day2,精读(上); day3,精读(下);

热门文章

  1. 游戏网站搭建,不止是一个网站那么简单
  2. golang中的xg作用
  3. Homekit智能家居DIY之智能灯泡
  4. 为什么需要计算机语言?高级语言有哪些特点?
  5. 2007热点技术职位
  6. win7注册表关闭防火墙服务器,急问::怎么用注册表关闭windows防火墙??
  7. 古为今鉴——为臣(为属)之道
  8. P2404 自然数拆分问题
  9. 设置IE浏览器文本模式为IE8或IE7
  10. 数字三角形 (15 分)