プロが教えるわが家の防犯対策術!

顧客情報を入力する単票フォームを作成しています。

データが勝手に書き換わってしまわないように、
更新確認メッセージを表示させ、
キャンセルが押された場合は、編集を取り消す。ということがしたいのです。

現在、ある本の例を元に下記の記述をしています。

------------------------------
Private Sub Form_BeforeUpdate(Cancel As Integer)

Dim myans As Integer

myans = MsgBox("レコードを更新します。よろしいですか?", vbOKCancel + vbQuestion, "更新確認")

If myans = vbCancel Then
Cancel = True
Me.Undo
End If

End Sub
------------------------------

キャンセルを押したときに、

このレコードは保存できません。
オブジェクトを閉じてもよろしいですか?と確認メッセージが出てしまいます。

文頭に、DoCmd.SetWarnings Falseなどを入れてみたのですが、ダメでした。

本当は、「登録」というボタンを作成し、
登録が押されたときに上記の処理&レコード更新を行いたいのですが記述がわかりません。

登録ボタンに上記の記述をすると、閉じるを押したときに、
再度、同じ更新確認メッセージが表示されてしまいます。

(1)今の記述で、キャンセル時の確認メッセージを非表示にする
(2)登録ボタンにこの動作をつける

どちらでも構いません。
よろしくお願いいたします。

A 回答 (4件)

Private Sub Form_BeforeUpdate(Cancel As Integer)



は、新規レコードに移動する時、あるいは
既存のレコードを変更し他のレコードに
移動する時、あるいは、レコードを変更したり
新規レコードに入力してそのまま閉じようとする
ときなどに発生します。

そこで、

>このレコードは保存できません。
>オブジェクトを閉じてもよろしいですか?と
>確認メッセージが出てしまいます。

この現象を調べると、単票フォームにデータを
新規に登録、または既存のデータを変更し、
そのままフォームの右上の閉じるボタンでフォームを
閉じようとすると、まず設定した更新確認のメッセージ
が表示され、キャンセルを押すと、
システムの「このレコードは保存することができません」
というメッセージが表示されます。

したがって、質問の更新前処理を残したままに
して、この現象を回避するためには、単に
他にボタンを設定するだけでなく、

(1)
閉じるボタンではキャンセルが難しいので、
この場合は、フォームのプロパティで閉じるボタンを
「いいえ」にする。


(2)
フォームを閉じるボタンを設定し、そのボタンのクリック時
にも変更確認をする。

(3)
また、登録ボタンを設定し、それにも変更確認をする。

なお、更新前処理を残せば、新しいレコードや
別のレコードに移動するときに更新を確認でき
るので残す必要があります。


以上を踏まえて、以下を設定します。

(1)登録ボタンの設定
名前を  cmd登録
標題を  登録

Private Sub cmd登録_Click()
If MsgBox("登録しますか", vbYesNo + vbQuestion, "更新確認") = vbOK Then
DoCmd.RunCommand acCmdSaveRecord
Else
Me.Undo
End If
End Sub

(2)フォームを閉じるボタンの設定
名前を  cmd閉じる
標題を  閉じる

Private Sub cmd閉じる_Click()
'編集中であるか確認
If Me.Dirty Then
If MsgBox("レコードを更新して閉じます。よろしいですか?", vbYesNo + vbQuestion, "更新確認") = vbOK Then
DoCmd.RunCommand acCmdSaveRecord
DoCmd.Close acForm, Me.Name
Else
MsgBox ("更新せずに閉じます")
Me.Undo
DoCmd.Close acForm, Me.Name
End If
Else
DoCmd.Close acForm, Me.Name
End If
End Sub


(3)質問にある更新前処理は残す


(4)フォームの既定の閉じるボタンの設定
既定の閉じるボタンではキャンセルが難しいので、
この場合は、フォームのプロパティで閉じるボタンを
「いいえ」にする。
    • good
    • 1
この回答へのお礼

なるほど!ひとつの考え方に執着してしまうようなので、何通りもの考え方をするようにがんばります!解決できました。ありがとうございます。

お礼日時:2011/02/09 13:38

