Access (VBA)

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

 
(Windows 7 Home Premium : Access 2013)
タブ移動を共通モジュール化したい
投稿日時: 17/02/17 11:07:14
投稿者: hanasakura

共通で使用できるモジュールについてご教示ください。
 
フォーム内のコントロール移動で(1)のような記述をしています。
タブ移動のコードは他のフォームのコントロールでも使用するため、標準モジュールを作成したしたいと思っています。
標準モジュールに(2)のように記述して、フォームから(3)のように呼び出しましたが、テキストボックスに「+」が入力されます。
標準モジュールを作成したことがないため、よくわかっていないのですが教示お願いします。
 
(1)
Private Sub サイズ2_KeyDown(KeyCode As Integer, Shift As Integer)
Select Case KeyCode
    'テンキー「+」タブ移動
        Case vbKeyAdd
           サイズ1.SetFocus
        KeyCode = 0
    'テンキー「-」タブ移動
        Case vbKeySubtract
           サイズ3.SetFocus
        KeyCode = 0
End Select
End Sub
 
 
(2)共通のモジュール
Public Sub Tasu(Ctr As Control)
    Select Case KeyCode
    'テンキー「+」タブ移動
            Case vbKeyAdd
               Ctr.SetFocus
            KeyCode = 0
    End Select
End Sub
 
(3)
Private Sub サイズ2_KeyDown(KeyCode As Integer, Shift As Integer)
    Call Tasu(サイズ1)
End Sub

回答
投稿日時: 17/02/17 11:53:26
投稿者: sk

引用:
タブ移動のコードは他のフォームのコントロールでも使用するため、
標準モジュールを作成したしたいと思っています。

「タブ移動」とは通常[Tab]キー(または[Shift]+[Tab]キー)のクリックにより、
アクティブなコントロールから次の(または前の)コントロールに
フォーカスを移動させる操作のことを言います。
 
ここでの「次」「前」とは、フォームの各セクション
(タブコントロールが配置されている場合は各ページ)における
タブオーダー(タブ移動順)の設定に基づく相対的な順番です。
 
その場合における[Tab]キーの同じ役割を[+]キーに、
[Shift]+[Tab]キーの同じ役割を[-]キーにも与えたい
(それも全てのフォームにおいて)というのが
本来の目的なのであれば、別の方法を用いられることを
お奨めします。
 
引用:
Private Sub サイズ2_KeyDown(KeyCode As Integer, Shift As Integer)
Select Case KeyCode
    'テンキー「+」タブ移動
        Case vbKeyAdd
           サイズ1.SetFocus
        KeyCode = 0
    'テンキー「-」タブ移動
        Case vbKeySubtract
           サイズ3.SetFocus
        KeyCode = 0
End Select
End Sub

上記の命令自体は、[サイズ1]や[サイズ3]などの
任意のコントロールにフォーカスを移動させるというものであって、
フォーム上におけるタブオーダーとは関わりがありません。
 
[サイズ1],[サイズ2],[サイズ3]の順にフォーカスが移動するように
タブオーダーが設定されているならば確かに表面上は
同じ現象としては観測されるでしょうけど、
もし[サイズ2],[サイズ1],[サイズ3]の順に
フォーカスが移動するようにタブオーダーを設定されていたとすれば、
上記のコードによる[+]キーと[-]キーによるフォーカス移動処理の結果と
通常のタブ移動操作によるフォーカス移動の結果は異なることになります。
 
その違いを踏まえた上で、実際になさろうとしている処理の
定義や目的を明確にされることをお奨めします。
 
引用:
(3)
Private Sub サイズ2_KeyDown(KeyCode As Integer, Shift As Integer)
    Call Tasu(サイズ1)
End Sub

いずれにせよ、ここでの KeyCode は
そのフォームモジュール内の サイズ2_KeyDown プロシージャの引数であり、
そのスコープは サイズ2_KeyDown プロシージャのみに留まります。
 
