3

クラスモジュール(たとえばTestClass)で次のようにインスタンス化されているUserForm、xFormがあります。

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

xForm自体のクラスモジュールには、フォームが実際に閉じた場合にのみ、フォームを閉じるときに実行する必要のあるコードがあります。

'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イベントのみを処理するため、何が起こっているかを完全に制御します。これは実行可能/より良いアプローチですか?

4

2 に答える 2

1

カスタムイベントのアイデアの先頭または末尾を作成することはできませんが、あるクラスを別のクラスと会話させる方法(形式やその他は関係ありません)は、それらをリンクすることです。これがきれいな例です:

基本的な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
于 2011-03-24T21:32:30.330 に答える
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

基本モジュールで、クラスをテストするには:

'***** 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
于 2011-03-25T12:57:37.487 に答える