深圳office培训 深圳excel培训
深圳excel培训 深圳office培训
咨询服务
深圳office培训
深圳office培训
office培训
excel培训
ppt培训
vba培训
access培训
word培训
visio培训
project培训
outlook培训
数据库培训
深圳access培训
深圳sql培训
深圳office培训
 

vba中的Sub及Function有何区别


2022年4月24日 作者: 来源:

这一期就是要介绍在VBA环境下你能使用什么东西。一般来讲,新手往往对到底写什么会引起什么结果感到比较混乱。比如写MsgBox可以出现对话框,但写MessageBox为什么就不可以。在VBA中,直接写代码,而不是在Sub里写就会报错?为何是Sub,而不是Suc,不是Sud?等等。我会将最常见的做概要性的讲解。但是我不会深入去介绍每个细节的语法。精简够用就好。如果有必要,你可以查任何的关于VB的参考手册。
Sub与Function最基本的问题是:如果你写了很多模块,每个模块有很多代码,那么你的程序代码是从哪一句开始执行?答案是,VB将代码组成一段一段的,每段从头到尾执行(当然,这是粗略的说,因为代码还可能有跳转和循环)。每一段叫做一个Sub或着一个Function。Sub是子过程“Subroutine”的简称。比如像如下的代码就定义了一个Sub。
Sub Test()
   MsgBox "Hello" 'Show Hello with a messagebox
End Sub
其中”Sub”这个关键字标志着Sub的开始,End Sub则表示其结束。其中的Sub和End Sub是关键字。所谓关键字就是VB定义好的,有特殊意义的词汇。在写代码时不可以写错一个字母,否则就不被程序解释器接受(但是你可以不区分大小写,VBA开发环境会自动帮你调整)。如果你在开发环境中写了这段代码就会发现关键字都被表为蓝色。其他的,如For,Next,If,Then,While等都是关键字。以上代码中的Test是一个名称,即这个Sub的名称。你可以随意定义这个名称,只要其不包含一些特别的符号,并且不和关键字重名(注意:绝对不能包含空白字符,如空格或制表符)。写完这段代码后,在Office的“宏”对话框列表里就能看到一项“Test”了。代码中的括号是用于定义参数的。如果想在Sub/Function上加输入参数,都是在括号中写一个列表,即
参数名1 As 类型1,参数名2 As 类型2,...
参数和类型在下面的“变量与类型”一节更详细的介绍。即使没有参数也要写个空括号来占位置。这是VB的要求。之后,当你将键盘光标放在这个Sub里,并点击上面的绿色箭头;或者到“宏”对话框执行Test,这个Sub就被执行了。
另外值得注意的是单引号后边的文字,称为注释。VB中所有写在单引号后边的文字都会被解释器忽略掉,它们仅仅是给人看的。所以你可以在写代码时加上注释,方便其他人看懂你的程序。
Function和Sub是很类似的东西。比如:
Function Add(a1 As Integer, a2 As Integer) As Integer
   sum = a1 + a2
   Add = sum
End Function
这个例子实现了一个Function,含义是将两个整数加起来。这次我添加了两个参数a1和a2用于输入,其类型均为Integer。参数的语法Sub和Function是一样的。形式上,Function和Sub仅仅有关键字的差别。Function与Sub最大的不同就在于Function需要返回一个值,而Sub不需要。第一行最后那个“As Integer”是指返回值的类型。返回的语法是:
Function名称=想要返回的值
那么什么叫“返回”呢?这是因为程序段之间是可以互相调用的。Sub和Function可以调用其他的Sub和Function。每个Sub/Function都可以调用其他的Sub/Function,这种形式造成了一种层数无限定的树状结构。在调用时,上层可以以参数的形式给予下层输入,而下层将控制权返回给上层的时候,也可以给上层一个返回值(只有Function可以)。比如上面的Sub “Test” 调用了VB已经定义好的MsgBox这个Function来完成工作(是不是觉得MsgBox应该是一个Sub?实际上MsgBox会返回一个整数值表示用户是按哪个键关闭对话框的,比如“确定”,“取消”,“重试”等。只不过在最简单的情况下我们不关心这个返回值罢了)。另外,我们也可以写一个程序让Test调用Add。
Sub Test()
  sum = Add(3,4)
  MsgBox sum
