1603439180 Accessのデザインビュー→プロパティシート内の「レコード削除時」にイベントプロシージャを設け、「Delete」キー押下でレコードが削除できるようにしたい


いつもお世話になっております。
フォームからデータを一行、削除する方法につきまして、調べております。
以前、

Accessのフォームで重複した値を入力すると、それ以降、入力がで… - 人力検索はてな
https://q.hatena.ne.jp/1601970529

という質問でも紹介したのですが。
「レコードの削除」ボタンを設け、それをクリックすることで、フォームに入力した値を一行まるまる消去することはできました。

しかし…他のプログラムでは、削除ボタンを作らなくても。
質問のタイトルおよび画像にありますように「レコード削除時」において。

Private Sub Form_Delete(Cancel As Integer)
Cancel = True
disposaljudge = Format(Forms("F_注文履歴").商品コード.Value, "")
Cancel = False
End Sub

のようなプロシージャを記載することで。

キーボードの「Del」押下時に「1件のレコードを削除します」と、「はい」「いいえ」の選択肢とともに、ダイアログが出てくるのですが。

回答の条件
  • 1人20回まで
  • 登録:
  • 終了:2020/10/30 11:18:33
id:moon-fondu

このシステムに同じ機能を実装しようとして上記コードを追加してみました。

https://f.hatena.ne.jp/moon-fondu/20201023164747

しかし、全く反応が無く…。

「Del」キー押下でレコードを削除をする方法を、お教えいただけますと有り難いです。

現状のシステムはこちらになります。

https://xfs.jp/7AW5Mk

よろしくお願い致します<m(__)m>

※以下の「ボタン押下で行を削除する方法」は一旦、コメントアウトで、機能しないようにしています。

--------------------------

Private Sub レコードの削除_Click()

Dim lans As Long

If Me.NewRecord = True Then

MsgBox "新規レコードは削除できません"

Exit Sub

End If

lans = MsgBox("削除してもよろしいですか?", vbYesNo + vbInformation, "確認")

If lans = vbNo Then

Exit Sub

End If

On Error GoTo ErrExit

DoCmd.SetWarnings False

DoCmd.RunCommand acCmdDeleteRecord

DoCmd.SetWarnings True

Exit Sub

ErrExit:

MsgBox "エラーが発生した為、削除できませんでした。" & vbCrLf & "エラー内容: " & Err.Description

End Sub

--------------------------

ベストアンサー

id:ken3memo No.2

回答回数303ベストアンサー獲得回数107

ポイント1500pt

もしかしたら、会社の前システムが動作するのに、
moon-fonduさんの作成したテストが動作しないのは、

f:id:ken3memo:20201027221524j:image

↑"KeyPreview/キーボードイベント取得" プロパティ (Access)
https://docs.microsoft.com/ja-jp/office/vba/api/Access.Form.KeyPreview

※作成された、テストフォームのプロパティが違っているので、
 先輩・上司さんの作成した会社の財産コードが動作しなかったとか?
※※↑勝手な予想です。




以下、いつものデバッグどうがです。

https://youtu.be/7j61Fd9HX9Q

※この動画でもしかしたら、
KeyPreview/キーボードイベント取得"
プロパティさえ設定すれば、社内サンプルが動くのかな?と思ったり。

Private Sub Form_Delete(Cancel As Integer)
Cancel = True
disposaljudge = Format(Forms("F_注文履歴").商品コード.Value, "")
Cancel = False
End Sub

↑この、コードだけでは、Deleteキーを拾わないと思うので、
違う原因だとは思いますが。





Deleteキーが押された時のイベント発生順を探ってみる

1.Debug.Print で 確認する
Fromのイベントに Debug.Printを入れて確認する

キークリック時 Form_KeyDown:KeyCode=46
レコード削除時 Form_Delete
削除前確認 Form_BeforeDelConfirm
削除後確認 AfterDelConfirm


定数 (Visual Basic for Applications)
https://docs.microsoft.com/ja-jp/office/vba/language/reference/constants-visual-basic-for-applications

:KeyCode=46

vbKeyDelete 0x2E Delete キー



2.Deleteキーでレコード削除を走らせてみる

Private Sub Form_AfterDelConfirm(Status As Integer)
    Debug.Print "削除後確認 AfterDelConfirm"
End Sub

Private Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer)
    Debug.Print "削除前確認 Form_BeforeDelConfirm"

End Sub

Private Sub Form_Delete(Cancel As Integer)

    Debug.Print "レコード削除時 Form_Delete"
    'Cancel = True
    ' disposaljudge = Format(Forms("F_注文履歴").商品コード.Value, "")
    'Cancel = False
End Sub

