【入門編】DAO.Field.Attributesを解析し、自動採番(AutoNumber)フィールドをVBAで特定する – Access VBA解析バイブル

スポンサーリンク

こんにちは! Access VBAの世界へようこそ。
マクロの記録ボタンを押すだけの世界から一歩踏み出し、自分の手でAccessのエンジンを自在にコントロールしたいと思っているあなたへ。

今回は、Access VBAの真骨頂とも言える「DAO(Data Access Objects)を使ったテーブル構造の動的解析」について、魂を込めて解説します。

ここをクリアすれば、単なる「言われた通りに動くコード」ではなく、「どんなテーブル構造の変化にも耐える、頭の良い汎用プログラム」が書けるようになりますよ。しっかりついてきてくださいね!

なぜ「自動採番フィールド」をコードで特定する必要があるのか?

Excelからデータをインポートしたり、外部システムと連携したりするツールを作ったことはありませんか?
その時、こんな壁にぶつかったはずです。

> 「あれ? インポート先のテーブルに『オートナンバー(自動採番)』のフィールドがあるせいで、VBAから直接データを追加しようとするとエラーになっちゃう……!」

そう、オートナンバー型のフィールドは、Accessが勝手に番号を振る場所なので、人間(あるいはVBA)が勝手に値を書き込むことができません。

もし、テーブルの設計が変わるたびに「ええっと、何番目の列がオートナンバーだっけ?」とVBAのコードを書き直していたら、エンジニアとしての寿命が縮まってしまいますよね。

だからこそ、「VBAにテーブルの中身を覗かせ、自動採番フィールドがどこにあるかを自発的に見つけ出させる」仕組みが必要なのです。

魔法のキーワードは `DAO.Field.Attributes`

Accessの裏側でデータをガッチリ支えているエンジンが DAO(Data Access Objects) です。
テーブルの列(フィールド)の性質は、すべて `DAO.Field` というオブジェクトに詰まっています。

そして、そのフィールドが「どんな性格をしているか(主キーなのか、必須なのか、自動採番なのか)」をビット単位で保持しているのが、`Attributes`(属性)プロパティです。

自動採番を見抜くビット演算の秘密

`Attributes` プロパティは、複数のフラグを足し合わせたような数値を持っています。
そのため、自動採番(AutoNumber)であるかどうかを判定するには、「定数 `dbAutoIncrField` が含まれているか」をビット演算(`And`演算子)で調べる必要があります。

言葉で説明するより、コードを見たほうが早いですね。実際の判定ロジックを見てみましょう。

実践:自動採番フィールドを自動特定するVBAコード

以下のコードを標準モジュールに貼り付けて実行してみてください。
現在開いているデータベースの中にある特定のテーブルを解析し、どのフィールドが自動採番(オートナンバー)なのかを教えてくれます。

Option Explicit

‘ =====================================================================
‘ プロシージャ名: CheckAutoNumberField
‘ 概要: 指定したテーブルのフィールドを走査し、自動採番フィールドを特定する
‘ =====================================================================
Sub CheckAutoNumberField()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Dim targetTableName As String

‘ 解析したいテーブル名を指定(ご自身の環境のテーブル名に変更してください)
targetTableName = “T_商品マスタ”

‘ 現在のデータベースへの参照を取得(CurrentDbは呼ぶたびにインスタンスが変わるため変数に格納するのが鉄則)
Set db = CurrentDb

On Error GoTo ErrorHandler

‘ テーブル定義を取得
Set tdf = db.TableDefs(targetTableName)

Debug.Print “=== 【” & targetTableName & “】の構造解析結果 ===”

‘ すべてのフィールドをループで総チェック
For Each fld in tdf.Fields

‘ 【重要】Attributesプロパティと dbAutoIncrField をAND演算して判定する
If (fld.Attributes And dbAutoIncrField) = dbAutoIncrField Then
Debug.Print ” [発見!] フィールド名: ” & fld.Name & ” は「自動採番」です。”
Else
Debug.Print ” [通常] フィールド名: ” & fld.Name
End If

Next fld

Debug.Print “========================================”

‘ 後片付け
Set fld = Nothing
Set tdf = Nothing
Set db = Nothing
Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
Set fld = Nothing
Set tdf = Nothing
Set db = Nothing
End Sub

コードの深掘り解説:プロが教える「3つの急所」

上記のコードには、Access VBAを極める上での重要なエッセンスが詰まっています。初学者がハマりやすいポイントと合わせて解説します。

1. `CurrentDb` は変数に受けて使え!

コード内で `Set db = CurrentDb` としていますね。
`CurrentDb` は呼び出すたびに新しいデータベースオブジェクトのインスタンスをメモリ上に生成します。
ループの中で毎回 `CurrentDb.TableDef…` などと書くと、メモリリークの原因になり、パフォーマンスが劇的に低下します。オブジェクトは変数に入れて使い回す、これがプロの鉄則です。

2. ビット演算 `(fld.Attributes And dbAutoIncrField)` の意味

`Attributes` は、一つの数値の中に「主キーである」「必須入力である」「自動採番である」といった複数の意味を詰め込んでいます。
例えるなら、お弁当の「ハンバーグ、唐揚げ、目玉焼き入り」のような状態です。
「このお弁当に唐揚げが入っているか?」を調べるために `And` 演算子を使い、特定のフラグが立っているかを正確に検知しています。

3. エラーハンドリングの重要性

存在しないテーブル名を指定したり、リンクテーブルで予期せぬ挙動があった場合、VBAは容赦なく停止します。`On Error GoTo` を仕込んでおき、オブジェクトの開放(`Set … = Nothing`)を必ず通るようにする構造化が、実務では絶対に必要です。

この知見をどう実務の「インポートツール」に活かすか?

ここまでの技術が身につけば、冒頭で話した「汎用的なデータインポートツール」の核心部分が作れます。

たとえば、外部のCSVデータをDAOのレコードセット(Recordset)を使ってテーブルに追加する際、以下のようなロジックを組むことができます。

1. インポート先テーブルの `TableDefs.Fields` をループする。
2. そのフィールドが 自動採番(`dbAutoIncrField`) なら、CSVからの流し込み対象から除外する。
3. 自動採番でなければ、CSVの対応する列のデータをそのまま `Add` する。

これさえできれば、「オートナンバー型があるからインポートエラーになる」という現場の悲鳴を、美しいコードで一発解決できるようになります。

まとめ

今回は、`DAO.Field.Attributes` を解析し、自動採番フィールドを特定する手法について解説しました。

  • DAOを使うことで、Accessのテーブル構造をプログラムから自由自在に覗き見ることができる。
  • `Attributes` と `dbAutoIncrField` のビット演算により、自動採番フィールドを完璧に特定できる。
  • オブジェクトは変数に格納し、メモリとパフォーマンスに配慮したコードを書く。

ここをクリアしたあなたなら、もう「マクロの記録の卒業生」ではありません立派なAccess VBAエンジニアです。
ぜひ、ご自身の業務システムに応用して、まわりの人を驚かせてあげてくださいね。それでは、次のステップでお会いしましょう!

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