【入門編】フォームの「RecordsetClone」と「Bookmark」を同期させ、非連結フォームで検索結果を表示するテクニック – Access VBA解析バイブル

スポンサーリンク

こんにちは! Access VBAの開発現場で、日々フォームやクエリと格闘していませんか?

「検索窓を作ったはいいものの、検索のたびにフォームのデータソース(レコードソース)を書き換えていたら、画面がチラついたり、思わぬところでエラーが出たりする……」
そんな壁にぶつかったことはありませんか?

実は、プロの現場では、フォームのデータソースを直接汚さずに、スマートに検索結果を同期させる「RecordsetClone(レコードセットクローン)」と「Bookmark(ブックマーク)」という強力な武器を使います。

ここをクリアすれば、あなたもマクロの記録から完全に脱却し、ワンランク上のAccessエンジニアの仲間入りです。さあ、一緒に本質をマスターしていきましょう!

1. なぜ「データソースの直接書き換え」は危険なのか?

検索機能を実装するとき、多くの初心者がやってしまいがちなのが、以下のようなコードです。

‘ 駄目な例:検索のたびにフォームのデータソースを書き換えている
Me.RecordSource = “SELECT FROM T_顧客 WHERE 顧客名 Like ‘” & Me.txt検索 & “‘”
Me.Requery

一見すると動くように思えますが、これには大きなデメリットがあります。

  • フォームの「現在の状態」がリセットされる(カレントレコードが先頭に戻ってしまう)。
  • マルチユーザー環境においてロックやパフォーマンスの面で不利になる。
  • フォームが持っている本来の「入力・編集用」という役割と、「検索・表示用」という役割が混ざってしまい、コードがスパゲッティ化する。

これを解決するのが、「フォームの表示はそのままに、裏で持っているコピー(クローン)を操作し、その位置を本体に教え込ませる」というテクニックです。

2. 核心に迫る!「RecordsetClone」と「Bookmark」の正体

このテクニックの仕組みを、図解的にイメージしてみましょう。

[ Accessフォーム (画面) ]

├─ 表示されているデータ (そのまま維持!)

▼ 同期! (Bookmarkの受け渡し)

[ RecordsetClone (メモリ上のコピー) ]

└─ ここで「検索・絞り込み」を行う

1. RecordsetCloneとは?
フォームが現在開いているレコードセットの「双子の兄弟(コピー)」をメモリ上に呼び出すプロパティです。このクローンを操作しても、画面上のフォームの表示はビクともしません。
2. Bookmarkとは?
レコードセット内の「特定の1行(レコード)」をピンポイントで指し示す、いわば「しおり(ブックマーク)」です。

この2つを組み合わせると、「裏側のクローンで検索して目的のレコードを探し、その『しおり』をフォーム本体に渡すことで、画面の表示位置をピタッと合わせる」という神業が可能になります。

3. 実践!検索結果をスマートに同期させるコード例

それでは、実際のフォームに実装するコードを見ていきましょう。
ここでは、「T_顧客」テーブルから「顧客名」の部分一致検索を行い、該当するレコードにフォームをジャンプさせるシナリオを想定しています。

フォームに配置するコントロール:

  • 検索キーワードを入力するテキストボックス:`txt検索`
  • 検索を実行するボタン:`btn検索`

Private Sub btn検索_Click()
Dim rs As DAO.Recordset

On Error GoTo ErrorHandler

‘ 1. フォームのクローン(双子の兄弟)をオブジェクト変数に取得する
Set rs = Me.RecordsetClone

‘ 2. クローン側で、入力されたキーワードをもとにレコードを検索する
‘ ※ここではDAOのFindFirstメソッドを使用します
Dim 検索条件 As String
If Trim(Me.txt検索.Value) = “” & “” Then
‘ 検索ワードが空の場合は何もしないか、全件表示に戻す等の処理
MsgBox “検索ワードを入力してください。”, vbExclamation, “入力チェック”
Exit Sub
End If

検索条件 = “顧客名 Like ‘” & Me.txt検索.Value & “‘”
rs.FindFirst 検索条件

‘ 3. 該当するデータが見つかったか判定する
If rs.NoMatch Then
MsgBox “該当するデータは見つかりませんでした。”, vbInformation, “検索結果”
Else
‘ 4. ★ここが最重要!★
‘ クローンの「しおり(Bookmark)」を、フォーム本体の「しおり」に代入する
Me.Bookmark = rs.Bookmark

‘ ※これによって、画面上のフォームが「一瞬で」該当レコードにジャンプします!
End If

CleanUp:
‘ 5. オブジェクト変数を解放し、メモリリークを防ぐ(プロの必須作法)
Set rs = Exit Sub

ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
Resume CleanUp
End Sub

4. コードの深掘りポイントとプロの知見

上記のコードで、特に意識してほしいポイントを解説します。

① `Me.Bookmark = rs.Bookmark` の魔法

フォームの `Bookmark` プロパティに、クローン側(`rs`)の `Bookmark` を代入した瞬間、Accessは自動的に画面上の表示をその行へスクロールさせ、カレントレコードを移動させます。
ループを使って1行ずつ `MoveNext` するような野暮ったいコードを書く必要は一切ありません。一瞬で処理が完了します。

② メモリの解放(`Set rs = Nothing`)を怠らない

Access VBAにおいて、`DAO.Recordset` などのオブジェクト変数を生成したら、処理の最後で必ず `Nothing` を代入してメモリを解放するのが鉄則です。これをサボると、長期間アプリを稼働させた際にメモリリーク(メモリの無駄遣い)を引き起こし、Access全体の動作が重くなる原因になります。

まとめ:ここをクリアすれば、Access VBAの基本はバッチリです!

今回は、フォームの「RecordsetClone」と「Bookmark」を同期させ、データソースを汚さずに検索結果を反映させるテクニックをご紹介しました。

  • フォームのデータソースを直接書き換えない
  • 検索はメモリ上の `RecordsetClone` で行う
  • 見つけた位置を `Bookmark` でフォーム本体に教え込む

この3つの原則さえ押さえておけば、どれだけデータ量が増えても軽快に動作する、プロフェッショナルな画面設計ができるようになります。

「マクロの記録」や「力技のコード」から卒業し、Accessのオブジェクトモデルを自在に操る楽しさを、ぜひあなたの開発現場でも体感してください。応援しています!

タイトルとURLをコピーしました