ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 8872|回复: 7

[转帖] VBA类模块完全教程(中篇)

[复制链接]

TA的精华主题

TA的得分主题

发表于 2013-5-15 15:24 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:类和类模块
  广义上讲,所有VBA的知识,包括语句、函数以及为我们提供的标准类甚至第三方的资源都可以在类中被使用。本文无法也不准备逐一探讨,这里只说一些最密切最基本的,但即使这样,笔者仍然不能把这些点的知识都写到,甚至因为对问题解释清晰或符合逻辑的需要,采用非规范的表述,对专门问题的全面理解,请读者注意参考有关标准帮助文档并加以甄别。
1.从构建者的角度理解对象
      上一回我们提到,类被认为是VBA难点还有一个原因,这就是我们的思想!VBA提供了大量的现成的类,我们几乎不再需要去构建自己的类,这种结果,我们熟练地习惯了从使用者的角度去理解类—的实例:对象,包括它的属性、方法和事件。但是,现在你还要尝试做一个提供者,这和你作为使用者时的思考方法是完全不同的,甚至是革命性的。这种角色的转位是痛苦的,它需要你放弃你原本可以自豪地解释出对象以及它的属性、方法、事件的定义,它们原本是如此逻辑地被划分,如此清晰,但现在,类模块中的一切,彼此交织,你会发现它们都模糊了!是需要你忘掉所有固执的“招势”的时候了,当你心中无剑时,转位也就完成了,隐者变得清晰了,她是如此美丽。且慢,在你完全忘掉前,让我们最后再看一眼它们的样子,呵呵,如果你实在忘不掉,你就提醒一下自己构建者的身份吧。下面是通常情况下关于对象、属性、方法、事件的基本表述,如果你以前没了解过,则应当找些资料先认真地理解它们,然后再按照上面的提示去做。

      对象是由类创建的一个实例,它是类的实体化。

      对象的引用和操作被逻辑上划分为不重叠的三个部分:
属性是指对象的特性。以前面的Textbox为例,有长度,高度,框中显示的文字等等。
方法是指对象的某个操作。如让Textbox成为当前的焦点(即光标移动到它上面)。
事件是指对象对外部动作的响应。如我们用鼠标点击Textbox时,会产生一个Click事件,改变它的值,则产生一个Change事件

变量的作用域
      变量因为声明的位置和方式不同,从而有不同的作用域。作用域是指变量在多大范围内能被代码识别。可以划分为过程级、模块级和全局变量。
过程级变量在过程中声明,这里过程指的是一个Sub或Function,也包括后面提到到属性过程。通常用Dim或Static进行声明。Dim声明的变量,只在该过程执行时存在,过程结束,变量的值也就消失了。Static声明的变量称为静态变量,这个值在整个程序运行期间都存在。
模块级变量对整个模块的所有过程都有效,但对其它模块不可用。可以在模块顶部声明。声明模块级变量用Private关键字和直接使用Dim没有区别。但推荐使用Private进行声明,因为这样可以方便地与后面的全局变量区分开来。

      全局变量是对整个VBA工程的所有过程都有效的变量,使用Public关键字在标准模块的顶部来声明。

在类模块中,对变量作用域的理解要注意下面两点:
(a)由于类是生成对象的模具,每生成一个对象,相当于产生了一个副本,这个副本就是对象的“真身”,副本间是相互独立的,从而,模块级的变量只作用于副本自身。
(b)类模块中使用Public关键字,只有当对象变量是这个类的实例时,才能被访问。

        过程和函数
      变量、过程(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时,只有在自己的工程创建了该类的对象时,其它工程才允许使用这个对象,注意,仅仅是在本工程中创建的对象,而不能用她在其它工程中创建对象。

      隐者已经来到你的身边,透过薄薄的面纱,你似乎已看到她神秘的微笑。站起身来,走过去吧

TA的精华主题

TA的得分主题

发表于 2013-5-15 16:27 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
对类理解很模糊,占位学习,希望楼主持续更新
好人一生平安

TA的精华主题

TA的得分主题

发表于 2013-5-15 17:01 | 显示全部楼层
头像被屏蔽

TA的精华主题

TA的得分主题

发表于 2013-5-19 13:35 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2013-7-21 20:47 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2014-2-18 22:30 | 显示全部楼层
对我来说, 类模块很模糊, 很遥远, 但是有好想学习 。。。。

TA的精华主题

TA的得分主题

发表于 2021-2-2 22:18 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2021-2-2 22:18 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-12-4 03:09 , Processed in 0.079066 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表