0

画像のあるフォームがMSAccessにあります。画像には、モーダルフォームを開くClickイベントがあります。モーダルフォームには、[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/

4

2 に答える 2

3

別の開発環境の概念をAccessVBAに適用することで、生活が複雑になりすぎています。VBAはWithEvents/RaiseEventをサポートしていますが、ここでそれを複雑にする理由はありません。

Accessでダイアログを操作する通常の方法は、ダイアログを閉じる代わりに非表示にすることです。これにより、フォームを開いた後のコードを実行しながら、フォームの値をそのコードで使用できるようにします。

レポートをフィルタリングするための値を収集するためのフォームを開くレポートのOnOpenイベントのサンプルコード:

  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

ダイアログフォームには、CONTINUE>>とCANCELの2つのコマンドボタンがあります。CANCELボタンは、フォームのタグを「キャンセル」に設定し、フォームの.VisibleプロパティをFalseに設定します。CONTINUE >>ボタンは、フォームの.VisibleプロパティをFalseに設定するだけです。これらのボタンのいずれかをクリックすると、acDialogスイッチでフォームを開いた後、コードをその行に続けることができます。

私の哲学は、ダイアログをできるだけ愚かにすることです。呼び出し元のコードは、フォームで何を探しているかを知る必要があります(つまり、データを読み取るコントロールの名前を知る必要があります)が、フォームに顧客のプロパティを追加することで回避できます。ただし、プロパティ名を知っている必要があるため、ボールを移動しただけです。

また、クラスモジュールでdailogフォームをラップすることでこの種のことを実装しました。その後、呼び出し元のコンテキストは、クラスのインスタンスを初期化し、適切なタイミングでそのインスタンスから値を引き出します。しかし、それは実際には上記のアプローチよりも複雑です。

于 2010-09-16T23:47:17.117 に答える
0

まあ私は同意しません

「VBAはWithEvents/RaiseEventをサポートしていますが、ここでそれを複雑にする理由はありません。」

私はさまざまなVB6およびVBAプロジェクトに取り組んできました。最近、WinFormからイベントを発生させたExcelでVBAをコーディングしました。そうするときに考慮すべきことはほとんどありません。

  1. withevents/raiseeventを使用してVBAで非モーダルWinFormを呼び出している場合。期待どおりに正常に動作するはずです。大きな回避策は必要ありません
  2. VBAでモーダルwinformを呼び出している場合。Withevents / raiseeventsは、要件に従って機能しない場合があります。簡単な回避策は、モジュールファイルで宣言されたパブリック変数を使用してデータを転送することです。

あなたは回避策を使う必要があるでしょう、そして私はそれが絶対にうまくいくと信じています。

于 2016-11-09T11:39:18.990 に答える