Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(指定なし : 指定なし)
UserForm.Show vbModeless で TextBox にフォーカスさせたい(↓↑に関係して)
投稿日時: 23/02/16 15:01:01
投稿者: taichi

「↓キーと↑キーでは動きが違う?」の質問と同じUserFormなので、
ダミーの Label コントロール も配置しています。
 
UserFormを開いたにTextBoxのフォーカスがあれば、すぐ3桁の数字を入力して
いけるのですが、vbModeless で開いているときは、フォーカスが消失しています。
vbModeless の方で開いた方が同時にファイル操作もできますので何かと便利なのです。
 
Private Sub UserForm_Initialize()
    TextBox.SetFocus
End Sub
としてもTextBoxにフォーカスが戻らないので、マウスでTextBoxを選択してから
数字を入力しています。少しのことですがちょっでも面倒だと感じることは、
できることならVBAで解決を試みたいのです。
 
宜しくお願いいたします。

回答
投稿日時: 23/02/16 15:30:54
投稿者: taitani
投稿者のウェブサイトに移動

Private Sub UserForm_Initialize()
ではなく、
Private Sub UserForm_Activate()
を使用されてはいかがでしょうか。
<参考>
https://officedic.com/excel-vba-userform-activate-event/#:~:text=%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%A8%E3%81%AF-,%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%8C%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%9F%E9%9A%9B%E3%81%AB%E5%AE%9F%E8%A1%8C,%E3%81%A6%E3%82%82%E7%99%BA%E7%94%9F%E3%81%97%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82
 
/// 引用 ///
2.ActivateとInitializeの違い
Activateイベントと同じくらい使用頻度の高いInitializeイベントがあり、混同されやすいイベントです。
違いについて、簡単にご説明します。
Initializeイベントは「初期化する」という意味ですが、基本的には読み込まれた瞬間に実行されます。
Activateはユーザーフォームがアクティブになった時に実行されます。
何が違うかと言いますと、Initializeイベントは表示→削除→表示→削除と表示したり消したりを繰り返すことで何度も実行されます。
ですが、ActivateイベントはUserForm1とUserForm2を同時に開いている場合に、UserForm1と2を交互に選択することで、アクティブになるたびに実行されます。
似ていますが、トリガーとなるタイミングが違いますので使い分けが必要になります。

回答
投稿日時: 23/02/17 07:29:09
投稿者: gombohori

 TextBoxのTabIndexプロパティはどうなってますか?
 TabIndex プロパティが小さい順にアクティブになります
 (Tabキー押すごとにTabIndexプロパティが小さい順にアクティブになる)
 
 デフォルトでは、デザイン時にコントロールを挿入して順に TabIndexが振られるので、
 UserForm起動時には、最初に挿入したコントロールになってるはずです。

回答
投稿日時: 23/02/17 12:37:51
投稿者: はぶ

失礼します。
 
gombohori さんの TabIndexプロパティをヒントに
> Private Sub UserForm_Initialize()
> TextBox.SetFocus
   ↓
     Me.TextBox.TabIndex = 0
> End Sub
 
また、
> vbModeless の方で開いた方が同時にファイル操作もできますので何かと便利なのです。
 
モードレス起動後、TextBox 操作中に いったん UserForm
から離れて再度、TextBox にフォーカスを戻すような場合、
UserForm を動かすと発生する Layout イベントあたりが
無難かもしれません。
例)
Private Sub UserForm_Layout()
    If Me.ActiveControl.Name = "TextBox1" Then
      Me.CommandButton1.SetFocus
      Me.TextBox1.SetFocus
    End If
End Sub
ここまで要求していなければ飛ばしてください。
 
> ダミーの Label コントロール も配置しています。
宿題?)フォーカスが移らない簡単な説明
 
 Userform の編集画面では、矢印方向に近いコントロールに
フォーカスが移ります。Userform 実行中の画面でも、同様に
近いコントロールに移ります。(Tab キー動作とは無関係です)
 
 実行中、フォーカスを持たないコントロールがあります。
標準では、Label と Image のコントロールです。
 
 矢印方向にあるコントロールがフォーカスを受け取れない
場合、矢印キーを押しても、Exit イベントは発生しません。
それは、矢印キーを押した側のコントロールから出ていない
ということだと思います。
 
なぜそういう仕様なのか、というところまでは理解していません。
ご納得されたかどうかはわかりませんが、この辺の説明で
いかがでしょうか。失礼しました。

投稿日時: 23/02/18 13:13:00
投稿者: taichi

taitani さん gombohori さん はぶ さん 回答ありがとうございました。
 
■ taitani さん
Private Sub UserForm_Activate()
 TextBox1.SetFocus
End Sub
で開いた状態でTextBox1にフォーカスがあり一応解決です。
 
但し、vbModeless 状態で、セル選択後 UserFormにカーソルを
戻しても TextBox1にフォーカスが戻らないので、
■ はぶ さん
Private Sub UserForm_Layout()
 …
