Microsoft Access 掲示板

PDF表示後、SetFocus が効かない

7 コメント
137 views
4 フォロー

初めて質問させていただきます。

SetfFocusでテキストBOXにフォーカスをあてたいのですが、フォーカスが移動せず困っています。

フォーム上には、「テキストBOX」,「コマンドボタン」、「PDFを表示するWEBブラウザ」
を配置しております。

動作概要は、
①バーコードリーダーで「テキストBOX」にコードを入力し、
②「コマンドボタン」をクリックしたら、
③PDFを「WEBブラウザ」に表示したまま、
④「テキストBOX」にフォーカスを戻す
というものです。

この一連の動作をバーコードリーダーの1クリックで行いたいのですが、④のところでSetFocusを使ってもフォーカスが行方不明の状態となります。〈①~③は期待通りに動作〉(マウスポインタは表示している)
なにが原因で動作しないのでしょうか?
アドバイスをお願いします。

■検証したこと
・SetFocus後に Screen.ActiveControl.Name で確認してみると、「テキストBOX」となっている
・「テキストBOX」の“フォーカス取得時"イベントに MsgBox "hello"と記述しても表示されない
・setfocus後にkeycode=0 を記述したが、変化なし
・ダミーのコマンドボタンを作成してからVBAで飛ばしたが変化なし(実際にダミーボタンをクリックするとフォーカスは移動します)

以下、記述です。実際の名称は下記3行となります。

テキストBOX名    = コード検索
コマンドボタン名  = コマンド24
WEBブラウザ名     = PDF表示

Private Sub コード検索_LostFocus()
Call コマンド24_Click
End Sub

Private Sub コマンド24_Click()
Dim code As String
Dim StrPass As String ''PDFファイルフルパスを入れる変数
Dim imagePass As String 'imageを入れる変数
Dim GKfolder As String  '現物カンバンフォルダ
Dim NGfolder As String
Const GF As String = "c:\PDF\現物カンバン\"
imagePass = Dir(GF & "image.PDF")
NGfolder = GF & imagePass

    If IsNull([Forms]![フォーム1]![コード検索]) Then
         MsgBox "品目コードが入力されてません"      
         [コード検索].SetFocus
    Else
        code = [Forms]![フォーム1]![コード検索]
        StrPass = Dir(GF & code & "*.pdf")                  '現物カンバン あいまい検索
        GKfolder = GF & StrPass                             '現物カンバンファイルパス

         '********* PDF表示 *******************************************************
         If Dir(GF & code & "*.pdf") <> "" Then
            ' MsgBox "OK"
           Me.PDF表示.ControlSource = "=" & Chr$(34) & GKfolder & Chr$(34)
         Else
           '  MsgBox "NG"
           Me.PDF表示.ControlSource = "=" & Chr$(34) & NGfolder & Chr$(34)
         End If
         '**********************************************************************
         [Forms]![フォーム1]![コード検索] = Null
         [Forms]![フォーム1]![コード検索].SetFocus
     End If
End Sub
はなまる ごりざえもん
作成: 2025/02/23 (日) 14:46:33
最終更新: 2025/02/23 (日) 16:17:08
通報 ...
1
hatena 2025/02/24 (月) 18:20:51 修正

バーコードリーダーは「コード検索」テキストボックスにコードを読み込んだあと、EnterキーとかTabキーを送信して次のコントロールへ移動する仕様でしょうか。
で、ご希望のことは、バーコードリーダーで「コード検索」テキストボックスにコードを読み込んだ後、コントロール移動せずに「コード検索」テキストボックスにフォーカスをとどめておきたいということでしょうか。

もし、そうだとすると、
コード検索_LostFocusイベント内で、コード検索.SetFocus しても無意味です。
LostFocusイベント(フォーカス喪失後)内では、まだ、フォーカス移動はしていない、つまりコード検索にフォーカスがある。
LostFocusイベント終了後に、次のコントロールへフォーカス移動します。
フォーカス移動関係のイベント内でフォーカス移動のコントロールしようというのは無理があります。。

