Access VBAの「SetFocusエラー」を制する!安全なフォーカス移動の極意
こんにちは。現場の最前線でAccessと格闘している皆さん、お疲れ様です。
Access VBAを書いていると、必ずと言っていいほど直面するのが「実行時エラー 2110:このコントロールにフォーカスを移動することはできません」という壁です。
初心者のうちは「なぜ動かないんだ!」と頭を抱えますが、これはAccessが「表示されていないものや、操作できないものにはフォーカスを当てられない」という、至極真っ当なルールを守っているだけなんです。
今日は、この「SetFocusの悲劇」を二度と起こさないための、「安全なフォーカス移動」の設計術を伝授します。これさえ押さえれば、あなたのコードは格段にプロフェッショナルな安定感を放ち始めますよ。
—
なぜ「SetFocus」は失敗するのか?
まず、Accessの心臓部である「オブジェクトモデル」の考え方を理解しましょう。
フォーム上のコントロール(テキストボックスやボタンなど)は、「今、操作できる状態にあるか?」という厳格なライフサイクルを持っています。以下のいずれかに該当すると、`SetFocus` メソッドを呼んだ瞬間にAccessは悲鳴を上げ、エラーを吐き出します。
1. Visible = False(非表示になっている)
2. Enabled = False(使用不可になっている)
3. そもそもフォーム自体が開かれていない(またはアクティブでない)
つまり、力技で `Control.SetFocus` を叩き込むのではなく、「フォーカスを当てても大丈夫な状態か?」を確認するガードレールが必要なのです。
—
現場で使える「安全なSetFocus」関数
毎回 `If` 文でプロパティを確認するのは面倒ですよね。そこで、私たちアーキテクトは「汎用関数」として切り出します。これを標準モジュールに一つ置いておくだけで、開発効率は劇的に変わります。
‘ =================================================================
‘ 目的:安全にコントロールへフォーカスを移動する
‘ 引数:targetControl – フォーカスを当てたいコントロールオブジェクト
‘ 戻り値:成功した場合は True、失敗した場合は False
‘ =================================================================
Public Function SafeSetFocus(ByVal targetControl As Control) As Boolean
‘ 1. コントロールが本当に存在するか確認(念のため)
If targetControl Is Nothing Then Exit Function
‘ 2. Visible(表示)かつ Enabled(使用可能)かを確認するガード節
‘ ここがプロフェッショナルなコードの分かれ道です
If targetControl.Visible And targetControl.Enabled Then
On Error Resume Next ‘ 万が一の例外に備える
targetControl.SetFocus
If Err.Number = 0 Then
SafeSetFocus = True
End If
On Error GoTo 0
Else
‘ デバッグ用にイミディエイトウィンドウへ出力しておくと調査が楽になります
Debug.Print “フォーカス移動不可: ” & targetControl.Name
SafeSetFocus = False
End If
End Function
このコードの「賢いポイント」
- ガード節による早期判定: `Visible` と `Enabled` を一度にチェックすることで、エラーが発生する「前」に処理をスキップさせています。
- 戻り値による制御: 関数が `True` を返せば成功、`False` なら失敗とわかるため、呼び出し側で「失敗した時の代替案」を書くことができます。
- エラーハンドリング: `On Error Resume Next` を保険として使い、予期せぬロックにも対応しています。
—
実際に使ってみよう
例えば、特定のボタンを押した時に「名前」欄へ自動的にカーソルを飛ばしたい場合、以下のように書くだけです。
Private Sub btnInput_Click()
‘ 従来の書き方だとここでエラーになる可能性がある
‘ Me.txtUserName.SetFocus
‘ 安全な書き方
If SafeSetFocus(Me.txtUserName) Then
MsgBox “準備OK!入力してください。”
Else
MsgBox “入力欄が隠れているか、使用不可になっています。”
End If
End Sub
—
さらなる高みへ:設計のヒント
この「SafeSetFocus」をマスターしたら、次は「なぜそのコントロールがフォーカスを受け付けない状態なのか」という業務要件の設計に目を向けてみてください。
- 「入力を必須にする場合はEnabledを切り替える」
- 「ステータスに応じて表示・非表示を制御する」
といったUIの制御は、VBAのコードよりも「フォームのプロパティ設計」が重要です。VBAはあくまで、その設計を補助する「魔法の杖」だと考えてください。
まとめ:ここをクリアすれば大丈夫!
1. SetFocusは「エラーが起きる前提」で扱うこと。
2. Visible と Enabled のチェックを怠らないこと。
3. 汎用関数化して、コードをスッキリ保つこと。
Access VBAは、正しく扱えばこれほど頼もしい自動化ツールはありません。今日からあなたのコードにこの「安全な設計」を取り入れて、エラー知らずの快適な開発ライフを送りましょう。
何か不明な点があれば、いつでも聞いてくださいね。応援しています!
