暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

自定义类事件

VBA语言専攻 2021-07-06
133
【分享成果,随喜正能量】命,是失败者的借口;运,是成功者的谦词。失败者说,命不好,心里却后悔,当初没尽力;成功者说,是命好,心里却清楚,付出的代价。命运,不是什么神秘的力量,而是自我的花开出的果。你如何选择,命运就如何发生。想要知道费了多少心,只需看树上挂了多少果实。人生,越努力,越幸运。
《VBA中类的解读及应用》教程是我推出第五套教程,目前已经是第一版修订了。这套教程定位于最高级,是学完初级,中级后的教程。
类,是非常抽象的,更具研究的价值。随着我们学习、应用VBA的深入,有必要理解这些抽象的理论知识。对象,类,过程,方法,属性,事件,接口,接口如何实现等等。掌握了这些理论,不仅对于VBA这种寄生语言的实质有所深入的理解,也对自然界的很多事物将同样有所感悟。目前,这套教程程序文件已经通过32位,64位两种office系统测试。
这套教程共两册,八十四讲,今后一段时间会给大家陆续推出修订后的教程内容。今日的内容是第8讲:自定义类事件。

第八讲  用户自定义类事件

大家好,到上一讲,我们学习了有关类的定义部分,涉及到的概念较多,需要大家仔细地理解。我们今日这讲,讲用户自定义事件。
我们建立了类,通过对象把类进行了实例化,把灵魂具体到了肉身,下面我们就要让这个实例的对象参与各种事件了,由于类是我们自己进行的定义,那么实例对象要参与的事件也是能自己定义的。

1  用户如何自定义事件

定义用户自定义的事件的语法:
[Public] Event procedurename [(arglist)]
上述参数中:
1)  Public 可选的。指定该 Event 在整个工程中都是可见的。缺省情况下 Events 类型是 Public。应注意,事件只能在所声明的模块中产生。
2)  procedurename 必需的。事件的名称;建议大家遵循标准的变量命名约定,但我们也可以自己加入自己的部分习惯。
3)  arglist 参数的语法及语法的各个部分如下:[ByVal | ByRef] varname[( )] [As type]
其中:
① ByVal 可选的。表示该参数是按值传递的;
② ByRef 可选的。表示该参数是按地址传递的。ByRef 是缺省设置。
③ varname 必需的。代表要传递给过程的参数变量的名称;遵循标准的变量命名约定。
④ type 可选的。指传递给过程的参数的数据类型;可以是 Byte、布尔、Integer、Long、Currency、Single、Double、Decimal(目前尚不支持)、Date、String(只支持变长)、Object、Variant、用户定义类型或对象类型。

u说明:
1) 事件被声明之后,就可以使用RaiseEvent 语句来产生该事件。
2) 声明事件只能在类模块中声明,如果在标准模块中出现 Event 声明,就会产生语法错误。这也好理解,事件是对产生对象进行的声明,对象是由类产生的。
3) 不能声明带返回值的事件。在下面的代码段中,给出了声明事件和产生事件的典型事件:
如下语句:在类模块的模块级中声明一个事件,及触发一个事件:
Public Event UpdateTime(ByVal mynow As Double)
RaiseEvent UpdateTime(Timer - myStart)

l注意 可以象声明过程的参数一样来声明事件的参数,但有以下不同:事件不能有带命名参数、Optional参数、或者 ParamArray 参数。事件没有返回值。

产生事件的类是事件源,实现该事件的类则是事件吸收。一个事件源可以有多个针对其所产生的事件的类。事件可以被每个选定出为对象的实例吸收事件的类所触发。

2  实现定时器功能的自定义类事件代码实例讲解

实例:下面的示例实现一个定时器功能。代码实现了所有与事件相关的方法、属性和语句,包括Event 语句。该示例使用一个窗体,该窗体有两个按钮,以及两个文本框。单击按钮后,第一个文本框显示提示内容,第二个文本框中时钟开始计时。

建立一个类,命名为mytime
Option Explicit
Public Event UpdateTime(ByVal mynow As Double)
Public Event dabiao()
Public Sub TimerTask(ByVal biaozhun As Double)
    Dim myStart As Double
    Dim mySecond As Double
    Dim myFar As Double
    myStart = Timer
    myFar = myStart
    Do While Timer < myStart + biaozhun
        If Timer - myFar >= 1 Then
            myFar = myFar + 1
            RaiseEvent UpdateTime(Timer - myStart)
        End If
    Loop
    RaiseEvent dabiao
    Do While Timer >= myStart + biaozhun
        If Timer - myFar >= 1 Then
            myFar = myFar + 1
            RaiseEvent UpdateTime(Timer - myStart)
        End If
    Loop