もし、フォーカス移動関連イベントで、フォーカス移動させないようにするには、Exitイベント(フォーカス喪失時)でイベントをキャンセルすることになります。

Private Sub コード検索_Exit(Cancel As Integer)
    Call コマンド24_Click
    Cancel = True
End Sub

ただし、これをするといったんコード検索にフォーカス移動したら二度とそこから出ることができなくなるので、
バーコードリーダーでデータを読み込んだときのみ Cancel = True するような条件処理が必要です。
こちては仕様が不明ですのて、その条件はそちらで考えてください。

最初の私の推測がことなっているなら、その辺の仕様をもう少し詳細に説明してください。

2
はなまる ごりざえもん 2025/02/24 (月) 21:58:14 fd0b4@9d10d

hatena さん
早速のご回答ありがとうございます。
フォーカスを「コード検索」テキストボックスにとどめておくというこではございません。

バーコードリーダーは「コード検索」テキストボックスにコードを読み込んだあと、Tabキーを送信する仕様です。
ですので、バーコードリーダーを1回クリックすると、「コマンド24」ボタンにフォーカスが移動し、
「コード検索」のLostFocusイベントで、「コマンド24」をクリックさせる。
クリックさせることによってPDF表示させて「コード検索」に戻すという動作になります。
コントロールを「コード検索」⇒「コマンド24」⇒「PDF表示」⇒「コード検索」に戻すということです。
「PDF表示」までは動作しており、最後「コード検索」にフォーカスがあたりません。
(コントールは移動しているが、フォーカスがあたってない?)

ただ、「PDF表示」後の

     [Forms]![フォーム1]![コード検索] = Null

は効いています。コントロールは移動しているということでしょうか。

1つ気になるのは、PDF表示させている「WEBブラウザ」コントロールを表示させたままだからなのかなと思いましたが、
関係ないでしょうか。

ご教授をお願いいたします。

3
hatena 2025/02/25 (火) 09:39:40 修正

 バーコードリーダーは「コード検索」テキストボックスにコードを読み込んだあと、Tabキーを送信する仕様です。
ですので、バーコードリーダーを1回クリックすると、「コマンド24」ボタンにフォーカスが移動し、
「コード検索」のLostFocusイベントで、「コマンド24」をクリックさせる。
クリックさせることによってPDF表示させて「コード検索」に戻すという動作になります。

 読み込み前は「コード検索」にフォーカス、読み込み後も最終的には「コード検索」にフォーカスといういことですよね。

ひょっとするとCall コマンド24_Clickはコマンド24にフォーカスがないと有効でないと勘違いしているのかな?
Call コマンド24_Clickはコマンド24にフォーカスがなくても実行されます。

前の回答でもいいましたが、LostFocusイベント内で「コード検索」に戻すことはできません。
繰り返しになりますが質問のコードだと詳細に説明すると下記のような動作になります。

コード検索_LostFocusイベント発生(コード検索にフォーカスがある状態)
  Call コマンド24_Click実行
    「WEBブラウザ」にPDF表示

    [Forms]![フォーム1]![コード検索].SetFocus
     ↑この時点ではコード検索にフォーカスがある状態なので無意味なコマンド

コード検索_LostFocusイベント終了後
  Tabキーの動作により次のコントロール(コマンド24)にフォーカス移動

つまり、LostFocusイベント内でSetFocusを実行しても無意味ということです。

そして、最終的に「コード検索」にフォーカスがある状態にしたいのなら、Exitイベント(フォーカス喪失時)でイベントをキャンセルします。

とりあえず下記のコードで想定の動作になりませんか。

Option Compare Database
Option Explicit
Dim コード検索更新 As Boolean

Private Sub コード検索_AfterUpdate()
    Debug.Print コード検索.Value
    コード検索更新 = True
End Sub

Private Sub コード検索_Exit(Cancel As Integer)
    '更新されていて、かつ、12桁の数字(JANコードを想定)になっている
    If コード検索更新 = True And Me.コード検索.Text Like "############" Then
        Cancel = True  'イベントのキャンセル
        Call コマンド24_Click
    End If
    コード検索更新 = False