'フォームのプロパティ
'"KeyPreview/キーボードイベント取得" プロパティ (Access)
' https://docs.microsoft.com/ja-jp/office/vba/api/Access.Form.KeyPreview
'に注意
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    Debug.Print "キークリック時 Form_KeyDown:KeyCode=" & KeyCode
    If KeyCode = vbKeyDelete Then
        Debug.Print "DELキーが押された処理"
        Call レコードの削除_Click   'レコードの削除
        KeyCode = 0
    End If
End Sub

Private Sub Form_KeyPress(KeyAscii As Integer)
    Debug.Print "キー入力時 Form_KeyPress:KeyAscii=" & KeyAscii
    
End Sub

Private Sub 商品コード_BeforeUpdate(Cancel As Integer)
    Dim nCNT As Integer
    
    MsgBox "チェックコードに入りました"
    
    'そもそも、本当に変更されたか、チェックする
    If Me.商品コード.Value = Me.商品コード.OldValue Then
        MsgBox "ここ、コード同じでした"
        Exit Sub '同じときは、チェックしない
    End If
    'チェック関数を通して(リターン値でもらって)TrueならキャンセルもTrue https://youtu.be/Irr_9wx6CAY?t=2141
    Cancel = chk商品コード(Me.商品コード)
    
End Sub

Private Sub レコードの削除_Click()


   Dim lans As Long

   If Me.NewRecord = True Then
        MsgBox "新規レコードは削除できません"
        Exit Sub
    End If


    lans = MsgBox("削除してもよろしいですか?", vbYesNo + vbInformation, "確認")
   If lans = vbNo Then
        Exit Sub
    End If
'
    On Error GoTo ErrExit
'
    DoCmd.SetWarnings False
    DoCmd.RunCommand acCmdDeleteRecord
    DoCmd.SetWarnings True
'
    Exit Sub
'
ErrExit:
    MsgBox "エラーが発生した為、削除できませんでした。" & vbCrLf & "エラー内容: " & Err.Description
End Sub

Private Sub 商品コード_DblClick(Cancel As Integer)
    DoCmd.OpenForm "F_メニュー一覧", , , , , , "F_注文履歴"
End Sub



'テスト、コントロールでDeleteキーを受け取り、処理を走らせる
'こっちも、フォームプロパティを変えて、テストしてみては?
'KeyPreview/キーボードイベント取得" プロパティ (Access)
'https://docs.microsoft.com/ja-jp/office/vba/api/Access.Form.KeyPreview

Private Sub 注文ID_KeyDown(KeyCode As Integer, Shift As Integer)
    Debug.Print "キークリック時 注文ID_KeyDown:KeyCode=" & KeyCode
    If KeyCode = vbKeyDelete Then
        Debug.Print "DELキーが押された処理"
        Call レコードの削除_Click   'レコードの削除
        KeyCode = 0
    End If

End Sub


https://youtu.be/7j61Fd9HX9Q
↑途中で動画が切れてしまいましたが、
 Access Form Deleteキーを拾い、削除処理を走らせる参考となれば幸いです。

他2件のコメントを見る
id:ken3memo

Delキーが動作するみたいで、よかったです。※先輩が複雑なコードを書いていなかったみたいでよかったです。

寄り道・回り道したので、イロイロ応用もできたみたいで。。。
近い将来 上位工程・操作設計などを 任された時に応用してみてください。※※まぁ、あまり複雑な機能を持たせると、後輩を困らせることになるので、ほどほどにね。

2020/10/28 17:43:02
id:moon-fondu

まだまだ遠い道のりですが…(^^;)
ありがとうございました。

2020/10/30 11:14:11

その他の回答1件)

id:ken3memo No.1

回答回数303ベストアンサー獲得回数107

ポイント1500pt

>Accessのデザインビュー→プロパティシート内の「レコード削除時」にイベントプロシージャを設け、「Delete」キー押下でレコードが削除できるようにしたい


0.まず現状確認
 左側のレコードを選択中なら、何もしなくてもDeleteキーで削除が走ると思いますが・・
0.1 Access フォームで左側の行選択で明細行を選択後、
Deleteキーを押す操作をユーザに覚えてもらう※トリッキーなプログラムは組まない

https://youtu.be/qKpQOqNNIu8?t=24

f:id:ken3memo:20201027191652j:image

0.2 単票フォームの時、左下のレコードセレクタで<>で移動する人いる、

0.3 右クリックで切り取る上級国民じゃなかった一般ユーザに対応するのか?
Accessの操作を※統一操作を考えてみるのも、、、、
※だから、全システム、前のシステムでも当社のシステムはそのようになってます。
 と、いわれれば、それまでなんだけど。

※※テキストボックスにコードや数量などを入力するときも、
  BSバックスペースではなく、Delキーを使う人もいるので、
  何も意識しないDelキーに特殊な操作を割り当てるのは、
  まぁシステム設計者の好みもあるし、間違って押さないか心配でもあったり。

