「データの『鮮度』か、『速度』か」——ADO CursorTypeを掌握して、プロのAccess開発者へ
こんにちは。よくここまで辿り着きましたね。
マクロの記録から一歩踏み出し、「自分でコードを書きたい」と願うその向上心こそが、エンジニアとしての最初の、そして最も重要な資質です。
Access VBAを学んでいると、必ずと言っていいほど「DAO(ディー・エー・オー)」と「ADO(エー・ディー・オー)」という二つの言葉に出会います。
「どちらを使えばいいのか?」「なぜか動きが重い」「他の人が更新したデータが反映されない……」
そんな壁にぶつかっているあなたに、今日は「CursorType(カーソルタイプ)」という、データの見え方を決定づける極めて重要な概念を伝授します。
ここをクリアすれば、あなたの作るアプリケーションの品質は、一気に「ツール」から「プロのシステム」へと昇華するはずですよ。
1. そもそも、DAOとADOは何が違うのか?
本題に入る前に、まずは地図を手に入れましょう。DAOとADOの違いを理解していないと、コードの海で迷子になってしまいます。
- DAO (Data Access Objects):
Accessの「ネイティブ」な技術です。Accessの内部構造に最適化されており、Accessファイル(.accdb)を操作するなら、もっとも高速で安定しています。いわば「地元に精通したベテラン」です。
- ADO (ActiveX Data Objects):
Accessの外の世界(SQL ServerやOracle、Web APIなど)と通信するための「共通言語」です。データの種類を問わず、同じ書き方で操作できる柔軟性を持っています。いわば「世界中どこでも通用する外交官」です。
「Access内だけで完結するならDAO、外部のデータベースと連携するならADO」というのが基本戦略です。今回は、柔軟性の高いADOの挙動について深掘りしていきます。
2. 「カーソル」とは、データの「窓」である
ADOでデータを読み込むとき、私たちは「Recordset(レコードセット)」というオブジェクトを使います。このレコードセットが、データベースから取り出したデータの塊を指し示す「窓」のような役割を果たします。
この「窓」の性質を決めるのが、`CursorType` プロパティです。
イメージしてください。あなたは今、大きな図鑑(データベース)を読んでいます。
- 静的カーソル (Static Cursor): 図鑑を開いた瞬間のページを「写真に撮って」眺めている状態。
- 動的カーソル (Dynamic Cursor): 図鑑を「リアルタイムで直接」見ている状態。
この違いが、実務において致命的な差を生むのです。
3. CursorTypeの使い分け:速度か、鮮度か
実務でよく使う、代表的なカーソルタイプを比較してみましょう。
① 静的カーソル (`adOpenStatic`):スピード重視の「スナップショット」
データを開いた瞬間の状態をメモリ上にコピーして保持します。
- メリット: 非常に高速。一度読み込めば、その後データベースがどう変わろうと、手元のデータは変わりません。
- デメリット: 他のユーザーがデータを更新・追加しても、あなたの画面には反映されません(「鮮度」がない)。
- 使い所: 集計処理、レポート作成、データの読み取り専用画面など。
② 動的カーソル (`adOpenDynamic`):リアルタイムの「ライブビュー」
データベースの現在の状態を常に追いかけます。
- メリット: 他のユーザーが追加したレコードや、変更した内容が即座に反映されます(「鮮度」が最高)。
- デメリット: 常に「最新はどうなっているか?」とデータベースに問い合わせ続けるため、動作が重くなります。また、ネットワーク負荷も高まります。
- 使い所: 複数人が同時に同じデータを編集する、リアルタイム性が求められる管理画面など。
③ 前方専用カーソル (`adOpenForwardOnly`):最速の「一方向通行」
最初から最後まで、一度読み飛ばしたら戻れない、最も軽量なタイプです。
- メリット: メモリ消費が最小限で、圧倒的に速い。
- デメリット: 「前のレコードに戻る」といった操作ができません。
- 使い所: 大量のデータを順番に処理して計算するだけのプログラムなど。
4. 【実践】CursorTypeを切り替えるVBAコード
では、実際にどのようにコードを書くのか見てみましょう。
以下のコードは、接続設定からカーソルタイプの指定までを網羅したテンプレートです。
Option Explicit
' ADOを使用するための参照設定が必要です:
' Microsoft ActiveX Data Objects x.x Library
Sub DemonstrateCursorTypes()
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strConn As String
Dim strSQL As String
' 1. 接続文字列の設定 (Accessファイルに接続する例)
' ※ご自身の環境に合わせてパスを書き換えてください
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & CurrentProject.FullName & ";"
' 2. SQL文の準備
strSQL = "SELECT * FROM T_社員マスタ"
On Error GoTo ErrorHandler
' Connectionオブジェクトの生成とオープン
Set cn = New ADODB.Connection
cn.Open strConn
' --- パターンA: 静的カーソル (adOpenStatic) ---
' 処理速度を優先し、読み取り専用に近い形でデータを扱う場合
Set rs = New ADODB.Recordset
rs.CursorType = adOpenStatic ' ★ここがポイント!
rs.LockType = adLockOptimistic ' 更新を許可する設定
Debug.Print "--- 静的カーソルでオープン ---"
rs.Open strSQL, cn
If Not rs.EOF Then
Debug.Print "現在の社員名: " & rs!社員名
End If
' 読み込みが終わったら閉じる
rs.Close
Set rs = Nothing
' --- パターンB: 動的カーソル (adOpenDynamic) ---
' 他者の更新をリアルタイムに反映させたい、インタラクティブな操作の場合
Set rs = New ADODB.Recordset
rs.CursorType = adOpenDynamic ' ★ここがポイント!
rs.LockType = adLockOptimistic
Debug.Print "--- 動的カーソルでオープン ---"
rs.Open strSQL, cn
' (ここで他のユーザーがデータを書き換えると、rs.Requery等で反映される)
If Not rs.EOF Then
Debug.Print "現在の社員名(ライブ): " & rs!社員名
End If
' クリーンアップ
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
MsgBox "処理が正常に完了しました。", vbInformation
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
If Not rs Is Nothing Then If rs.State = adStateOpen Then rs.Close
If Not cn Is Nothing Then If cn.State = adStateOpen Then cn.Close
Set rs = Nothing
Set cn = Nothing
End Sub
コードの解説と陥りやすい罠
1. `rs.CursorType` の指定: ここで `adOpenStatic` か `adOpenDynamic` を選ぶことで、プログラムの挙動が劇的に変わります。
2. `rs.LockType`(ロックタイプ): カーソルタイプとセットで考えましょう。`adLockOptimistic`(楽観的ロック)は、「編集が終わるまでは他の人に邪魔させないけれど、書き込む瞬間だけロックをかける」という、現代的な効率の良いやり方です。
3. エラーハンドリング: データベース操作は、ネットワーク断絶やファイルロックなど、予期せぬエラーがつきものです。必ず `On Error GoTo` で、エラー時に `Connection` や `Recordset` を適切に閉じる(`Close` する)処理を書いてください。これを怠ると、「Accessがファイルを開いたままになっていて、他の人が開けない!」というトラブルの原因になります。
5. アーキテクトからのアドバイス:迷った時の指針
「結局、どっちを使えばいいの?」と迷ったら、この基準に従ってください。
- 「計算して、結果を出して、終わり」の処理なら
👉 `adOpenStatic`(または `adOpenForwardOnly`)を選んでください。無駄な通信を減らし、ユーザーを待たせないのがプロの仕事です。
- 「画面を開いたまま、誰かが更新したのをパッと見せたい」なら
👉 `adOpenDynamic` を検討してください。ただし、データ量が多い場合は、動作がガタガタになるリスクを覚悟し、必要最小限の範囲に絞って使用しましょう。
おわりに
CursorTypeの使い分けを理解することは、単なる文法の習得ではありません。「データの性質を理解し、システムのリソース(メモリや通信)をどう配分するか」という、設計思想に触れることなのです。
最初は難しく感じるかもしれません。でも、実際にコードを書いて、動作の重さの違いを肌で感じてみてください。その経験こそが、あなたを「マクロ使い」から「真のエンジニア」へと変えてくれます。
ここをクリアすれば、Access VBAの基本はバッチリですよ。
次の一歩へ、自信を持って進んでくださいね。応援しています!