End Sub

建立一个窗体:
Option Explicit
Private WithEvents mText As mytime

Private Sub CommandButton1_Click()
    TextBox1.Text = "开始计时:"
    TextBox2.Text = "0"
    mText.TimerTask (9)
End Sub

Private Sub CommandButton2_Click()
    End
End Sub

Private Sub mText_dabiao()
    TextBox1.Text = "已经达到标准"
    DoEvents
End Sub

Private Sub mText_UpdateTime(ByVal mynow As Double)
    TextBox2.Text = Str(Format(mynow, "0"))
    DoEvents
End Sub

Private Sub UserForm_Initialize()
    TextBox1.Text = ""
    TextBox2.Text = ""
    Set mText = New mytime
End Sub

Private Sub UserForm_Terminate()
    End
End Sub

代码的运行过程及解释:
1) 在窗体的构建过程中TextBox1.Text = "";TextBox2.Text = "";Set mText = New mytime;这里mytime 是一个类,Set mText = New mytime就是将mText实例了一个新的mytime的类。

2)  我们点击“开始按钮”,这个时候TextBox1.Text = "开始计时:",然后在第二个文本框中显示计时的开始为0, TextBox2.Text = "0",然后执行类的TimerTask过程,(什么是过程呢?其实就是方法、函数、事件的总称).此处的过程指的是方法,会传递一个参数9,mText.TimerTask (9)。

3)  我们看看上述类的过程是如何执行的. mText.TimerTask (9)

Public Sub TimerTask(ByVal biaozhun As Double)
    Dim myStart As Double
    Dim mySecond As Double
    Dim myFar As Double
    myStart = Timer
    myFar = myStart
    Do While Timer < myStart + biaozhun
        If Timer - myFar >= 1 Then
            myFar = myFar + 1
            RaiseEvent UpdateTime(Timer - myStart)
        End If
    Loop
    RaiseEvent dabiao
    Do While Timer >= myStart + biaozhun
        If Timer - myFar >= 1 Then
            myFar = myFar + 1
            RaiseEvent UpdateTime(Timer - myStart)
        End If
    Loop
End Sub
上面的过程中先定义了几个变量,然后将执行一个循环,循环执行到RaiseEvent UpdateTime(Timer - myStart)会触发事件UpdateTime(Timer - myStart).

4)  关于UpdateTime(Timer - myStart)事件.这个事件是在类模块中Public Event UpdateTime(ByVal mynow As Double)进行声明的相应的是myclass事件,我们回到窗体的代码,看看这个事件的过程。
Private Sub mText_UpdateTime(ByVal mynow As Double)
   TextBox2.Text = Str(Format(mynow, "0"))
   DoEvents
End Sub
这个事件就是在textbox2的文本框中显示一个值,这个值是TimerTask传递过来的.显示值后,会DoEvents。交出程序的控制权,也就是说程序会向下进行。

5)  程序向下进行仍是执行的是第一个循环语句。

6)  当第一个循环语句结束时,会执行RaiseEvent dabiao,会触发dabiao事件,这个事件同样也是在类模块中声明的Public Event dabiao(),是mText的事件。仍是回到窗体代码看看这个事件过程:
Private Sub mText_dabiao()
  TextBox1.Text = "已经达到标准"
   DoEvents
End Sub
这个时间在文本框中显示已经达到标准。执行完后交出程序的控制权。

7) 程序执行完上面的代码后将向下执行第二个循环。这个循环和上面第一个循环类似。

好,我们看看程序的运行:


当点击结束,程序将停止运行。

今日内容回向:
1  如何利用一个类的方法?
2  方法、事件的区别是什么?
本讲内容参考程序文件:VBA-CLASS(1-28).xlsm


我20多年的VBA实践经验,全部浓缩在下面的各个教程中,教程学习顺序
① 7→1→3→2→6→5或者7→4→3→2→6→5。
② 7→8
各套教程内容简介:

第7套教程(共三册):《VBA之EXCEL应用》:是对VBA基本的讲解
第1套教程(共三册):《VBA代码解决方案》是入门后的提高教程
第4套教程(16G):VBA代码解决方案之视频(第一套的视频讲解)
第3套教程(共两册):《VBA数组与字典解决方案》:是对数组和字典的专题讲解
第2套教程(共两册):《VBA数据库解决方案》:是对数据库的专题讲解
第6套教程(共两册):《VBA信息获取与处理》:讲解VBA的网络及跨程序应用
第5套教程(共两册):VBA中类的解读和利用:类及接口技术的讲解
第8套教程(共三册):VBA之Word应用(最新教程):word中VBA的利用



文章转载自VBA语言専攻,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论