https://youtu.be/qKpQOqNNIu8?t=84

f:id:ken3memo:20201027191656j:image


1.フォーカス、処理対象がどこにあって、
 どこでDeleteキーが押された時に処理をしたいのかを確認する。
 ※Deleteキーは値の修正時にも使うのでは?

2.イベントのタイミングを確認したいので
 Debug.Print や MsgBox で、
 慣れるまで、イベント発生順を確認する

こんな感じで、下準備をしながら、デバッグするとよいのでは?

他2件のコメントを見る
id:moon-fondu

ken3memoさん動画ありがとうございます!
「あれ?」と思いました。
そうです、自分がやりたかったのは、左端のレコード選択で削除、だったのですが。
既に機能として盛り込まれていたのですね。
自分の確認不足でしたね…失礼致しました<m(__)m>

------------
Public disposaljudge As String

Private Sub Form_Delete(Cancel As Integer)
Cancel = True
disposaljudge = Format(Forms("F_注文履歴").商品コード.Value, "")
Cancel = False
End Sub
------------

も、入れなくても削除できました。
会社のシステムにはなぜか「レコード削除時」のイベントプロパティとして、delete押下時にステップインで見ていくと、上記のようなコードを通っていたので、これを盛り込まないといけないと捉われていましたが。

上記コードを除去しても問題なく、左端のレコード選択+deleteで、レコードを削除することができました。

ken3memoさんがおっしゃるように、delキーに特殊な操作を割り当てると、色々と支障が生じそうですね。
以前参考にしたこの記事 https://www.feedsoft.net/access/guide-control/guide-c43.html のように、テキストボックスのボタンにイベントを設けてレコードを削除すれば、delを使わずにすみそうですが。

左端でdelキーで削除、の方がシンプルでいいですね。

2020/10/28 14:34:11
id:moon-fondu

keyミッション、勉強になります。
仕込みの部分、過程もお見せいただいて、ありがたいです。

「キーボードイベント取得」は、すごくわかりにくい場所にありますね。
「はい」にしたらフォーム全体に適用されるのは知らなかったです。
その場合の注意点もお教えいただき、助かります。
はい、でイベントを設けてしまうと。テキストボックスの値を削除したいのに、レコード全部を削除しますかどうか、になってしまうんですね。

キーイベント取得は「いいえ」にして、「注文ID」のところだけdelキー押下でレコード削除ができる…こういうこともできるんですね。ken3memoさんは自由自在にキー入力とフォーム操作の処理をコードにできるんですね、すごいです。ありがとうございます。

いただいた動画で学びながら、左端のレコード選択+deleteだけでなく、こちらの削除方法もできるようにしてみました。

コメントアウトしていた処理を戻したら「このコントロールはオートナンバー型の'注文ID'フィールドに連結しているため、編集できません。」というエラーが出てきまして、一瞬焦りましたが。

「キーボードイベント取得」を"いいえ"にして、かつ、ken3memoさんに教えていただいた、

Private Sub 注文ID_KeyDown(KeyCode As Integer, Shift As Integer)
Debug.Print "キークリック時 Form_KeyDown:KeyCode =" & KeyCode
If KeyCode = vbKeyDelete Then
Debug.Print "DELキーが押された処理"
Call レコードの削除_Click 'レコードの削除
KeyCode = 0
End If
End Sub

の処理を加えることで、注文IDのテキストボックス上でのDelキー押下でも、レコードを削除することができました。

ありがとうございました<m(__)m>

2020/10/28 14:38:57
id:ken3memo No.2

回答回数303ベストアンサー獲得回数107ここでベストアンサー

ポイント1500pt

もしかしたら、会社の前システムが動作するのに、
moon-fonduさんの作成したテストが動作しないのは、

f:id:ken3memo:20201027221524j:image

↑"KeyPreview/キーボードイベント取得" プロパティ (Access)
https://docs.microsoft.com/ja-jp/office/vba/api/Access.Form.KeyPreview

※作成された、テストフォームのプロパティが違っているので、
 先輩・上司さんの作成した会社の財産コードが動作しなかったとか?
※※↑勝手な予想です。




以下、いつものデバッグどうがです。

https://youtu.be/7j61Fd9HX9Q

※この動画でもしかしたら、
KeyPreview/キーボードイベント取得"
プロパティさえ設定すれば、社内サンプルが動くのかな?と思ったり。

Private Sub Form_Delete(Cancel As Integer)
Cancel = True
disposaljudge = Format(Forms("F_注文履歴").商品コード.Value, "")
Cancel = False
End Sub

↑この、コードだけでは、Deleteキーを拾わないと思うので、
違う原因だとは思いますが。





