プロが教える店舗&オフィスのセキュリティ対策術

単票フォームに非連結のテキストボックス「Tx_テキストA」と「Tx_テキストB」があり、
Tx_テキストA には「1~10の数値」という条件があるとします。

Tx_テキストAに数値を入力した後、更新後処理イベントで数値をチェックし、
範囲外であればその旨のメッセージを出力してTx_テキストAをクリア。
カーソルをTx_テキストAのままにして再度入力してもらう、という処理を
したいと思っています。

Tx_テキストAの更新後処理イベントに以下のコードを書いたのですが、
メッセージボックスを閉じるとTx_テキストAはクリアされるものの、
カーソルがTx_テキストBに移動してしまいます。
「Me.Tx_テキストA.SetFocus」を if文の外に出しても同様なのですが、
カーソルをTx_テキストAにするにはどうしたらよいのでしょうか?

ちなみにタブオーダーは
Tx_テキストA
Tx_テキストB
となっています。

よろしくお願いいたします。

Private Sub Tx_テキストA_AfterUpdate()

If Me.Tx_テキストA < 1 Or Me.Tx_テキストA > 10 Then
MsgBox "1~10の数字を入力"
Me.Tx_テキストA = Null
Me.Tx_テキストA.SetFocus
End If

End Sub

質問者からの補足コメント

  • No.1さまへの補足説明です。
    更新前処理に同じコードを書いて実行させると、Tx_テキストA に Nullを入れるステップで写真のようなエラーが出てしまいます。
    よろしくお願いいたします。

    「Access の SetFocus につ」の補足画像1
      補足日時:2022/08/04 13:07

A 回答 (5件)

No.1です。


更新前処理と更新後処理ではタイミングの問題だけじゃなくて色々違いがありますので、同じコードが使えるとは限りません。

こういうやり方でも可能です。
簡単に書きますので、環境に合わせて書き直してください。

If 条件 Then
 MsgBox ""
 A.SelStart = 0
 A.SelLength = Len(A)
 SendKeys "{BS}"
 Cancel = True
End If

入力された文字を全選択状態にし、BackSpaceで消しています。
    • good
    • 0
この回答へのお礼

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

イベントによって使えるコードと、使えないコードもあるのですね。
考えてみたら、更新前の処理でそのコントロールを更新しようとしているわけですから、矛盾していましたよね。。。

 A.SelStart = 0
 A.SelLength = Len(A)

ここまでは調べて見つけたのですが、全体が選択状態になっているので「中身を消すという動作は不要だからいいかな。。。」と思っていました。

バックスペースで消すという方法もあったのですね!
とても参考になりました!
ありがとうございました。

お礼日時:2022/08/05 06:31

こんにちは。



簡単な入力チェックなら Exit イベントがいいかもですね。
Cancel = True にして Exit をキャンセルできますし。

あと、

Null として間違った値を消してしまうのが良いか?
何が間違ったのか理由をMsgBoxで表示し、全選択状態で残すのが良いか?

ユーザビリティーの問題ですけど、大体後者のパターンが多いと思います。
これは余談でした。

Private Sub Tx_テキストA_Exit(Cancel As Integer)
  Dim n As Long
  n = Val(Tx_テキストA.Text)
  If n >= 1 And n <= 10 Then '<---以上、以下は大丈夫ですか?
    'OK
  Else
    'NG
    MsgBox "1~10までで再入力"
    Tx_テキストA.SelStart = 0
    Tx_テキストA.SelLength = Len(Tx_テキストA.Text)
    Cancel = True
  End If
End Sub
    • good
    • 0
この回答へのお礼

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

>Null として間違った値を消してしまうのが良いか?
>何が間違ったのか理由をMsgBoxで表示し、全選択状態で残すのが良いか?

これ、目からうろこが落ちる状態でした!!!
入力している人からすれば自分の入力値の何が間違っていたのか・・・
残しておいた方が良いように思いました。

アドバイスいただいた「Exit イベント」での記述ですが、試してみるとTx_テキストAにカーソルが移った後、正しい値を入力しない限り別のコントロールに移動できないのですね。

実際に作っているAccessDBでは、このコントロールは必須項目なので必須項目チェックをしないで済みそうです。
ただ、このコントロールにカーソルが行ってしまうと、別の項目を先に入力することができないので、Exit イベント が良いのか BeforeUpdate イベントが良いのか・・・・
使い勝手を考慮してもう少し考えてみます。

良いアドバイスをいただき、大変ありがとうございました!

お礼日時:2022/08/05 06:43

setfocus の後に、


cancel=true
をいれると、イベントがキャンセルされるんだったっけか?
    • good
    • 0
この回答へのお礼

再度の回答ありがとうございます。
cancel=true
これ、初めて知りました!

何をするコードなのか調べてみて、やっと理解できました^^;
使う機会も結構ありそうですね!
ありがとうございました!!

お礼日時:2022/08/05 06:24

Me.Tx_テキストA = Null


とした時点で、テキストが更新されますので、またイベントが起きるのかな? でもその場合はif文の外に出したら、動きそうなもんですけど。

こういう場合は、ステップ実効をしてどの行でなにがおきて、次にどの行が実行されるかを確認してみるとよいです。

まあ、lostfocus時のイベントに書いておけば、良いような気もします。
    • good
    • 0
この回答へのお礼

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

>こういう場合は、ステップ実効をしてどの行でなにがおきて、次にどの行が実行さ
>れるかを確認してみるとよいです。

ステップ実行は使ったことが無かったのですが、IF文にブレークポイントを設定して実行してみたところ、上から順番に実行されました。
「End Sub」が終わったところでフォームを見ると、やはりカーソルはTx_テキストBに移動していました。

また、コードを lostfocus 時のイベントに書いてやってみましたが、やはりカーソルはTx_テキストBに移動してしまいました。

この様な要求って結構ありそうですが、なかなか上手くいかないものですね。

お礼日時:2022/08/04 13:19

更新後処理じゃなくて更新前処理でやるといいです。

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

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

更新前処理にコードを書いてやってみたのですが、エラーになってしまいました。
補足説明にエラーの画像を載せましたので、見ていただけると幸いです。

よろしくお願いいたします。

お礼日時:2022/08/04 13:06

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