ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享] 类模块教程及实例

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2020-3-24 14:47 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:类和类模块
类模块教程及实例
使用类模块可以创建自定义的类,使用此类作为模板创建对象。
类模块包含一系列的属性,方法和事件,用来和其他对象或创建对象的代码交互。
· 属性
  有两类属性,第一类为Public类型的模块级变量,第二类为Property过程。
  · 模块级变量
    例:
    Public ProductId As Long
    使用这种方法定义的属性不能返回数组,定长字符串,常量或用户自定义类型。
  ·Property过程
    Property Let:用来设置属性值的过程
    Property Get:用来返回属性值的过程
    Property Set:用来设置对象引用的过程
    声明Property过程的语法:
    [Public | Private] [Static] Property { Get| Let | Set } propertyname [(arguments)] [As type]
        statements
    End Property
    在Property过程声明中所需要的参数为:
      Property Get propname(1, ..., n) As Type
      Property Let propname(1, ..., n, n+1)
      Property Set propname(1, ..., n, n+1)
    在具有相同名称的Property过程中,从第一个到最后一个参数(1, ..., n)都必须共享相同的名称与数据类型。
    其中Property Get过程的数据类型必须与相关的Let及Set声明中的最后(n+1)个参数的类型相同。
    ※在Property Set声明中,最后一个参数的数据类型必须是对象类型或Variant。
    例:
    Property Let Names(intX As Integer, varZ AsVariant)
        ' statement here.
    End Property
    Property Get Names(intX As Integer) AsVariant
        ' statement here.
    End Property
· 方法
  就是一个过程。
  定义为Private的方法只可以在类内部使用。
· 事件
  使用Event语句定义事件。
  [Pubulic] Event eventname [(arglist)]
  事件只能在所声明的模块中产生。
  使用RaiseEvent语句产生事件。
  不能声明带返回值的事件。
  VBA定义了2个特殊的事件,Initialize和Terminate。
  ※在创建对象时使用WithEvents关键字来使用事件。
  ※Class_Initialize事件的代码在类被创建时执行,Class_Terminate事件的代码在类被销毁时执行。
RaiseEvent语句使用例子
下面的例子使用事件来模拟100米跑秒表计数器。
代码中,除了与事件有关的方法,属性,语句外,
还有RaiseEvent语句的记述。
下面的例子,除了类模块,还使用了Form模块(Form1)。
Form上,配置有命令按钮控件(Command1),标签控件(Label1)和2个文本框控件(Text1和Text2)。
点击命令按钮,第一个文本框中显示"开始",第二个文本框显示经过的秒数。
到达设定的最大秒数(9.84秒)后,第一个文本框中显示"终点",第二个文本框中显示经过的秒数"9.84"。
Form模块Form1中的代码。
包括开始和终了时刻执行的代码,事件发生时执行的代码。
OptionExplicit
PrivateWithEvents mText As TimerState
Private SubCommand1_Click()
     Text1.Text = "开始"
     Text1.Refresh
     Text2.Text = "0"
     Text2.Refresh     
Call mText.TimerTask(9.84)
End Sub
Private SubForm_Load()
     Command1.Caption = "点击开始"
     Text1.Text = ""
     Text2.Text = ""
     Label1.Caption = "经过的秒数:"
     Set mText = New TimerState
End Sub
Private SubmText_ChangeText()
    Text1.Text = "终点"
    Text2.Text = "9.84"
End Sub
Private SubmText_UpdateTime(ByVal dblJump As Double)
        Text2.Text = Str(Format(dblJump,"0"))
        DoEvents
End Sub
类模块TimerState中的代码。
OptionExplicit
Public EventUpdateTime(ByVal dblJump As Double)
Public EventChangeText()
Public SubTimerTask(ByVal Duration As Double)
    Dim dblStart As Double
    Dim dblSecond As Double
    Dim dblSoFar As Double
    dblStart = Timer
    dblSoFar = dblStart
    Do While Timer < dblStart + Duration
        If Timer - dblSoFar >= 1 Then
            dblSoFar = dblSoFar + 1
            RaiseEvent UpdateTime(Timer -dblStart)
        End If
    Loop
    RaiseEvent ChangeText