End Sub
这样就能用对话框显示3与4的和了。在实践当中,Sub一般用于执行某个动作;而Function则在Excel自定义函数中特别有用。VB为开发者提供了一个很大的库,即你可以直接使用许许多多的Sub和Function来完成常见的任务(这和Office库无关),比如字符串操作的Substr,Trim,Len;文件操作的Dir,Write;数学运算的Log,Sqr等。完整的清单可以在任何一本VB的参考手册上找到。
变量与类型我们在算数的时候需要草稿纸,将计算的中间结果记录下来。计算机算数也不例外,也得需要在内存中开辟一些空间来记录这些内容。定义一块空间的方法的代码是:
Dim var 或者
Dim var As Type
或者就像上文Test中的sum那样不经定义直接使用。其中Dim和As是关键字,而var就是变量名。你可以随意定义变量名称,只要其不包含一些特别的符号,并且不和关键字重名。既然是分配一块内存空间,那么分配空间有多大呢,又是怎么使用的呢?这就由类型来定义了。一个类型规定了要分配的空间的大小和内部结构,比如Integer整数就分配2个Byte(所以其范围是-32768 ~ 32767);而Long长整型数分配4Byte;Double双精浮点数(小数)就分配8个Byte;String字符串的长度就是其存储字符串长度+一块用于存放字符串的长度的额外空间。以上这些类型由VB定义,被称为基本类型(还有其它几个基本类型可以使用)。VB会尽可能在你混用这些基本类型时进行自动转换。比如:
Dim str as String
Dim n as Integer
str = 12  'now str is "12"
n = "34"  'now n is 34
n = 23.45 'now n is 23
可见,在类型转换中,可能会有数据损失。此外对于对象类型(下文将介绍)来讲,将一个类型的值赋给另一个类型的变量是会报错的。因此建议大家尽量减少混用的情况。
一种特别的类型是Variant。这种变量可以放置任何类型的数据。比如上文中的Dim var就等价于Dim var As Variant。但是要注意的是Variant并不意味着变量内容的类型可以变化。它仅仅是能放置任何类型的数据而已,同一时间只有一个”实际类型”。为此,其内部必须维护当前到底是什么类型,还需要在被访问时进行内部的二次解释。所以它消耗的空间更大,并且性能更差。另外如果用Variant变量表示一个对象,在写变量名后输入一个点,就不会有自动提示出现。因此,建议大家少用Variant类型。
最后说一下作用域的问题。每一个变量都有一个作用域。如果在一个Sub/Function内定义变量,那么这个变量的作用域就仅仅限于这个Sub/Function,称为局部变量。也就是说,在其他Sub/Function中是访问不到这个变量的;或者说,如果在其他Sub/Function中定义了同名的变量,二者完全是两码事,互相不会有任何影响。
在Sub/Function中的参数也是一种局部变量,其定义的方式就是比常规方法省略了Dim。其形式正如上文所写的那样。当然,你也可以在参数列表里不写类型,这就意味着参数类型是Varaint。同样的,Function第一行的最后的As Type表明Function返回值的类型。不写这个返回值就意味返回Variant类型。
如果将Dim语句写在任意Sub/Function之外,就定义了全局变量。此时变量对于当前模块文件的所有Sub/Function都有效。这时,不同的Sub/Function之间就能通过全局变量交流(尽管这不是个好习惯,因为这样就破坏了Sub/Function的独立性,使得复用难以进行)。当然,还有可以在不同模块之间都有效的变量的定义方法,即将全局变量定义中的“Dim”改为“Public”。不过这种变量在小型程序中非常少见。
也许你会问,如果某个局部变量恰好和全局变量同名会怎么样?这时局部变量会“遮蔽”全局变量,使你只能访问到局部变量。
下面是一个例子,大家可以来复习一下本次的内容。
Sub ShowSum()
   Range("A1").Value = CalSum(200)
End Sub
Function CalSum(n As Integer) As Integer
   Dim sum As Integer
   sum = 0
   For i = 1 To n Step 1
      If i Mod 7 = 0 Then
         sum = sum + i
      End If
   Next
   CalSum = sum
