VBA:WithEvents拼图

时间:2011-03-23 13:52:14

标签: excel events vba excel-vba userform

我有一个UserForm, xForm ,它正在类模块中实例化(假设 TestClass ):

'TestClass
Dim Form as New xForm
Private WithEvents EvForm as MSForms.UserForm
Set EvForm = Form

在xForm本身的类模块中,我有一些必须在Form Closing上执行的代码,只有在表单实际关闭时才会执行:

'xForm class module
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    'Do some cleanup, otherwise the app would hang
    'If not closing, don't cleanup anything, otherwise the app would hang
End Sub

QueryClose事件也在TestClass中处理,可以避免表单关闭:

'TestClass
Private Sub EvForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    'Verify if closing is allowed based on User Control values
    Cancel = Not ClosingIsAllowed '<-- Pseudocode on the right side of "="
End Sub

如何在xForm类模块中测试TestClass中的Cancel = True? 让我们改一下:如果在TestClass中将Cancel设置为True,我不能在xForm类模块中执行清理代码。我怎么能做到这一点?

到目前为止,我已经考虑过在xForm类中实现另一个事件(My_QueryClose?)并在QueryClose事件上引发它。在表格背后的代码之外我只会处理My_QueryClose事件,因此可以完全控制正在发生的事情。这是一种可行/更好的方法吗?

2 个答案:

答案 0 :(得分:1)

不能对你的自定义事件的想法做出正面或反面,但让一个班级与另一个班级(形式或其他任何东西无关紧要)的方式是将它们联系起来;这是一个干净的例子:

Basic TestClass保存表单对象(此处不需要任何事件,让表单处理)

'TestClass code
Private MyForm          As UserForm
Private mbleCanClose    As Boolean

Public Property Get CanClose() As Boolean
    CanClose = mbleCanClose
End Property
Public Property Let CanClose(pbleCanClose As Boolean)
    mbleCanClose = pbleCanClose
End Property

Public Property Get MyFormProp() As UserForm1
    Set MyFormProp = MyForm
End Property

将自定义对象和属性添加到表单本身

'UserForm1 code
Private mParent As TestClass

Public Property Get Parent() As TestClass
    Set Parent = mParent
End Property
Public Property Set Parent(pParent As TestClass)
    Set mParent = pParent
End Property

在TestClass创建上调用表单如下所示:

'TestClass code
Private Sub Class_Initialize()
    Set MyForm = New UserForm1
    Load MyForm
    Set MyForm.Parent = Me
End Sub

然后在关闭表单的时候,你可以检查一下:

'UserForm1 code
Public Function WillMyParentLetMeClose() As Boolean
    If Not (mParent Is Nothing) Then
        WillMyParentLetMeClose = mParent.CanClose
    End If
End Function

Private Sub CommandButton1_Click()
    If WillMyParentLetMeClose = True Then
        Unload Me
    End If
End Sub

这是它想要调用的内容

'standard module code
Public Sub Test_TestClass()
    Dim myclass As TestClass
    Set myclass = New TestClass
    myclass.MyFormProp.Show
End Sub

答案 1 :(得分:1)

宣布另一项活动的工作

下面的代码做了我所期待的,虽然它不像我希望的那样整洁。

UserForm1 代码中:

'***** UserForm1
Public Event MyQueryClose(ByRef Cancel As Integer, ByRef CloseMode As Integer, ByRef Status As String)

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
   Dim Status As String
   Cancel = True
   Status = "QueryClose"
   Debug.Print "Entered QueryClose"
   Debug.Print "Cancel = " & Cancel
   Debug.Print "Status = " & Status
   Debug.Print "Just before raising MyQueryClose"
   RaiseEvent MyQueryClose(Cancel, CloseMode, Status)
   Debug.Print "Just got back from MyQueryClose"
   Debug.Print "Cancel = " & Cancel
   Debug.Print "Status = " & Status
End Sub

Class1 代码中:

'***** Class1
Dim UserForm As New UserForm1
Private WithEvents UF As UserForm1

Sub DoIt()
   Set UF = UserForm
   UserForm.Show
End Sub

Private Sub UF_MyQueryClose(Cancel As Integer, CloseMode As Integer, Status As String)
   Debug.Print "Just entered MyQueryClose"
   Cancel = False
   Status = "MY QueryClose"
End Sub

基本模块中,测试Class:

'***** Basic module
Sub TestClass()
   Dim C As New Class1
   C.DoIt
End Sub

这是最终结果(调试窗口):

TestClass
Entered QueryClose
Cancel = -1
Status = QueryClose
Just before raising MyQueryClose
Just entered MyQueryClose
Just got back from MyQueryClose
Cancel = 0
Status = MY QueryClose