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

txt_IDというテキストボックスにIDを入力して、
そのIDがデータベースに存在した場合、txt_IDを無効化したいと思います。

下記にソースコードを記載しましたが、下記では
Me.txt_ID.Enabled = False
まで遷移した後、下記のエラーメッセージが表示されてしまいました。

「実行時エラー '2164':

コントロールがフォーカスを取得しているときは、コントロールを無効にすることはできません。」

【ソースコード】
Private Sub txt_ID_BeforeUpdate(Cancel As Integer)
Dim record_Existence As Boolean

' 本来はDBにアクセスして入力したIDが存在するかチェックしています。
record_Existence = True

If record_Existence = True Then
Me.txt_ID.Enabled = False
End If
End Sub

その為、上記のような場合、どのようにすればコントロールを無効化できるか、
ご存知の方がいらっしゃいましたら、ご教示いただければと思います。

よろしくお願いします。

A 回答 (2件)

横レス失礼致します。



> 下記のソースで試してみた所、下記のエラーが表示され駄目でした。

更新前(BeforeUpdate)イベントは、フィールドやレコードの更新前に
発生するイベントで、そのイベント内で更新を完了させることはできません。

ですので、コントロールを移動させる(=フィールド(=コントロール)の更新を
確定させる)場合は、更新後(AfterUpdate)イベントで行う必要があります。


【更新前/更新後イベントの大雑把な使い分け】
更新前イベント:
 イベントのキャンセルを可能にしたい場合に使用
 (指定した条件が満たされない場合、Escキーなどで入力を取り消さない限り、
 そのコントロール(またはそのレコード)からの移動を許可しない)
更新後イベント:
 上記以外で、入力値に対する対応を行う場合に使用
 (上述した通り、こちらではコントロールの移動やレコードの(強制)保存が
  できます。また、値の代入(例えば値を削除(=Nullを入力)した場合に
  強制的に代替値を入力するなど)も行えます)
 なお、このイベントは、対応する更新前イベント(→同じコントロールの
 更新前/後、フォームの更新前/後)でCancel=Trueにされた場合は
 発生しません。


今回のように、フォーカスの移動などが必要になる場合は、
 a)値のチェックのみを更新前イベントで行い、フォーカス移動などは更新後
  イベントで実行、と分割して対応するか、
 b)全てを更新後イベントで行う形にして、条件を満たさなかった場合は
  更新前イベントの「Cancel=True」の代わりに、OldValueプロパティを
  使用して、更新前の値に戻す(→コントロールの更新前イベントの場合)
  ※コントロールソースがないコントロール(=非連結コントロール)では、
   OldValueプロパティでは更新前の値は取得できません。
   (変更後と同じ値が返されます)
のどちらかを選択することになります。


以下は、全てを更新後イベントで対応した場合のサンプルです:

Private Sub txt_ID_AfterUpdate()
  Dim Record_Existence As Boolean
  Record_Existence = True

  If Record_Existence Then  
  '→If文での「= True」は省略可なので私は省略しています
    Me.txt_Name.Enabled = True
    Me.txt_Name.SetFocus
    Me.txt_ID.Enabled = False
  Else
    'OldValueプロパティにより、直前の更新を行う前の値に戻します。
    Me.txt_ID = Me.txt_ID.OldValue

    '他のフィールドの編集は有効とした上で、「ID」のみ取り消す場合は、
    'レコードを保存し直します。
    '(レコード全体の編集を取り消す場合は、提示のコード(=Escキーの
    ' 送信でもOkです)
    DoCmd.RunCommand acCmdSaveRecord
    'SendKeys "{Esc}"
  End If

End Sub
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

ご提示いただいたソースで意図した動作が行われる事を確認しました。
また、更新前イベント、更新後イベントの解説をしていただき、ありがとうございます。

なお、よく考えたら「txt_ID」は下記の感じの動作でいいのかなと思ったので、
Else内のソースを変更させていただきました。


【動作】
1. 異常時は、入力欄を空白にして問題なさそうでした
(入力エラーの内容はメッセージボックスでポップアップ表示するようにしました)。
2. 異常時は、txt_IDにフォーカスがとどまっていた方が良いと思いました。

【変更後のソース】
' ------------------------------------------------------------------------------
Me.txt_ID = ""

' 一度適当な生きているコントロールにフォーカスを飛ばした後、フォーカスを戻す
Me.preview.SetFocus
Me.txt_ID.SetFocus
' ------------------------------------------------------------------------------

このたびはどうもありがとうございました。

以上、よろしくお願いします。

お礼日時:2009/10/06 19:20

>コントロールがフォーカスを取得しているときは、コントロールを無効にすることはできません。



これがネックであればif文のあとにフォーカスを移動させてから
無効化は駄目でしたか?
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

下記のソースで試してみた所、下記のエラーが表示され駄目でした。

【エラー内容】
「実行時エラー '2108':

"GoToControl/コントロールの移動"アクション、GoToControl メソッド、または
SetFocus メソッドを実行する前に、フィールドを保存する必要があります。」

【ソースコード】
Private Sub Form_Open(Cancel As Integer)
Me.txt_name.Enabled = False
End Sub

Private Sub txt_ID_BeforeUpdate(Cancel As Integer)
Dim record_Existence As Boolean

' 本来はDBにアクセスして入力したIDが存在するかチェックしています。
record_Existence = True

If record_Existence = True Then
Me.txt_name.Enabled = True
Me.txt_name.SetFocus

Me.txt_ID.Enabled = False
Else
Cancel = True
SendKeys "{Esc}"
End If
End Sub

動作としては、起動時はtxt_nameを無効化しておき、txt_IDの入力値が正常の場合、txt_nameを有効化した上で、txt_IDを無効化したいと思います。

以上、よろしくお願いします。

お礼日時:2009/10/03 08:53

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

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


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