5

Microsoft Access フォームでは、現在のレコードが変更されるたびに、バインドされたコントロールのすべての変更がサイレント モードでデータベース テーブルに保存されます。これは問題ありませんが、ユーザーがフォームを閉じたときに発生したくありません。これは、多くの人が期待することとは正反対であるためです。

最良の例は、変更が保存されていない Excel ファイルを閉じようとすると、変更を破棄するかどうかを尋ねられます。これはまさに私が Access で達成しようとしているものですが、VBA で閉じるボタンのイベントをトラップする方法が見つかりません。

フォームの Unload イベントは、誰かが閉じるボタンをクリックしたときにトリガーされる最初のイベントですが、それまでに、変更は既にデータベースに書き込まれています。

これはまったく可能ですか、それとも独自の閉じるボタンを作成する必要がありますか? このような些細なことのために大量のコードを書くことには慣れていますが、GUI を乱雑にするのは嫌いです。

4

6 に答える 6

7

Form_BeforeUpdateイベントで作業する必要があります。以下は例です。ただし、データベースの設定によっては、「現在、このレコードを保存できません。Microsoft Access は、レコードを保存しようとしているときにエラーが発生した可能性があります。...」という典型的な警告メッセージが作成されます。以下の簡単な回避策を使用して、そのメッセージが表示されないようにすることができます。

Private Sub Form_BeforeUpdate(Cancel As Integer)
   Cancel = True
   'Or even better you can check certain fields here (If Then...)

End Sub


Private Sub Form_Error(DataErr As Integer, Response As Integer)
    If DataErr = 2169 Then 
        Response = True
    End If
End Sub
于 2012-10-18T13:15:11.100 に答える
6

Sean はほぼ正しい答えを出しましたが、ギャップが残ります。

一般に、FORMBeforeUpdateは最も重要なフォーム イベントです。これはあなたの最後の防御線であり、保存を促したもの (フォームを閉じる、新しいレコード、独自の保存ボタン、サブフォームをクリックするなど) に関係なく、レコードが保存される前に常に実行されますBeforeUpdate。そのため、ユーザーはエラー メッセージをより早く受け取ることができ、私が記述した検証コードの大部分はForm_BeforeUpdateイベントで実行されます。これは、特定のコントロールが空でないことを確認する場合に使用する必要があるイベントです。すべての状況でこれを確実に実行する制御レベル イベントはありません。主な理由は、コントロールがフォーカスされない場合、コントロール レベル イベントが発生しないためです。 Form_BeforeUpdate検証に複数のフィールドが含まれる場合に使用するイベントでもあります。他のコントロールまたはイベント レベルのイベントを使用している場合は、時間を無駄にしています。「トラップ」の周りには常に離れており、テーブルにはほぼ確実に無効なデータが含まれています。

OPの質問について。人々に独自の保存ボタンを使用させ、そうでない場合はプロンプトを表示させたい場合は、ショーンの提案が暗示しているように、フォームレベル変数が必要です。唯一の違いは、Open イベントではなく、フォームの Current イベントで False に設定する必要があることです。フォームが開いたときだけでなく、新しいレコードごとにフラグをリセットする必要があります。次に、レコードを強制的に保存する直前に、保存ボタンのクリック イベントで True に設定しますDoCmd.RunCommand acCmdSaveRecord

最後に、Form_BeforeUpdateイベントで変数の値を確認します。

If bClose = False Then
   If MsgBox("Do you want to save the changes?", vbYesNo) = vbNo Then
       Cancel = True
       If MsgBox("Do you want to discard the Changes?", vbYesNo) = vbYes Then           
            Me.Undo
       End If
       Exit Sub
   End If
End If
于 2015-02-27T19:14:55.817 に答える
2

これは、フォームが閉じられているか保存されているかを確認するコードです。

Private Sub Form_BeforeUpdate(Cancel As Integer)

If Not UsingSaveButton Then
    If MsgBox("Abandon Data?", vbInformation + vbYesNo) = vbNo Then
        Cancel = True
    Else
        DoCmd.RunCommand acCmdUndo
    End If
End If
End Sub

ロード時に False に設定されたブール値フラグがあり、[保存] ボタンが使用されたときにそれを true に設定して、更新を実行できるようにします。
フラグが設定されていない場合は、(別のレコードに移動するか、フォームを閉じることによって) レコードを離れているので、実際に変更を保存するかどうかを尋ねます。変更が行われた場合、 はフォームの終了または別のレコードへの移動を中止します
。 は変更を元に戻すため、変更は保存されません。Cancel = True
DoCmd.RunCommand acCmdUndo

于 2012-10-18T14:48:22.723 に答える
0

実際には、これをトラップすることはできません.Accessはテーブルで直接作業しており、フィールドが別のフィールド、レコード、またはボタンに移動してフォーカスを失ったときに、すべての変更が既に保存されています.

実際、これはExcelと比較して大きな利点です

Excel と同様の動作が本当に必要な場合は、テーブルのコピーと更新用のコードを作成する必要があります。

于 2012-10-18T13:11:19.230 に答える
-1

** このコードで終了ボタンを使用できます**

Private Sub Button_Click()
If Me.Dirty = True Then
   If MsgBox(" Save Change ", vbYesNo) = vbYes Then
      Me.Dirty = False
   Else
      Me.Undo
   End If
End If
DoCmd.Close acForm, "FormName"
End Sub
于 2015-12-20T17:57:33.930 に答える