End Sub
上のコード(初めて知りました)で UserForm を動かすとTextBox1にフォーカスが
戻るのを確認できました。
 
UserForm 位置を動かさなくてもカーソルをUserFormに戻すだけで
TextBox1にフォーカスが戻ると便利なので
Private Sub UserForm_MouseMove_MouseMove(…)
 TextBox1.SetFocus あるいは Me.TextBox.TabIndex = 0
End Sub
を入れてみましたが効果なしでした。
 
でも開いた時点でTextBox1にフォーカスがあるだけでも助かります。
 
■ はぶ さん
> Private Sub UserForm_Initialize()
>  Me.TextBox.TabIndex = 0
> End Sub
TextBox.TabIndex = 0 で何故フォーカスがあるのか
理屈はわかりませんが、確かにフォーカスが当たります。
(助かります)
 
>ご納得されたかどうかはわかりませんが
何となく理解できたような気がします。(>_<)
 
■ gombohori さん
TabIndex はListBox1=0 TextBox1=1 Label1(ダミー)=2 CommandButton1=3
但し、これは実験用のUserFormで実際にはコントロールは20個ほど配置しています。
TabStopもFalseにしてあるのもあります。

回答
投稿日時: 23/02/18 13:35:41
投稿者: hatena
投稿者のウェブサイトに移動

まず、
開いたときにTextBoxにフォーカスがあるようにしたいという点については、既にはぶさんから回答があるように
Me.TextBox.TabIndex = 0
とすればいいでしょう。
あるいは、TextBoxのプロパティで TabIndex に 0 を設定しておけばいいでしょう。
 
希望の動作としては、TextBoxでフォーカスがある状態で↓↑キーでリストボックスの選択を変更したいということなのでリストボックスにフォーカスが移動する必要がないといえるので、
Me.ListBox1.TabStop = False
としてタブキーでの移動ができないようにした方がいいかもしれません。もちろんプロパティで TabStop を False にしてもいいでしょう。
 
 
つぎに、
「↓キーと↑キーでは動きが違う?」の質問が閉じているので、こちらで回答させていただきます。
 
↓キーと↑キーには既定の動作があります。
↑キーは自分の上方にあるコントロールに移動
↓キーは自分の下方にあるコントロールに移動
です。
 
前回の質問で↓キーでコマンドボタンへ移動するのは、コマンドボタンがテキストボックスの下にあるからでしょう。
↑キーでフォーカスが移動しないのは上になにもコントロールがないからだと思われます。
 
もし、コマンドボタンをテキストボックスの上に配置したら↑キーで移動してしまうでしょう。
 
対策としては、↓↑を押したときにそれを無効化します。
具体的には、KeyCode = 0 とすれば何もキーが押されなかったとになります。
 

Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    Select Case KeyCode
        Case 38 'Up Arrow
            KeyCode = 0
            If ListBox1.ListIndex > 0 Then
               ListBox1.ListIndex = ListBox1.ListIndex - 1
            End If
        Case 40 'Down Arrow
            KeyCode = 0
            If ListBox1.ListIndex < ListBox1.ListCount - 1 Then
               ListBox1.ListIndex = ListBox1.ListIndex + 1
            End If
   End Select
End Sub

回答
投稿日時: 23/02/18 14:02:20
投稿者: hatena
投稿者のウェブサイトに移動

シートを操作した後、ユーザーフォームを選択したとき、フォーカスが消失する点については、
当方のサンプルで試した所では、下記でうまくいきました。
 
 

Private Sub UserForm_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
      Me.CommandButton1.SetFocus
      Me.TextBox.SetFocus
End Sub

 
Me.TextBox.SetFocusだけではだめでしたので、Me.CommandButton1.SetFocusも追加してみました。
なぜ、そうなるかはよく分かりません。
 
ただし、タイトルバーをクリックしても無反応ですので、フォームのクライアントエリアをクリックする必要がありますが。

投稿日時: 23/02/18 21:27:18
投稿者: taichi

hatena さん 回答ありがとうございました。
 
>↓キーと↑キーには既定の動作があります。
>↑キーは自分の上方にあるコントロールに移動
>↓キーは自分の下方にあるコントロールに移動
です。
  
>↓キーでコマンドボタンへ移動するのは、コマンドボタンがテキストボックスの下にあるからでしょう。
>↑キーでフォーカスが移動しないのは上になにもコントロールがないからだと思われます。
>もし、コマンドボタンをテキストボックスの上に配置したら↑キーで移動してしまうでしょう。
 
実験用のUserFormでテキストボックスの配置を変えて試しました。
おっしゃる今まで問題なかった↑キー希望通りには動きませんでした。
コントロールの配置位置で結果が違うとは思いもよりませんでした。
ありがとうございました。
 
あと1日に開いておいて締めたいと思います。

投稿日時: 23/02/20 15:03:53
投稿者: taichi

「↓キーと↑キーでは動きが違う?」 の解決策として
>ダミーの Label コントロールを配置
という意味があまり分からなかったのですが、
なんとなく理解できたような気がします。
 
ありがとうございました。