VBA--类模块学习
不废话,从基础开始学VBA的类模块。
主要分下⾯⼏个部分:
1.什么是类
2.为什么要学习类
3.类的预备知识
4.创建类属性
5.创建类⽅法
6.创建类事件
7.⼀个完整的类实例
8.未完的结尾
什么是类
在我们⾝边,相同或相似的物品⽆处不在,从⽣活⽤品,到⼯业产品,……通常它们都是由同⼀个可以称为“模具”的东西⽣产出来。
理解类,⼀般要先从对象谈起,但由于从不同的⾓度,有不同的理解,从⽽也有不同的关于类的定义,本⽂不去探讨⼀个完整并且公认的类概念,在这⼀部分后,只要你有⼀个基本的判断并且在遇到时知道是类就可以了。在上⾯的这个例⼦中,⼀个“模具”就是⼀个“类”,⽽由它⽣产出的每⼀个产品,就是⼀个“对象”。看下⾯的VBA语句:
Dim tx1 As Textbox
不⽤解释它的意思吧,这⾥我们⽤到⼀个类Textbox定义了⼀个对象tx1,再来看:
Dim tx1 As Textbox
Dim tx2 As Textbox
⼜定义了⼀个对象tx2,如果你不嫌烦,我还可以继续下去。对象增加了,但As后的Textbox没有变,它可以⽆限制的使⽤下去。
类是⼀个隐者,上⾯Textbox是VBA已经给我们准备好的⼀个类,我们⽆法知道VBA是怎么准备的(它的真⾝被隐藏了),但我们可以知道对象tx1怎么⽤。VBA把对对象的使⽤划分为三种,属性、⽅法和事件(后⾯预备知识我们再提)。
然⽽,Textbox是⼀个类,仍然不是本⽂要说的类,因为它是VBA已经给我们准备好了的,我们要做的,只是知道如何使⽤它⽽已。本⽂要介绍的,是利⽤VBA已经给我们提供的资源,来构建我们⾃⼰的类,姑且可称之为⾃定义类。这需要在VBE下,通过插⼊类模块,然后向类模块中写⼊代码来完成。这就是你常常听说的类,本⽂的主题就是这个包含代码的模块!通过这个模块,可以提供给我们⼀个和VBA 提供给我们的诸如Textbox功能性质完全相同的类,然后,再由我们⾃⼰象使⽤Textbox⼀样使⽤!
类是⼀个隐者,她把⾃⼰藏在所有模块的最后,甚⾄在多数情况,她从不出场。现在,她挂着神秘的微笑,向你⾛来,你要拒绝吗?
为什么要学习类模块
类通常被认为是学习VBA的难点之⼀,之所以如此,因为相对于制造⼀个标准模块或⽤户窗体,我们可以到的类的学习资源少之⼜少,甚⾄很多VB的书籍也只有缪缪字语(在后⾯的预备知识,我们再提另⼀个重要的原因)。从技术⾓度上看,类的构建,不象窗
体,VBA的类也不象有些语⾔提供了可视的设计界⾯,感性上那样直接,隐者!她是不可视的设计,所有的构建都是通过在类模块中写代码来实现的。
1.学习是⼀种兴趣的追求
俗语云:学的千千万,⽤的有⼏何?⼜⽈:书到⽤时⽅恨少。
林语堂先⽣将做学问划分为三重境界,第⼆重说“为伊消得⼈憔悴,⾐带渐宽终不悔”,⼤多数朋友,包括本⼈,都不是专业程序员,学习程序只是⼀种兴趣和爱好,就好象有⼈喜欢修炼⽹游⼀样,对喜欢程序的⼈,不断地学习和提⾼,也是⼀种追求优秀的态度,并且乐意享受这个追求的过程。模块、控件、链接库和类构成软件⼯程开发的四⼤技术,⽽类技术是控件和链接库技术的基础,我们不得不学。
2.类有什么⽤
如你前⾯看到的我们使⽤Textbox类,类可以创建⼤量性质相近的对象,减轻我们的程序量,简洁代码并提⾼效率。
类定义后,在其它模块中使⽤时,我们就可以暂时忘记或不必考虑它内部复杂的细节,让我们变得轻松,VBA虽然不能真正封装类的形式,但在这⾥,我们可以封装它的概念。
这并不是类的全部好处,其它的,留着朋友们⽤的时候慢慢体会吧。
类挂着神秘的微笑,已经⾛到你的⼤门⼝,开门迎接她吧,你还等什么?
⼴义上讲,所有VBA的知识,包括语句、函数以及为我们提供的标准类甚⾄第三⽅的资源都可以在类中被使⽤。本⽂⽆法也不准备逐⼀探讨,这⾥只说⼀些最密切最基本的,但即使这样,笔者仍然不能把这些点的知识都写到,甚⾄因为对问题解释清晰或符合逻辑的需要,采⽤⾮规范的表述,对专门问题的全⾯理解,请读者注意参考有关标准帮助⽂档并加以甄别。
1.从构建者的⾓度理解对象
上⼀回我们提到,类被认为是VBA难点还有⼀个原因,这就是我们的思想!VBA提供了⼤量的现成的类,我们⼏乎不再需要去构建⾃⼰的类,这种结果,我们熟练地习惯了从使⽤者的⾓度去理解类—的实例:对象,包括它的属性、⽅法和事件。但是,现在你还要尝试做⼀个提供者,这和你作为使⽤者时的思考⽅法是完全不同的,甚⾄是⾰命性的。这种⾓⾊的转位是痛苦的,它需要你放弃你原本可以⾃豪地解释出对象以及它的属性、⽅法、事件的定义,它们原本是如此逻辑地被划分,如此清晰,但现在,类模块中的⼀切,彼此交织,你会发现它们都模糊了!是需要你忘掉所有固执的“招势”的时候了,当你⼼中⽆剑时,转位也就完成了,隐者变得清晰了,她是如此美丽。且慢,在你完全忘掉前,让我们最后再看⼀眼它们的样⼦,呵呵,如果你实在忘不掉,你就提醒⼀下⾃⼰构建者的⾝份吧。下
⾯是通常情况下关于对象、属性、⽅法、事件的基本表述,如果你以前没了解过,则应当些资料先认真地理解它们,然后再按照上⾯的提⽰去做。
对象是由类创建的⼀个实例,它是类的实体化。
对象的引⽤和操作被逻辑上划分为不重叠的三个部分:
属性是指对象的特性。以前⾯的Textbox为例,有长度,⾼度,框中显⽰的⽂字等等。
⽅法是指对象的某个操作。如让Textbox成为当前的焦点(即光标移动到它上⾯)。
事件是指对象对外部动作的响应。如我们⽤⿏标点击Textbox时,会产⽣⼀个Click事件,改变它的值,则产⽣⼀个Change事件
变量的作⽤域
变量因为声明的位置和⽅式不同,从⽽有不同的作⽤域。作⽤域是指变量在多⼤范围内能被代码识别。可以划分为过程级、模块级和全局变量。
过程级变量在过程中声明,这⾥过程指的是⼀个Sub或Function,也包括后⾯提到到属性过程。通常⽤
Dim或Static进⾏声明。Dim声明的变量,只在该过程执⾏时存在,过程结束,变量的值也就消失了。Static声明的变量称为静态变量,这个值在整个程序运⾏期间都存在。 模块级变量对整个模块的所有过程都有效,但对其它模块不可⽤。可以在模块顶部声明。声明模块级变量⽤Private关键字和直接使⽤Dim 没有区别。但推荐使⽤Private进⾏声明,因为这样可以⽅便地与后⾯的全局变量区分开来。
全局变量是对整个VBA⼯程的所有过程都有效的变量,使⽤Public关键字在标准模块的顶部来声明。
在类模块中,对变量作⽤域的理解要注意下⾯两点:
(a)由于类是⽣成对象的模具,每⽣成⼀个对象,相当于产⽣了⼀个副本,这个副本就是对象的“真⾝”,副本间是相互独⽴的,从⽽,模块级的变量只作⽤于副本⾃⾝。
(b)类模块中使⽤Public关键字,只有当对象变量是这个类的实例时,才能被访问。
过程和函数vba自学好学吗
变量、过程(Sub)、函数(Function)是我们在标准模块中使⽤的最基本的构件,在类摸块中,它们仍然是最基本和重要的⾓⾊。对于它们,你已经再熟悉不过,之所以前⾯还要花这么多⽂字,是为了突出它的重要,也是想让你放松⼀下,哦,我花了很短的时间已经看了这么多(我也写了这么多!)。
过程和函数并⽆实质的区别,当需要返回值时,就使⽤Function,如果不需要返回任何结果,随你的爱好,但这时推荐你使⽤Sub,因为这样更符合微软的本意。过程(Sub)、函数(Function)也有作⽤域,在标准模块中通过使⽤Private和Public关键字(可以省略Public关键字,因为它是默认的),可以划分为模块级和全局级,以决定它是在当前的模块有效还是整个⼯程有效。
集合Collection
Collection是我们在使⽤类时最常⽤到的对象。⼀个Collection对象代表⼀组相关的项⽬,虽然它的成员并不被强制要求是同⼀类型的的,但请记住,这通常并不能给我们带来额外的⽅便,相反,我们通常是⽤来收集同⼀类型的数据。
建⽴集合的⽅法和建⽴其它对象⼀样,如:
Dim col As New Collection
集合建⽴后,可以使⽤Add⽅法添加成员,⽤Remove⽅法删除成员,⽤Item⽅法从集合中返回特定成员。
Private Sub CommandButton1_Click()
Dim col As New Collection
Dim i%
Dim ct As Control
For Each ct In Me.Controls
If Left(ct.Name, 7) = "TextBox" Then col.Add ct
Next ct
For i = col.Count To 1 Step -1
MsgBox "下⾯删除成员" & col.Item(i).Name
col.Remove i
Next i
End Sub
上⾯的代码先将窗体上所有的TextBox加⼊到集合中,然后再删除掉。Count属性返回集合的成员数量,
Remove⽅法后⾯的参数是集合成员的索引号。成员的索引号通常是按照加⼊的顺序⾃然编号,从1开始,但可以在加⼊时使⽤Add⽅法的参数进⾏改变。Add⽅法的完整语法是:
object.Add item[, key][, before][, after]
item 必需的。任意类型的表达式,指定要添加到集合中的成员。
key 可选的。唯⼀字符串表达式,指定可以使⽤的键字符串,代替位置索引来访问集合中的成员。
before/after 可选的。表达式,指定集合中的相对位置。
下⾯语句向集合增加⼀个对象TextBox1,并定义该成员的关键字为tx1。
col.Add TextBox1, "tx1"
然后,下⾯两句都可以向集合中增加⼀个TextBox2,并把它放在成员TextBox1的前⾯。
col.Add TextBox2, , col.Count
col.Add TextBox2, , "tx1"
第⼀句中,因为只有⼀个成员,所以col.Count也是索引号
使⽤事件的WithEvents变量
WithEvents不是⼀个单独的语句,为了使⽤对象的事件,需要在声明该对象时使⽤WithEvents关键字。例如:
Dim WithEvents app As Application
将上⾯的语句写⼊ThisWorkBook的模块,可以看到在通⽤框中出现了⼀个变量app:
此主题相关图⽚如下:
在通⽤框选择app后,左边的声明框便会显⽰app的事件。
此主题相关图⽚如下:
需要注意的是,使⽤WithEvents只是声明了对象变量,⽽并不实际⽣成对象,为了⽣成真实的对象,你仍然需要在声明后向⽣成其它对象⼀样,使⽤Set语句进⾏指定。此外,WithEvents变量不能是通⽤类变量如Object,⽽必须指定类名,也不能把WithEvents变量声明为As New。不能在标准模块中使⽤WithEvents.
初识类模块
现在,请打开你的VBE,主菜单-插⼊-类模块。
插⼊了⼀个类模块,也就建⽴了⼀个类。类模块的名字就是类的名字。你现在看到的,她的名字叫“类1”,这是VBA按她妹排⾏给她取的的,是的,VBA⼀贯如此,你早就熟悉了这种规则,现在,在标准模块或其它模块中输⼊Dim …As的时候,提⽰框中她已经出现了。但我知道,有件事你正耿耿于怀,“类1”,太没个性了,想改成⾃⼰要的名字吧。很容易,和你改标准模块的名字⼀样,打开属性窗⼝,看到了吧,第⼀⾏就是她的名字,随你的意愿修改吧。
此主题相关图⽚如下:
你或许已经注意到,在名字下⾯,只有⼀个属性:Instancing,其值也只有两个选项:Private和PublicNotCreatable。事实上,你完全可以忽略这个Instancing,就象你完全忽略条件编译指令⼀样,因为在VBA中我们⼏乎⽤不到它们,⽽只需维持她的默认值即可。⾄少我是这样认为的,但我给不了您充⾜的理由,⽽只是个⼈的⼀种狭隘经历。既然提到了,就简单说明⼀下:
Instancing属性决定该“类”在其它⼯程中是否可以被使⽤。我们知道,标准模块中的Public过程,可以保存在宏⼯作簿甚⾄直接被另⼀⼯作簿的⼯程调⽤,但类中的代码是不可分割的整体,所以必须整体决定是否允许外⽤。当Instancing属性设为Private(默认)时,不允许其它⼯程访问。当设置为PublicNotCreatable时,只有在⾃⼰的⼯程创建了该类的对象时,其它⼯程才允许使⽤这个对象,注意,仅仅是在本⼯程中创建的对象,⽽不能⽤她在其它⼯程中创建对象。
隐者已经来到你的⾝边,透过薄薄的⾯纱,你似乎已看到她神秘的微笑。站起⾝来,⾛过去吧
让我们想⼀下作为类的使⽤者时,我们是如何操作对象的属性的,对象属性的操作不外乎读和写两种。当我们要给对象的某个属性赋值时,我们会:
TextBox1.Text=”abc”
当我们要读取对象的属性时,
S= TextBox1.Text
现在,看看作为类的提供者需要怎样做。
我们将“类1”改名为“MyClass”并为它创建⼀个名称为x的字符型属性。
1.使⽤Public变量创建类属性
在类模块中写下⾏代码:
Public x$
是的,就这么简单,通常情况下,只需要这么简单
使⽤Property过程创建类属性
Private s$
Public Property Get x() As String
x = s
End Property
Public Property Let x(ByVal c As String)
s = c
End Property
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论