Deleteキーが押された時のイベント発生順を探ってみる

1.Debug.Print で 確認する
Fromのイベントに Debug.Printを入れて確認する

キークリック時 Form_KeyDown:KeyCode=46
レコード削除時 Form_Delete
削除前確認 Form_BeforeDelConfirm
削除後確認 AfterDelConfirm


定数 (Visual Basic for Applications)
https://docs.microsoft.com/ja-jp/office/vba/language/reference/constants-visual-basic-for-applications

:KeyCode=46

vbKeyDelete 0x2E Delete キー



2.Deleteキーでレコード削除を走らせてみる

Private Sub Form_AfterDelConfirm(Status As Integer)
    Debug.Print "削除後確認 AfterDelConfirm"
End Sub

Private Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer)
    Debug.Print "削除前確認 Form_BeforeDelConfirm"

End Sub

Private Sub Form_Delete(Cancel As Integer)

    Debug.Print "レコード削除時 Form_Delete"
    'Cancel = True
    ' disposaljudge = Format(Forms("F_注文履歴").商品コード.Value, "")
    'Cancel = False
End Sub

'フォームのプロパティ
'"KeyPreview/キーボードイベント取得" プロパティ (Access)
' https://docs.microsoft.com/ja-jp/office/vba/api/Access.Form.KeyPreview
'に注意
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    Debug.Print "キークリック時 Form_KeyDown:KeyCode=" & KeyCode
    If KeyCode = vbKeyDelete Then
        Debug.Print "DELキーが押された処理"
        Call レコードの削除_Click   'レコードの削除
        KeyCode = 0
    End If
End Sub

Private Sub Form_KeyPress(KeyAscii As Integer)
    Debug.Print "キー入力時 Form_KeyPress:KeyAscii=" & KeyAscii
    
End Sub

Private Sub 商品コード_BeforeUpdate(Cancel As Integer)
    Dim nCNT As Integer
    
    MsgBox "チェックコードに入りました"
    
    'そもそも、本当に変更されたか、チェックする
    If Me.商品コード.Value = Me.商品コード.OldValue Then
        MsgBox "ここ、コード同じでした"
        Exit Sub '同じときは、チェックしない
    End If
    'チェック関数を通して(リターン値でもらって)TrueならキャンセルもTrue https://youtu.be/Irr_9wx6CAY?t=2141
    Cancel = chk商品コード(Me.商品コード)
    
End Sub

Private Sub レコードの削除_Click()


   Dim lans As Long

   If Me.NewRecord = True Then
        MsgBox "新規レコードは削除できません"
        Exit Sub
    End If


    lans = MsgBox("削除してもよろしいですか?", vbYesNo + vbInformation, "確認")
   If lans = vbNo Then
        Exit Sub
    End If
'
    On Error GoTo ErrExit
'
    DoCmd.SetWarnings False
    DoCmd.RunCommand acCmdDeleteRecord
    DoCmd.SetWarnings True
'
    Exit Sub
'
ErrExit:
    MsgBox "エラーが発生した為、削除できませんでした。" & vbCrLf & "エラー内容: " & Err.Description
End Sub

Private Sub 商品コード_DblClick(Cancel As Integer)
    DoCmd.OpenForm "F_メニュー一覧", , , , , , "F_注文履歴"
End Sub



'テスト、コントロールでDeleteキーを受け取り、処理を走らせる
'こっちも、フォームプロパティを変えて、テストしてみては?
'KeyPreview/キーボードイベント取得" プロパティ (Access)
'https://docs.microsoft.com/ja-jp/office/vba/api/Access.Form.KeyPreview

Private Sub 注文ID_KeyDown(KeyCode As Integer, Shift As Integer)
    Debug.Print "キークリック時 注文ID_KeyDown:KeyCode=" & KeyCode
    If KeyCode = vbKeyDelete Then
        Debug.Print "DELキーが押された処理"
        Call レコードの削除_Click   'レコードの削除
        KeyCode = 0
    End If

End Sub


https://youtu.be/7j61Fd9HX9Q
↑途中で動画が切れてしまいましたが、
 Access Form Deleteキーを拾い、削除処理を走らせる参考となれば幸いです。

他2件のコメントを見る
id:ken3memo

Delキーが動作するみたいで、よかったです。※先輩が複雑なコードを書いていなかったみたいでよかったです。

寄り道・回り道したので、イロイロ応用もできたみたいで。。。
近い将来 上位工程・操作設計などを 任された時に応用してみてください。※※まぁ、あまり複雑な機能を持たせると、後輩を困らせることになるので、ほどほどにね。

2020/10/28 17:43:02
id:moon-fondu

まだまだ遠い道のりですが…(^^;)
ありがとうございました。

2020/10/30 11:14:11

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません