• 締切済み

コントロールが発生させるイベントを回避したい

VB2008です。 状態: フォーム上にtextbox1、textbox2、button1があり、textbox1からtextbox2もしくはbutton1にフォーカスが移動したとき 1:textbox2への移動->textbox1のlostfocusイベントを通常通り発生させる。 2:button1への移動->textbox1のlostfocusイベントをキャンセルする。(1度たりとも発生させない、もしくは発生してもその処理を1度たりともさせない。) 1は通常の処理なのでなにもしなくていいと思うのですが、2の処理が上手に浮かびません。button1でフラグを立てて、textbox1_lostfocusの処理を抜けるようにしているのですが、必ず1度は処理が実行されます。 どのようにコードを書けばうまくできるでしょうか。もし、これが仕様ということなら、同じような処理をするにはどうすればよいでしょうか。 わかりにくければ補足いたします。よろしくお願いします。

みんなの回答

  • pulsa
  • ベストアンサー率57% (34/59)
回答No.3

概念としてNO.2の方で正解ですね lostfocus→getfocus のように進まないと、一時的にfocusが二つあることになってしまいますもんね 今回の場合、lostfocusには処理は入れられません getfocusの時lostfocusに入れていたイベントの内容を実行させるのが、良いかと思います もう少し突っ込むと、textbox1のlostfocusが重要なのではなく、 「textbox2がgetfocusした時、直前がtextbox1だった事」が重要と考えます NO.2の方のように、フラグでも良いでしょうし、全てのlostfocusに抜けるコントロールの名前を変数に入れさせるようにして、変数の値が「"textbox1"」の時だけ反応するようにgetfocusのイベントの先頭にこれまでtextbox1のlostfocusに書いていた処理を実行させるのも手です 質問内容によるとbutton1のgetfocusには不要ですので、何も書かなければ、実行されません つまり、変数の判断処理自体不要です lostfocusするときに、変数が更新されるので、初期化は考慮しなくて済みます 関数化して Call CtrlChack(Ctrl) と呼んでみます        ↑これを実行させる可能性のあるgetfocusの先頭に書いておく Dim Ctrl As String 'これまでfocusがあったコントロール ↑これをFormモジュールの先頭に書いておく Private Sub TextBox1_LostFocus()   Ctrl = "TextBox1" End Sub Private Sub TextBox2_LostFocus()   Ctrl = "TextBox2" End Sub Private Sub TextBox2_GotFocus()   Call CtrlChack(Ctrl) 'こんな感じ End Sub Private Sub Button1_GotFocus()  '処理不要なので特にtextbox1のlostfocusに関係する処理なし End Sub ↓これは標準モジュールでOK(Formモジュールでも良いハズですが…) Sub CtrlChack(Ctrl As String)   If Ctrl = "TextBox1" Then     'textbox1のlostfocusに書いてた処理   End If End Sub

xiaolong_goo
質問者

お礼

お返事ありがとうございました。 textbox2のenterイベントで処理するようにしました。

  • DexMachina
  • ベストアンサー率73% (1287/1744)
回答No.2

AccessのVBAしか扱ったことのない者ですが(汗)、概念としては共通でいけると思いますので・・・ 移動元のFocus喪失系のイベントが終了してからでないと、移動先のFocus取得系のイベントは 発生しないので、移動先でのフラグ処理では間に合わないと推測されます。 従って、移動先によるLostFocusイベントの切り分けは無理だと思いますので、以下はその前提での 対策になります。 1)TextBox1のLostFocusイベントでは、「TextBox1のLostFocusイベントが発生したこと」を記録する  フラグだけを立てます(変数EveFlag=True) 2)Button1のGotFocusイベントでは、上記フラグを元に戻します(EveFlag=False) 3)TextBox1のLostFocusイベントで行いたかった処理を、イベントとは無関係のPrivate Subとして  フォーム モジュールに記述します(WhenMoveFromTB1) 4)TextBox1・Button1以外の、Focusを取得できる全コントロールのGotFocusイベントで、上記フラグが  オンだった場合は、上記Private SubをCallします ・・・以上が概念です。 コードの実例は以下の通り: Option Explicit 'フォームのモジュールレベルでフラグを宣言 Dim EveFlag As Boolean Private Sub TextBox1_LostFocus()   'TextBox1のLostFocusイベントが発生したことをフラグに記録   EveFlag = True End Sub Private Sub WhenMoveFromTB1()   'フラグの初期化   EveFlag = False   'ここ(↓)には、現在、TextBox1のLostFocusイベントに記述している処理を転記   MsgBox "LostFocusイベントの処理を代行します。" End Sub Private Sub TextBox2_GotFocus()   'TextBox1のLostFocusイベントが必要なTextBox2では、代行するSubをCall   If EveFlag = True Then Call WhenMoveFromTB1 End Sub Private Sub Button1_GotFocus()   'TextBox2のLostFocusイベントが無用のButton1では、フラグの初期化のみを実行   EveFlag = False End Sub Private Sub TextBox3_GotFocus()   'TextBox1のLostFocusイベントの起動が必要なコントロールがTextBox2以外にも   'ある場合は、TextBox2と同様に、代行SubをCall   If EveFlag = True Then Call WhenMoveFromTB1 End Sub ・・・以上です。

xiaolong_goo
質問者

お礼

お返事ありがとうございました。 結局フラグを立てるのもめんどくさくなりtextbox2のenterイベントで処理するようにしました。

  • onnobu
  • ベストアンサー率33% (1/3)
回答No.1

LeaveイベントのActiveContorolのプロパティーの項目に button1だけでしたら、ActiveContorol.Name = "button1"などで処理を回避できます。 また、プロパティー名を忘れてしまいましたが、buttonコントロール全体を回避することもできますよ。

xiaolong_goo
質問者

お礼

お返事ありがとうございました。 textbox2のenterイベントで処理するようにしました。

関連するQ&A

専門家に質問してみよう