顧客情報入力テーブル


を用意し
入力→入力→入力
最後に3件分更新
の仕掛けをすれば
テーブル本体への影響少ない。
入れるだけ入れておいて
更新となればエラーないものを処理。


アクションクエリ時のメッセージが出る出ない、アクセスそのものの設定はどうですか。
    • good
    • 0
この回答へのお礼

まだまだ完成まで時間がかかるので、完成した時はアクセスの設定を変更したいと思います!
ありがとうございます。

お礼日時:2011/02/09 13:40

私がよく行う方法を書きますが、具体的な事はご自分でお調べになってください。


まったく何を言ってるのかわからないのであればお勧めしません。

ようはフォームをレコードソースに直結させず、単なるデータの表示・入力の用途とし、VBA のコードでフォーム上の入力値をテーブルに登録するって方法です。


普通にフォームを作成し、テキストボックスなども配置させます。
普通はこの後、フォームのレコードソースにテーブルやクエリを指定し、テキストボックスなどのデータソースにはフォームのレコードソースが持つフィールドを指定するかと思いますが、あえてそうせずに非連結なままにします。

フォームに配置した [登録] ボタンのクリック イベントはプロシージャに設定。
あとはフォーム上の各コントロールの値を読み取って、"何らかの手法" でレコードを登録する処理を VBA で書きます。

"何らかの手法" はいくつかあり、どれを使っても構いません。
私がよくやるのは、レコードを追加するクエリを ADO から実行する方法。
レコードを追加するクエリはパラメーター クエリにしておきます。
パラメーター クエリは ADO から Command オブジェクトとして参照し、Parameter オブジェクトでクエリのパラメーターにフォーム上の値を入れて登録します。


■ テーブル
テーブル名: employees
列1: empID 長整数型
列2: empName テキスト型


■ クエリ
クエリ名: DataAdd
内容:
PARAMETERS [@ID] Long, [@Name] Text ( 255 );
INSERT INTO employees ( empID, empName )
VALUES ([@ID], [@Name]);

■ フォーム
フォーム名: EntryForm
1つ目のテキストボックスの名前: idTextBox
2つ目のテキストボックスの名前: nameTextBox
ボタンの名前: RegistButton

■ ボタンのクリック イベントプロシージャ
見やすいように全角スペースでインデントしてあるため、このコードをこのままコピペしてもエラーになる。
インデント部分の全角スペースは半角スペースに置き換えること。
また、ADO を使うため、"Microsoft ActiveX Data Object xx Library" を参照すること。

Private Sub RegistButton_Click()
 Dim con As ADODB.Connection
 Set con = CurrentProject.Connection

 Dim com As New ADODB.Command
 With com
  .ActiveConnection = con
  .CommandType = adCmdStoredProc
  .CommandText = "DataAdd"
 End With

 Dim paramID As New ADODB.Parameter
 Dim paramName As New ADODB.Parameter

 With paramID
  .Name = "[@ID]"
  .Type = adInteger
  .Value = Me.idTextBox.Value
 End With
 com.Parameters.Append paramID

 With paramName
  .Name = "[@Name]"
  .Type = adVarWChar
  .Size = 255
  .Value = Me.nameTextBox.Value
 End With
 com.Parameters.Append paramName

 com.Execute
End Sub

このコードの先頭のほうに MssBox で 「登録するか?」 を問いかけてユーザーに答えさせるように書けばよい。
    • good
    • 0

OKボタンと、Cancelボタンを置くときは下記でいけると思います。


ご参考まで。

Private Sub OKbutton_Click()
If MsgBox("OK?", vbYesNo) = vbYes Then
DoCmd.RunCommand acCmdSaveRecord
'必要により、呼び元の帳票フォームをrequery
DoCmd.Close
End If
End Sub

Private Sub CancelButton_Click()
Me.Undo
DoCmd.Close
End Sub
    • good
    • 0
この回答へのお礼

同じく、保存できませんメッセージが表示されてしまいました。。が、別の方法で解決できました!ありがとうございます。

お礼日時:2011/02/09 13:36

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A