End Function
最近代码计算了1~200之间所有可以被7整除的数字之和,并在A1单元格内显示结果(所以,请在Excel的VBA环境里运行此段代码)。里面展示了如何定义和使用Sub,Function以及如利用变量来存储数据。当然,我也用了一些没有讲过的关键字,如For,If等。但我觉得它们的意思都是非常容易懂的。比如For i=1 To n Step 1就定义了一个循环,让i从1逐渐增长为n,每次步长是1。所以i依次变为1,2,3,……,n。当运行到Next那句时就会返回到For那一行,将i增量,重新执行循环体代码。而If是判断语句,判断i与7取模是否是0(整除),Mod是关键字表示取模。而Range(”A1″)则是Excel提供的一个对象,意为得到名称为A1的那个单元格区域。之后的代码就是将其值设为想要的结果。关于对象将是下次的主题。最后值得注意的是那个n不要设的过大,否则很容易造成sum不足以存储过大的数据而越界(记得么,整数的最大值是32767)。
总结本期我们讲了最基本的VB构造元素。讲解了Sub、Function、关键字、变量定义和类型等概念。如果你能读到这里,想想看你还能记得它们是怎么回事不?当然关于这个主题,有很庞大的内容我没有讲。但往往就是这20%的内容在100%代码里被用到,它们是最核心的内容。对于一些高级话题,如果你有兴趣的话,可以看Programming Microsoft Visual Basic 6.0 by Francesco Balena (Microsoft Press)。下一期讲带大家进入对象的世界:)
问答1.我是菜鸟,一般一个sub连dim都不用,想起什么变量就上去用了。 这是不是相当于dim as variant ?
比如
sub a()
aa=1
msgbox aa
end sub
真实感觉:速度上,损失似乎不大;内存,似乎一个sub一次执行之后,变量全清空了,内存里的aa也被释放了。那么对于一般的小程序来说,是不是就无所谓了呢?
—————————————————–
是的,小程序无所谓,方便就好。但是如果程序稍微大了些,对象多了些,类型检查是一个很好的防止错误的功能。那个时候,写的对比写的少更重要。其实我觉得在目前的硬件平台上,性能可以不做最优先考虑。反倒是编程的便利性(写正确的类型后VBA编辑器有自动提示),可读性和类型错误检测让我不喜欢用Variant。
2.能返回数值的function,以及带变量的sub。 感觉很好用,但是他们自己若返回数值就不能单独执行了 ?? 比较困扰
—————————————————–
是的,一般情况下,Function不能像Sub直接被绑定到某个快捷键,某个按钮那样执行。必须被某个Sub或者Function调用才行。但是有一种情况,就是Excel的自定义函数,Function的地位无可替代。写一个Function后,可以像Excel自带函数那样直接在单元格里使用。
3.VBA的变量必须先声明再使用么?
—————————————————–
当然不是,VBA允许你直接使用变量而不经任何声明。但是这样做可能会引起难以调试的错误。比如你在第一行直接使用了变量abc,结果到了后边由于笔误写成了acb。这一定会出逻辑错误,但是解释器因为语法没问题而不会报错。你自己也很难在密密麻麻的代码中将这个错误挑出来。为了强迫变量必须先声明,再使用,在程序的第一行加上这句:
Option Explicit
这样,如果不经声明直接使用变量就会报语法错误。这对于比较大的程序十分必要


阅读:1341 上一则:Excel VBA 专家咨询服务 下一则:常用vba英文词语

返回前页 返回顶部
温馨提示:本中心是深圳较为专业office培训机构、咨询及报名请先预约,电话:0755-82124110。
深圳地址:深圳红荔路四川大厦1109B-1110(3号龙岗线通新岭地铁站A出口10米)
热线:0755-82124110(福田、南山、宝安) 0755-22205758(罗湖、龙岗、龙华) 13510024571(东莞、惠州、珠海、广州)
北京地址:北京清华大学华业大厦三区三楼 版权所有:深圳万博计算机教育 粤ICP备11006947号-1
 
深圳信息系统项目管理师培训
深圳信息系统项目管理师培训 欢迎咨询!
您好!请点击这里咨询万博教育
深圳万博吴老师
您好!请点击这里咨询万博教育
深圳万博史老师
 
深圳信息系统项目管理师培训
深圳信息系统项目管理师培训