引用:
(2)共通のモジュール
Public Sub Tasu(Ctr As Control)
    Select Case KeyCode
    'テンキー「+」タブ移動
            Case vbKeyAdd
               Ctr.SetFocus
            KeyCode = 0
    End Select
End Sub

したがって、標準モジュールからは参照出来ません。

投稿日時: 17/02/17 14:17:36
投稿者: hanasakura

左手は伝票を押えていて、入力がほぼ数字のためテンキーでフォーカスの移動をしています。
(特に[Shift]+[Tab]では伝票から手を離すか、マウスに持ち変える必要があるため)
タブオーダーはサイズ1→項目1→サイズ2→項目2・・・なので「Enter」で移動します。
ただ「項目1・2・3」は入力しない場合も1/3ほどあるため、「+」「-」でサイズにフォーカスを移動しています。
現状この部分をテキストボックス毎に記述しているので、汎用的にできないかなと思い標準モジュールを書いてみました。
 
きちんとモジュールの仕組みについて理解していないと難しいですね。
ご回答ありがとうございました。

回答
投稿日時: 17/02/17 17:10:37
投稿者: sk

引用:
左手は伝票を押えていて、入力がほぼ数字のためテンキーでフォーカスの移動をしています。
(特に[Shift]+[Tab]では伝票から手を離すか、マウスに持ち変える必要があるため)
タブオーダーはサイズ1→項目1→サイズ2→項目2・・・なので「Enter」で移動します。
ただ「項目1・2・3」は入力しない場合も1/3ほどあるため、
「+」「-」でサイズにフォーカスを移動しています。

本来のタブオーダーとは別に、テンキーの[+]キー及び[-]キーに対して
独自のフォーカス遷移機能を割り当てたい、ということであれば、
少なくとも標準モジュールだけでは不可能です。
(各テキストボックスの KeyDown イベントをトラップ出来ないので)
 
引用:
現状この部分をテキストボックス毎に記述しているので、
汎用的にできないかなと思い標準モジュールを書いてみました。

そのフォームのフォームモジュール内で完結させるならば、
例えば、以下のようなコードを記述することで、
複数のテキストボックスの KeyDown イベントでの処理を
共通化させることが可能です。
 
(フォームモジュール)
-----------------------------------------------------------------------------
Option Compare Database
Option Explicit
 
'**** 変数の宣言(モジュールレベル) ****
 
'アクティブテキストボックスを参照するための変数
Private WithEvents txtActiveTextBox As Access.TextBox
 
'フォーカスの移動先となるコントロールの名前を保持するための変数
Private strNextControlName As String
Private strPreviousControlName As String
 
'フォームの[開く時]イベント
Private Sub Form_Open(Cancel As Integer)
     
    '各コントロールのイベントプロパティの設定
    With Me
        ![サイズ1].OnGotFocus = "=fncGetActiveTextbox(""サイズ2"",""サイズ3"")"
        ![サイズ1].OnKeyDown = "[イベント プロシージャ]"
        ![サイズ2].OnGotFocus = "=fncGetActiveTextbox(""サイズ3"",""サイズ1"")"
        ![サイズ2].OnKeyDown = "[イベント プロシージャ]"
        ![サイズ3].OnGotFocus = "=fncGetActiveTextbox(""サイズ1"",""サイズ2"")"
        ![サイズ3].OnKeyDown = "[イベント プロシージャ]"
    End With
         
End Sub
 
'[フォームの読み込み解除時]イベント
Private Sub Form_Unload(Cancel As Integer)
     
    Set txtActiveTextBox = Nothing
     
End Sub
 