End Sub
响应Application事件
可以在类模块和用户窗体中使用Application事件。
例:
(1)新建frmEventForm窗体,添加一个lstEvent的ListBox,添加如下代码。
  Public WithEvents appEvent As Application
  Private Sub appEvent_NewWorkbook(ByVal Wb AsWorkbook)
      Me.lstEvent.AddItem "Newworkbook"
  End Sub
  Private Sub appEvent_SheetActivate(ByVal ShAs Object)
      Me.lstEvent.AddItem " Activate" & Sh.Name
  End Sub
(2)新建过程,输入如下代码
  Dim frm As New frmEventForm
  Set frm.appEvent = Application
  frm.Show vbModeless
Application对象事件的使用
为了使用Application的事件,
要生成类模块,在类模块中声明事件型的Application对象。
例如,生成EventClassModule类模块。
将下面的代码加入类模块中。
PublicWithEvents App As Application
声明包含事件的对象后,类模块的“对象”一览框中可以看到此对象,
就可以写此对象的的事件处理过程了。
([对象]栏中,选择事件对象,对象的有效事件会表示在处理过程一览框中)
但是,事件处理代码执行前,声明使用事件处理类的代码中,
需要将类中的对象变量与Application对象进行关联。
例:
Dim X As NewEventClassModule
SubInitializeApp()
    Set X.App = Application
End Sub
InitializeApp过程中,
类模块(EventClassModule)中的App与MicrosoftExcelApplication对象关联,
Application对象事件发生后,
类模块(EventClassModule)中对应的事件处理过程被执行。
嵌入图形中事件的使用
缺省的设置中,可以使用嵌入图形的事件。
为了使用表示嵌入图形的Chart对象的事件,
要生成新的类模块,声明事件型的Chart对象。
例如,生成"EventClassModule"类模块,写入下面的代码。
PublicWithEvents myChartClass As Chart
声明包含事件的对象后,类模块的“对象”一览框中可以看到此对象,
就可以写此对象的的事件处理过程了。
([对象]栏中,选择事件对象,对象的有效事件会表示在处理过程一览框中)
但是,事件处理代码执行前,声明使用事件处理类的代码中,
需要将类中的对象变量与嵌入图形对象进行关联。
DimmyClassModule As New EventClassModule
SubInitializeChart()
    Set myClassModule.myChartClass = _
        Charts(1).ChartObjects(1).Chart
End Sub
InitializeChart过程中,类模块(EventClassModule)中的myChartClass与图表1中的图1对象关联,
这个图表对象事件发生后,
类模块(EventClassModule)中对应的事件处理过程被执行。
QueryTable对象事件的使用
为了使用QueryTable的事件,
要生成类模块,在类模块中声明事件型的QueryTable对象。
例如,生成ClsModQT类模块。
将下面的代码加入类模块中。
PublicWithEvents qtQueryTable As QueryTable
声明包含事件的对象后,类模块的“对象”一览框中可以看到此对象,
就可以写此对象的的事件处理过程了。
([对象]栏中,选择事件对象,对象的有效事件会表示在处理过程一览框中)
事件处理代码执行前,
需要将类中的对象变量与QueryTable对象进行关联。
类模块中
SubInitQueryEvent(QT as Object)
        Set qtQueryTable = QT
End Sub
‘代码中
DimclsQueryTable as New ClsModQT
SubRunInitQTEvent()
        clsQueryTable.InitQueryEvent _
            QT:=ActiveSheet.QueryTables(1)
End Sub
RunInitQTEvent过程中,
类模块(ClsModQT)中的qtQueryTable与ActiveSheet.QueryTables(1)对象关联,
此对象事件发生后,
类模块(ClsModQT)中对应的事件处理过程被执行。

评分

6

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-3-24 15:40 | 显示全部楼层
类模块响应控件组1
Dim Col AsNew Collection '集合
Private SubUserForm_Initialize() '窗体初始化
    Dim I As Integer: Dim Myc As cmds '类名称,声明对象
    For I = 1 To 3
        Set Myc = New cmds '类名称,指定对象
        Set Myc.Cmd =Me.Controls("TextBox" & I)
        Col.Add Myc '添加集合
    Next: Set Myc = Nothing
End Sub
'第1行代码在模块顶部声明变量col的类型为集合?
'第5行到第9行代码,将窗体中的三个文本框赋给col集合。
'类模块中的代码
PublicWithEvents cmd As MSForms.TextBox'声明对象
Private SubCmd_Change()
    Dim I As Integer: Dim Dval As Double'和
    For I = 1 To 3
        和 = 和 +Val(UserForm1.Controls("TextBox" & I))
        UserForm1.TextBox4.Value = 和
    Next
End Sub
'代码解析:窗体中的3个文本框统一的Change事件,
'当任何一个文本框中的数据发生变化时,
'所有文本框相加的合计数显示在最后一个文本框中。
'使用Public语句声明变量cmd
'是用来响应由TextBox对象触发的事件的对象变量
'窗体中的3个文本框统一的Change事件,当任何一个文本框中的数据发生变化时,所有文本框相加的合计数显示在最后一个文本框中。
类模块响应控件组2
Dim Col AsNew Collection '集合
Private SubUserForm_Initialize() '窗体初始化
    Dim I As Integer: Dim Myc As cmds '类名称,声明对象
    For I = 1 To 5
        Set Myc = New cmds '类名称,指定对象
        Set Myc.Cmd =Me.Controls("Label" & I)
        Col.Add Myc '添加集合
    Next: Set Myc = Nothing
End Sub
'第1行代码在模块顶部声明变量col的类型为集合?
'第5行到第9行代码,将窗体中的三个文本框赋给col集合。
'类模块中的代码
PublicWithEvents Cmd As MSForms.Label '声明对象
Private SubCmd_Click()  '控件的Click事件
    ID = Mid(Cmd.Name, 6, 2): LH = Cmd.Name
    UserForm1.T1.Value = LH
End Sub
类模块给控件组赋值
OptionExplicit’ VBA中的类3.xls
Dim LO As NewCollection '集合
Private SubUserForm_Initialize()'窗体初始化
    Dim I 'Label对象不是源自动事件错
    Dim Lyc As Lmds '类名称Cmds,声明对象
    For I = 1 To 5 'CommandButton
        Set Lyc = New Lmds '指定对象
        Set Lyc.Lmd =Me.Controls("CommandButton" & I)
        LO.Add Lyc 'Lae:类对象
    Next I
    Set Lyc = Nothing
End Sub
‘类模块中的代码
OptionExplicit 'Label对象不是源自动事件错
PublicWithEvents Lmd As CommandButton '声明对象
Private SubLmd_Click() 'CommandButton
    UserForm1.TextBox2 = Lmd.Caption
End Sub
类模块查控件组名称
Private SubUserForm_Initialize()'窗体初始化
    Dim nCtr As MSForms.Label
    For I = 1 To 38 '标签控件
        Set nCtr = Controls("Label"& I)
        Set ctlLB(I) = New cLB '创建cLB类实例
        ctlLB(I).Init nCtr     '将控件赋给类实例
    Next I
End Sub
‘类模块中的代码
PrivateWithEvents m_LB As MSForms.Label '标签控件类
Public SubInit(cLB As MSForms.Label)
    Set m_LB = cLB '初始化,将控件绑定到类
End Sub
Private Subm_LB_Click() '控件的Click事件
    LH = m_LB.Caption: ID = Mid(m_LB.Name, 6,2)
End Sub
Private SubClass_Terminate()
    Set m_LB = Nothing '注销类
End Sub

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-3-25 12:03 | 显示全部楼层
类模块基本示例

类模块基本示例.rar

112.15 KB, 下载次数: 427

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-3-25 15:50 | 显示全部楼层
VBA类模块响应控件组-实例
类学习较难,资料较少,没有实例很难理解,希望通过以上6例,可以帮助到读者。

VBA类模块响应控件组.rar

32.89 KB, 下载次数: 340

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2020-3-25 17:20 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-3-26 10:37 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 !!!橄榄树 于 2020-3-26 11:20 编辑

    为什么要使用类,假设有100个控件,要显示某个控件内容或名称,因VBA没有控件组,通常是写100个点击事件,显示某个控件内容,烦琐不!使用VBA类就简单了,看上面的6个例子:
VBA类模块响应控件组A.xls的功能,鼠标移动至上面三个文本框中,下面文本框显示内容,
VBA类模块响应控件组 .xls的功能,鼠标点击右边标签控件,下面文本框显示标签名称。简单吧!

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-4-3 13:25 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

鼠标滚动文字框实例

行政区划批量生成及合法性验证2020.rar

261.64 KB, 下载次数: 371

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2020-4-4 19:41 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2020-5-27 06:53 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
鼠标滚动文字框实例好

TA的精华主题

TA的得分主题

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

本版积分规则

关闭

最新热点上一条 /1 下一条

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

GMT+8, 2024-4-25 23:50 , Processed in 0.046950 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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