【入門編】DAOのRecordsetCloneを活用したフォーム操作の効率化 – Access VBA解析バイブル

スポンサーリンク

こんにちは!Accessでのフォーム開発、日々お疲れ様です。
「フォームのデータを検索したい」「特定のレコードにジャンプしたい」と思ったとき、あなたならどうやってコードを書きますか?

まさか、検索のたびに `Me.RecordSource = “SELECT FROM … WHERE …”` なんて書き換えていませんよね……?

もしそれに心当たりがあるなら、ここから先の話はあなたのAccess開発の常識を根底からひっくり返すかもしれません。今回は、Accessのパフォーマンスと安全性を極限まで高める秘儀「RecordsetClone(レコードセットクローン)」の世界へご案内します。

ここをクリアすれば、あなたも「マクロの記録」や「力技のコード」を卒業した、ワンランク上のエンジニアの仲間入りです。一緒に優しく、深く、マスターしていきましょう!

—

1. なぜ「直接フォームをいじるな」と言われるのか?

Accessのフォームには、テーブルやクエリといった「データソース」が紐付いていますよね。
画面にデータを表示している本丸(フォーム自身)を直接操作して検索や絞り込みを行おうとすると、以下のような問題が発生します。

  • 画面のチラつきと描画負荷: フォームのデータソースを頻繁に書き換えると、その都度Accessは画面の再描画(UIの更新)を行い、動作が重くなります。
  • カレントレコードの迷子: 検索処理の途中で予期せぬレコード移動が起き、ユーザーが今どこを見ているのか分からなくなる現象が起きます。
  • コードの複雑化: エラーが起きたときのロールバックや状態の復元が非常に面倒になります。

そこで登場するのが、「RecordsetClone」です。

💡 RecordsetCloneの本質とは?

一言で言うと、「フォームの裏側で動いているデータ(レコードセット)の『分身(クローン)』をメモリ上にこっそり呼び出す機能」です。

  • 分身だから安全: 分身をどれだけいじり倒しても、大元のフォーム画面(本物)には直接影響しません。
  • 高速: 画面の描画を伴わないメモリ内での処理なので、圧倒的に高速です。
  • 同期している: 分身の位置(カレントレコード)を動かすと、なんと一瞬で本物のフォーム側もそのレコードに追従してジャンプしてくれます。

この「分身を操作して、本体をスマートに操る」というアーキテクチャこそ、プロのAccess開発者が好む王道の手法なのです。

—

2. 【実践】RecordsetCloneを使った超高速「レコード検索」

それでは、実際の現場で即戦力となるコードを見ていきましょう。
「顧客ID」を入力して、ボタンを押したら一発でその人のレコードにジャンプする機能を実装します。

以下のコードを、フォームに配置したコマンドボタンの「クリック時」イベントに記述してみてください。

Private Sub btnSearch_Click()
‘ 1. 変数の宣言(DAOのレコードセットを扱います)
Dim rs As DAO.Recordset
Dim searchID As Long

‘ 2. 検索ボックスから値を取得(未入力チェック付き)
If IsNull(Me.txtSearchID.Value) Then
MsgBox “検索する顧客IDを入力してください。”, vbExclamation, “入力エラー”
Exit Sub
End If
searchID = Me.txtSearchID.Value

‘ 3. フォームのRecordsetCloneをオブジェクト変数に代入
‘ ※ここで「New」を使ってはいけません!すでにある分身を「Set」で取得します。
Set rs = Me.RecordsetClone

‘ 4. 分身の中でデータを検索する(FindFirstメソッド)
‘ 「ID」というフィールドから searchID を探します
rs.FindFirst “ID = ” & searchID

‘ 5. 見つかったかどうかの判定
If rs.NoMatch Then
‘ 見つからなかった場合
MsgBox “該当する顧客IDが見つかりませんでした。”, vbInformation, “検索結果”
Else
‘ 見つかった場合:
‘ ★ここが魔法の瞬間!分身のブックマークをフォーム本体に教え込む
Me.Bookmark = rs.Bookmark

‘ ついでにフォーカスをそのテキストボックスに移すなど
Me.txtCustomerName.SetFocus
End If

‘ 6. 对象的解放(メモリリークを防ぐプロの作法)
Set rs = Nothing

‘ 「ここをクリアすればバッチリ!」ですね。
End Sub

コードの重要ポイント解説

1. `Set rs = Me.RecordsetClone`
フォームが持っているデータセットの分身を取得しています。新しくクエリを発行するわけではないので、データベースに負荷をかけません。
2. `rs.FindFirst “条件式”`
DAOの真骨頂である高速検索メソッドです。上から順に条件に合うレコードを探します。(※文字列を探す場合は `FindFirst “氏名 = ‘” & searchName & “‘”` のようにシングルクォーテーションで囲むのを忘れないように!)
3. `Me.Bookmark = rs.Bookmark`
ここが最大のキモです!分身(`rs`)で見つけた「位置(ブックマーク)」を、フォーム本体(`Me`)のブックマークに代入することで、一瞬でフォームの表示位置がそのレコードにジャンプします。

—

3. 陥りやすい罠とエラー回避の知見

プロの現場でよくある失敗パターンと、その対策もあわせて押さえておきましょう。

⚠️ 注意点1: 新規追加行(入力中の行)でのエラー

フォームが「新規レコード入力待ち(一番下の新しい行)」の状態にあるとき、`RecordsetClone`に対して検索を行うと、エラーが発生することがあります。

  • 対策: 検索を行う前に、もしフォームが新規入力中なら `Me.Dirty = False` (変更を保存)するか、一度既存のレコードにフォーカスを移してから実行するガード節を入れましょう。

⚠️ 注意点2: オブジェクトの解放(`Set rs = Nothing`)をサボらない

VBAの初心者がやりがちなのが、`Set rs = …` と取得したオブジェクトをそのまま放置することです。
Access(VBA)の裏側では、明示的に `Nothing` を代入してメモリを解放しないと、小さなメモリリークが蓄積し、長時間の稼働でAccessが不安定になる原因を作ります。プロフェッショナルは「使ったら必ず捨てる(解放する)」を徹底します。

—

まとめ

いかがでしょうか?
`RecordsetClone` と `Bookmark` を組み合わせたこの手法をマスターすると、あなたの作るAccessアプリは見違えるほど軽快で、プロフェッショナルな挙動に生まれ変わります。

  • 画面を直接いじらず、「分身(Clone)」を操作する。
  • 見つけたら `Bookmark` で本体をジャンプさせる。
  • 使い終わったら `Nothing` で綺麗に片付ける。

この3つさえ心に留めておけば、もうフォーム操作で迷うことはありません。
明日からのAccess開発に、ぜひこの知見をフル活用してみてくださいね。あなたのVBAライフを心から応援しています!

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