'アクティブなテキストボックスへの参照を変数 txtActiveTextBox に渡し、
'テンキーの[+]キー及び[-]キーによるフォーカスの移動先を入れ換えるサブルーチン
Public Function fncGetActiveTextbox(NextControlName As String, _
                                    PreviousControlName As String)
 
    Set txtActiveTextBox = Nothing
    'アクティブコントロールのコントロールの種類に応じて分岐
    Select Case Me.ActiveControl.ControlType
        'テキストボックス
        Case acTextBox
            'アクティブコントロールへの参照を
            '変数 txtActiveTextBox に渡す
            Set txtActiveTextBox = Me.ActiveControl
            'テンキーの[+]キーによるフォーカスの移動先のコントロール名の取得
            strNextControlName = NextControlName
            'テンキーの[-]キーによるフォーカスの移動先のコントロール名の取得
            strPreviousControlName = PreviousControlName
        '上記以外
        Case Else
            '何もしない
    End Select
 
End Function
 
'変数 txtActiveTextBox が参照するテキストボックスの[キークリック時]イベント
Private Sub txtActiveTextBox_KeyDown(KeyCode As Integer, Shift As Integer)
     
    'クリックされたキーコードにより分岐
    Select Case KeyCode
        'テンキー[+]キー
        Case vbKeyAdd
            '入力されたキーを無効に
            KeyCode = 0
            '変数 strNextControlName と同じ名前の
            'コントロールにフォーカスを移動させる
            Me.Controls(strNextControlName).SetFocus
        'テンキー[-]キー
        Case vbKeySubtract
            '入力されたキーを無効に
            KeyCode = 0
            '変数 strPreviousControlName と同じ名前の
            'コントロールにフォーカスを移動させる
            Me.Controls(strPreviousControlName).SetFocus
    End Select
 
End Sub
-----------------------------------------------------------------------------
 
あらゆるフォームに対して上記と同様の機能を割り当てられるようにしたい、
ということであれば、標準モジュールではなくクラスモジュールの出番に
なると思います。
( WithEvents キーワードは標準モジュールでは使用出来ない)

回答
投稿日時: 17/02/17 20:39:52
投稿者: jung

邪道かもしれないけどこんな方法も
  
Formのキーボードイベント取得を「はい」にしておき
(これをしないとFrom_KeyDown発生せず)
  
フォームモジュール
Private Sub From_KeyDown(KeyCode As Integer, Shift As Integer)
    Call S_TenKeyTab(KeyCode)
End Sub
  
標準モジュール
Public Sub S_TenKeyTab(ByRef pmKey As Integer)
    Select Case pmKey
        'テンキー「+」タブ移動
        Case vbKeyAdd
            pmKey = 0
            SendKeys "{TAB}"
        'テンキー「-」タブ移動
        Case vbKeySubtract
            pmKey = 0
            SendKeys "+{TAB}"
    End Select
End Sub

回答
投稿日時: 17/02/17 22:25:58
投稿者: sk

引用:
Formのキーボードイベント取得を「はい」にしておき
(これをしないとForm_KeyDown発生せず)

・テンキーの[+]キー及び[-]キーによるフォーカス遷移が
 適用されるべきコントロール適用すべきではないコントロールがある。
 
・[Tab]キーや[Enter]キーによる既定のフォーカス遷移におけるフォーカスの移動先と
 テンキーの[+]キー及び[-]キーによるフォーカス遷移におけるフォーカスの移動先は
 明確に異なる。
 
・[Tab]キーや[Enter]キーによる既定のフォーカス遷移は
 あくまで通常通りに実行されなければならない。
 
という点を考慮する必要があるでしょう。

投稿日時: 17/02/18 09:50:47
投稿者: hanasakura

sk様、jung様ご回答ありがとうございます。
私には高度すぎて、理解するのに時間がかかっております。
質問したいことがあるかもしれないので、もう少し解決済みにせず保留にさせていただきます。
ご指導本当にありがとうございました。

投稿日時: 17/02/21 15:18:16
投稿者: hanasakura

解決済みが遅くなり申し訳ありません。
sk様、時間がかかりましたがようやく動きが理解できました。
jung様
SendKeys "{TAB}" は質問する前に検索したのですが、どのように使うか分からなかったのでスルーしたものでした。ありがとうございました。
sk様、jung様の本当にありがとうございました。