1. トランザクション処理時の注意点
特にテーブルと直接紐づいたフォームで、トランザクション処理を実行する場合の注意点。
勢いあまって?やりそうなのが次のような指定。
Dim ws As DAO.WorkSpace
Set ws = DBEngine.Workspaces(0)
ws.BeginTrans ' トランザクション開始
Dim qd As QueryDef
Set qd = CurrentDb.QueryDefs("クエリー1")
qd.Execute
・・・・
ws.CommitTrans ' トランザクションコミット
Set qd = Nothing
Set ws = Nothing ' ⇒これは絶対やっちゃダメ!(>_<)
Visual Basic Editorの画面から、オブジェクトブラウザーで"Workspace"の構成を調べるとわかりますが、オブジェクト"Workspace"の配下には、オブジェクト"Databases"が存在します。
つまり、上記のようにWorkspaceにNothingを指定⇒内容をクリアすることで、該当フォームで使っているCurrentDbが使えなくなるのです。
2. ForwardOnlyタイプ
OpenRecordsetなどでレコードセットをオープンするとき、指定するタイプには
・結果集合の参照のみのとき:SnapShot
・結果集合の更新ありのとき:DynaSet
を指定することが多いようですが、大量データを参照する必要があるときはForwardOnlyタイプの使用も検討するとよいでしょう。
<ForwardOnlyタイプのレコードセットの特徴>
・結果集合の参照のみ可能
・メソッドMoveFirst/MoveLastは指定不可。MoveNextのみ指定可(実行時エラーになります)
・RecordsetCountの値が当てにならない・・・次項参照
・他のレコードセットタイプより処理速度が高速
※参考:OpenRecordset メソッドのレコードセットタイプを比べる(T'sWare)
その性格上、例えばマスタレコードを全件走査して・・・といったバッチ処理などに使うと有効でしょう。
3. RecordSet.RecordCountのワナ
Recordsetオブジェクトには"RecordCount"というプロパティがあって、いかにも
「いつでもレコードセットの件数を格納している!」
というような名前なんですが、その扱いには注意が必要です。
例)テーブル"tablea"には7,500件のレコードが格納されています
Dim rs As DAO.Recordset
' Tableタイプでオープン
Set rs = CurrentDb.OpenRecordset("testa", dbOpenTable)
Debug.Print "Table 処理開始:" & rs.RecordCount
Do While (Not rs.EOF)
rs.MoveNext
Loop
Debug.Print "Table 処理終了:" & rs.RecordCount
' SnapShotタイプでオープン
Set rs = CurrentDb.OpenRecordset("testa", dbOpenSnapshot)
Debug.Print "Snapshot 処理開始:" & rs.RecordCount
Do While (Not rs.EOF)
rs.MoveNext
Loop
Debug.Print "Snapshot 処理終了:" & rs.RecordCount
' ForwardOnlyタイプでオープン
Set rs = CurrentDb.OpenRecordset("testa", dbOpenForwardOnly)
Debug.Print "ForwardOnly 処理開始:" & rs.RecordCount
Do While (Not rs.EOF)
rs.MoveNext
Loop
Debug.Print "ForwardOnly 処理終了:" & rs.RecordCount
(実行結果)
Table 処理開始:7500
Table 処理終了:7500
Snapshot 処理開始:1
Snapshot 処理終了:7500
ForwardOnly 処理開始:1
ForwardOnly 処理終了:-1
つまり、
・Tableタイプ:常にレコードセットの件数を保持
・Snapshotタイプ:アクセス済の件数を保持
・ForwardOnlyタイプ:???
という仕様になっているようです。
とはいえ、Tableタイプ以外でもレコードの存在有無には使えるわけで、うまく使いこなすことが大切でしょう。