【入門編】DAO.Recordsetの「Type」プロパティを用いた、汎用的なデータインポート・エクスポート処理 – Access VBA解析バイブル

スポンサーリンク

Access VBAを掌握せよ:DAO.Recordsetの「Type」でデータ転送を極める

こんにちは。システム開発の現場で、泥臭いデータの山と格闘し続けてきたエンジニアです。

Accessを使っていて「テーブルAのデータをテーブルBにコピーしたいだけなのに、型が合わなくてエラーになる」「フィールドが増えるたびにコードを書き直すのが面倒」と悩んだことはありませんか?

今日は、そんな皆さんのために、「DAO.RecordsetのTypeプロパティ」を使い、データの型を自動判別して安全に転送する、汎用的なインポート・エクスポート手法を伝授します。これさえ理解すれば、Access VBAの「オブジェクト操作」という中枢を掌握したも同然です。

なぜ「DAO.Recordset」なのか?

Access VBAには `DoCmd.RunSQL` や `INSERT INTO` といったSQL文を使う方法もありますが、現場で本当に強いのは DAO(Data Access Objects) です。

なぜなら、DAOは「データの行を、メモリ上で一つずつ手に取って確認できるから」です。SQLは一気に処理しますが、DAOは「一歩ずつ」処理する。この「一歩ずつ」の過程で型を判定することで、予期せぬエラーを未然に防ぐ堅牢な仕組みが作れるのです。

核心:フィールドの型を判定する「Type」プロパティ

Accessのテーブルにある各フィールドには、`dbText`(文字列)、`dbLong`(数値)、`dbDate`(日付)といった「型」が設定されています。

この型情報をプログラムから取得できるのが `Fields(i).Type` です。これを使うと、例えば「転送先が数値型なら、空文字は0に変換して入れる」といった、気の利いた処理が書けるようになります。

実践:汎用データコピープロシージャ

それでは、実際のコードを見てみましょう。このコードは、ソース(元データ)からターゲット(転送先)へ、フィールド名を一致させて値をコピーします。

Public Sub CopyDataGeneric(sourceTable As String, targetTable As String)
Dim db As DAO.Database
Dim rsSource As DAO.Recordset
Dim rsTarget As DAO.Recordset
Dim i As Integer

Set db = CurrentDb
Set rsSource = db.OpenRecordset(sourceTable, dbOpenSnapshot)
Set rsTarget = db.OpenRecordset(targetTable, dbOpenDynaset)

‘ データが空なら終了
If rsSource.EOF Then Exit Sub

Do While Not rsSource.EOF
rsTarget.AddNew ‘ 新規レコードを追加

‘ フィールドをループして値をコピー
For i = 0 To rsSource.Fields.Count – 1
Dim fldName As String
fldName = rsSource.Fields(i).Name

‘ ターゲットに同じフィールドが存在するか確認して値をセット
If FieldExists(rsTarget, fldName) Then
‘ ここが肝:型判定と安全な代入
‘ Null値の扱いはエラー回避の鉄則です
If IsNull(rsSource.Fields(i).Value) Then
rsTarget.Fields(fldName).Value = Null
Else
‘ ここで「型」に応じた変換処理を挟むことも可能
rsTarget.Fields(fldName).Value = rsSource.Fields(i).Value
End If
End If
Next i

rsTarget.Update ‘ 確定
rsSource.MoveNext
Loop

‘ オブジェクトの解放(メモリ管理の基本!)
rsTarget.Close
rsSource.Close
Set rsTarget = Nothing
Set rsSource = Nothing
End Sub

‘ 指定したレコードセットにフィールドが存在するか確認する補助関数
Private Function FieldExists(rs As DAO.Recordset, fldName As String) As Boolean
Dim f As DAO.Field
On Error Resume Next
Set f = rs.Fields(fldName)
FieldExists = (Err.Number = 0)
On Error GoTo 0
End Function

開発現場で陥りやすい「罠」と対策

1. 「型が一致しません」エラーの正体

一番多いのは、テーブルの「空文字(””)」と「Null」の混同です。

  • 対策: `If IsNull(value) Then …` を徹底してください。DAOはNullを許容しないフィールドにNullを突っ込もうとすると即座にエラーを吐きます。

2. メモリリーク(解放忘れ)

`Set rs = Nothing` を疎かにすると、Accessが重くなったり、最悪の場合はファイルが破損します。

  • 対策: 「開いたら必ず閉じる、そしてNothingにする」。これは職人の作法です。

3. 「フィールドが存在しません」エラー

転送先のテーブル構造が変わった瞬間にプログラムが落ちるのは悲劇です。

  • 対策: 今回紹介した `FieldExists` 関数のようにお節介なチェック機能を挟むことで、コードの生存期間が飛躍的に伸びます。

最後に:ここをクリアすれば、あなたはもう「脱・初心者」

この汎用的なコピー処理を自力で書けるようになったあなたは、もう「マクロの記録」に頼るだけのユーザーではありません。「データの構造をプログラムで制御するエンジニア」の一歩を踏み出しました。

Access VBAの真髄は、こうした「泥臭いデータの橋渡し」をいかに自動化し、エラーを排除するか、という点にあります。ぜひ、ご自身のプロジェクトでこのコードを走らせてみてください。

もしエラーが出ても怖がらないで。それは、プログラムがあなたに「ここを直せばもっと良くなるよ」と教えてくれているサインですから。応援しています!

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