MS Access VBAで発生していないイベント
-
03-10-2019 - |
質問
MS Accessに画像があるフォームがあります。画像には、モーダルフォームを開くクリックイベントがあります。モーダルフォームにはOKとキャンセルボタンがあります。 [OK]ボタンをクリックすると、メインフォームにクリックされたボタンを指示するイベントが発生するはずです。 (これは、C#のDialogResult機能をシミュレートするためです)。ただし、イベントハンドラーのコードは実行されません。
モーダルフォームには、一般宣言には次のとおりです。
Public Event OnDialogBoxClose(NewRecordID As Long, DialogResult As DialogResults)
OK]ボタンがクリックされる次のコード:
RaiseEvent OnDialogBoxClose(NewHardwareBaseItemID, dlgresBtnOKClicked)
メインフォームには、一般宣言に次のものがあります。
Dim WithEvents RespondQuickAddClose As Form_qckfrmHardwareBaseItemCreate
そして、次のイベントハンドラー:
Private Sub RespondQuickAddClose_OnDialogBoxClose(NewRecordID As Long, DialogResult As DialogResults)
MsgBox "Responding to closing of the dialog box" 'Never happens
Me.Requery
End Sub
イベントハンドラーが呼び出されない理由を誰かが説明できますか?ありがとう!
バックグラウンド:
これのすべての目的は、モーダルダイアログボックスがエントリを追加できるようにし、エントリのIDをメインフォームに戻してコントロールの値を設定することです。たとえば、保険フォームに記入していると想像してください。これがありません。これはありません。自動車ブランドを追加できるように、モーダルダイアログボックスにポップアップするアイコンをクリックします。次に、[OK]をクリックすると、保険フォームに戻り、作成したばかりの車のブランドを選択します。
これは私がここで見つけた例に従います:http://database.itags.org/ms-access-database/80292/
解決
別の開発環境から概念を適用してVBAにアクセスすることで、あなたの人生を複雑にしています。 VBAはEvents/Raiseeventをサポートしていますが、ここでそれを複雑にする理由はありません。
アクセスでダイアログを使用する通常の方法は、それらを閉じる代わりにそれらを隠すことです。これにより、フォームが開かれた後にコードが実行され、そのコードで使用可能なフォームの値を残しておくことができます。
レポートを収集するためのフォームを開くレポートのオープンイベントのサンプルコード:
Private Sub Report_Open(Cancel As Integer)
DoCmd.OpenForm "dlgDateRange", , , , , acDialog, "ThisYear"
If IsLoaded("dlgDateRange") Then
With Forms!dlgDateRange
If .Tag = "Cancel" Then
Cancel = True
Else
Me.Filter = "[InvoiceDate] Between #" & !txtStart & "# AND #" & !txtEnd & "#"
Me.FilterOn = True
Me!lblDateRange.Caption = StrConv(Trim(("from " + varZLStoNull(Format(!txtStart, "mm/dd/yyyy"))) _
& (" to " + varZLStoNull(Format(!txtEnd, "mm/dd/yyyy")))), vbProperCase)
End If
End With
DoCmd.Close acForm, "dlgDateRange"
End If
End Sub
ダイアログフォームには2つのコマンドボタンがあり、>>を続行し、キャンセルします。キャンセルボタンは、フォームのタグを「キャンセル」に設定し、フォームのVisibleプロパティをfalseに設定します。継続>>ボタンは、フォームのVisibleプロパティをFalseに設定する以外に何もしません。これらのボタンのいずれかをクリックすると、AcDialogスイッチでフォームが開いた後、コードがラインで続行できます。
私の哲学は、対話を可能な限り愚かにすることです。呼び出しコードは、フォームで探しているものを知る必要があります(つまり、データを読んでいるコントロールの名前を知る必要があります)が、フォームに顧客プロパティを追加することでそれを達成することができます。しかし、その後、あなたはプロパティ名を知る必要があるので、あなたはちょうどボールを動かしました。
また、クラスモジュールにdailogフォームをラッピングすることでこの種のことを実装しました。次に、呼び出しコンテキストはクラスのインスタンスを初期化して、適切な時期に値を引き出すだけです。しかし、それは実際には上記のアプローチがより複雑です。
他のヒント
まあ私は同意しません
「VBAはEvents/Raiseeventをサポートしていますが、ここでそれを複雑にする理由はありません。」
私はさまざまなVB6およびVBAプロジェクトに取り組んできました。最近、ExcelでVBAをコードし、Winformからイベントを提起しました。そうする際に考慮すべきことはほとんどありません。
- withevents/raiseeventを使用してVBAで非モーダルWinformを呼び出している場合。予想通りに正常に機能するはずです。主要な回避策は必要ありません
- VBAでModal Winformを呼び出している場合。 withevents/raiseeventsは、要件に従って機能しない場合があります。簡単な回避策は、モジュールファイルで宣言されたパブリック変数を使用してデータを転送することです。
回避策を使用する必要があり、私はそれが絶対にうまくいくと思います。