End Sub

Private Sub コマンド24_Click()
  '以下略

バーコードリーダーは利用したことがないのであくまで想像で書いたコードですので想定の動作になるかは分かりません。
また、12桁のJANコードという想定が書いていますので、実際のコードの仕様に合わせて変更してください。

4
はなまる ごりざえもん 2025/02/25 (火) 23:34:44 fd0b4@9d10d

hatena さん

再度のご回答ありがとうございます。
おっしゃる事が理解できたような気がします。
SetFocusでフォーカス移動させた気になっていましたが、結局はTABキーによる移動しかしていなかったということですね。
各所で「Screen.ActieControl.Name」でメッセージ表示させてみましたが、「コード検索」と表示されていました。
無意味なSetFocusコマンドだということがわかりました。

そこで、ご提示いただいたコードを試してみましたが、やはりフォーカスがどこにもあたっていない状態となってしまいます。
Exitイベント(フォーカス喪失時)でキャンセルするイベントとは何にあたるのでしょうか。

恥ずかしながら無知なまま作成しておりますので、大変お手数をおかけしますが、
引き続きご教授をお願いいたします。

ところで、私が言うフォーカスがあたっていないという症状は下記の通りですが、
フォーカルがあたらないという表現で良かったのでしょうか。

 ①「コード検索」でカーソルが表示してしない
 ②キーボード操作を受け付けない
 ③マウスポインタは表示している
 ④マウスポインタを「コード検索」にあて、クリックするとカーソル表示される

5

ところで、私が言うフォーカスがあたっていないという症状は下記の通りですが、
フォーカルがあたらないという表現で良かったのでしょうか。

 ①「コード検索」でカーソルが表示してしない
 ②キーボード操作を受け付けない
 ③マウスポインタは表示している
 ④マウスポインタを「コード検索」にあて、クリックするとカーソル表示される

WEBブラウザコントロールを配置したサンプルを作成して実験したら症状が再現しました。
WEBブラウザのコントロールソースを設定するとフォーカスが消えてしまうような感じですね。

同一フォーム内がWEBブラウザコントロールあると症状が発生するようなので、
別フォームにWEBブラウザコントロールを配置して、そのフォームをサブフォームとして配置してみたら、
フォーカスは消えるという症状は発生せずうまく動作するようになりました。

試してみてはどうでしょう。

7
はなまる ごりざえもん 2025/02/26 (水) 23:33:55 fd0b4@9d10d >> 5

hatena さん
毎度、素早い回答ありがとうございます。
再現して頂いたのですね。悩みを共有してもらえる方に出会えてとても嬉しく思います。
また、サブフォームを使うという具体的な対策まで提示して頂き、大変感謝しております。
早速、試してみます。
どうもありがとうございました。

hiroton  さん
丁寧な解説ありがとうございます。
ExitイベントでCancel = True を設定したときの動作について、理解できました。
私のような初心者には、このような場はてとも助かります。
深く感謝いたします。

6
hiroton 2025/02/26 (水) 07:09:21 bdb5b@75660

Exitイベント(フォーカス喪失時)でキャンセルするイベントとは何にあたるのでしょうか。

各イベントは「ACCESSが」管理しています。通常、Exitイベントが終了するとLostFocusイベントが発生し、次のコントロールにフォーカスが移動し、そのコントロールのEnterイベント等が発生します
Exitイベントにより実行されるxxx_ExitプロシージャでCancel = Trueを設定すると、この、「Exitイベントが完了後、ACCESSが次に実行する制御」が中断されます


Webブラウザコントロールの制御が怪しいということで、hirotonもちょっと試してみましたが、かなり怪しいですね
ブラウザの読み込み処理などでおかしなことになっているような感じです。DoEvents等加えると、また違った挙動が発生します。hatenaさん提示のとおり、フォームを変える(サブフォームにする)ことで対応できるならそうしたほうがよさそうです