【入門編】DoCmd.TransferTextの「仕様書(インポート定義)」をVBAで動的に切り替える運用 – Access VBA解析バイブル

スポンサーリンク

こんにちは!Accessでのシステム開発、日々のデータ取り込みにお疲れ様です。

「取引先A社から届くCSV」と「B社から届くCSV」で、項目の並び順や区切り文字が違う……。そのたびにAccessの「インポート定義」を手動で作り直していませんか? あるいは、マクロの記録のまま固定された処理に頭を悩ませていませんか?

ここをクリアすれば、Access VBAの基本はバッチリですよ。今回は、`DoCmd.TransferText`のインポート定義をVBAから華麗に動的に切り替え、何種類ものバラバラなCSVをたった一つのプロシージャで飲み込む、実戦的なテクニックを伝授します。

伝説のアーキテクトが現場の知見を込めて、優しく、そして深く解説していきますね。

なぜ「インポート定義の動的切り替え」が必要なのか?

Accessで外部のCSVファイルを取り込むとき、最も頼りになるのが `DoCmd.TransferText` メソッドです。
このメソッドには、第2引数に「インポート定義名(スペック名)」を指定する仕組みがあります。

通常、Accessの画面から「詳細設定」を開いて保存したインポート定義は、固定の文字列としてコードにベタ書きされがちです。しかし、世の中のCSVフォーマットは千差万別。ファイルごとに処理用のプロシージャを何個も作るのは、エンジニアとしてナンセンスです。

「ファイル名やデータの種類に応じて、使うインポート定義をVBA側でパッと切り替えられたら……?」

これを実現するのが、今回のテーマです。まずは、Accessオブジェクトモデルの基本からしっかり押さえていきましょう。

基礎知識:ApplicationオブジェクトとCurrentDbの立ち位置

Access VBAを書く上で、絶対に外せない基本概念があります。それが `Application`(世界を統べる神)`CurrentDb`(今開いているデータベースへの直通回線) です。

  • `DoCmd` オブジェクト

これは `Application.DoCmd` の省略形です。AccessのUI(画面)で行うような操作(フォームを開く、レポートを印刷する、ファイルを取り込むなど)を裏側で代行してくれる、いわば「優秀な作業員」です。`DoCmd.TransferText` もこの作業員にお願いする仕事の一つです。

  • `CurrentDb` 関数

現在開いているAccessファイルそのものを指し示すオブジェクトを返します。テーブルやクエリ、そして後述する「インポート定義」といったシステム内部のデータ構造(シス・テーブル)をプログラムから操作するときに必須となります。

実践!動的インポート切り替えシステムの設計

では、具体的なシナリオを考えてみましょう。
今、フォルダの中に以下のような2種類のCSVが届くとします。

1. 売上データ(CSV):インポート定義名 `”ImportSpec_Sales”` を使う
2. 顧客データ(CSV):インポート定義名 `”ImportSpec_Customers”` を使う

これらをファイル名の一部で判定し、自動的に適切なインポート定義を割り当てて取り込むVBAコードを組み立てます。

コピペで使える実用コード

以下のコードを、標準モジュールに貼り付けてみてください。現場でそのまま使えるよう、エラーハンドリングも考慮した堅牢な設計にしています。

Option Compare Database
Option Explicit

‘ =========================================================================
‘ 概要: CSVファイルの名称に応じてインポート定義を動的に切り替え、取り込むプロシージャ
‘ ターゲット読者: マクロからVBAへのステップアップを目指す開発者の皆様へ
‘ =========================================================================
Public Sub ExecuteDynamicImport()

On Error GoTo ErrorHandler

Dim strFolderPath As String
Dim strFileName As String
Dim strFullPath As String
Dim strSpecName As String
Dim strTargetTable As String

‘ 1. フォルダパスの指定(環境に合わせて書き換えてください)
strFolderPath = CurrentProject.Path & “\Data\”

‘ 2. フォルダ内のCSVファイルを総なめにする準備(Dir関数を使用)
strFileName = Dir(strFolderPath & “.csv”)

If strFileName = “” Then
MsgBox “対象となるCSVファイルが見つかりません。”, vbExclamation, “ファイルなし”
Exit Sub
End If

‘ 3. ファイルをループ処理
Do While strFileName <> “”
strFullPath = strFolderPath & strFileName

‘ — 【核心】ファイル名によるインポート定義と保存先テーブルの動的切り替え —
If strFileName Like “Sales_.csv” Then
‘ 売上データの場合
strSpecName = “ImportSpec_Sales” ‘ あらかじめAccess上で作成したインポート定義名
strTargetTable = “T_Sales_Raw” ‘ 取り込み先テーブル名

ElseIf strFileName Like “Customer_.csv” Then
‘ 顧客データの場合
strSpecName = “ImportSpec_Customers” ‘ あらかじめAccess上で作成したインポート定義名
strTargetTable = “T_Customers_Raw” ‘ 取り込み先テーブル名

Else
‘ どのパターンにも当てはまらない場合はスキップ
Debug.Print “スキップされたファイル: ” & strFileName
GoTo NextFile
End If

‘ 4. 既存のテーブルデータをクリアする(必要に応じて)
‘ ※実務ではTRUNCATEの代わりにSQLでDELETEを実行するのが安全です
CurrentDb.Execute “DELETE FROM ” & strTargetTable & “;”, dbFailOnError

‘ 5. 【実行】DoCmd.TransferTextによる動的インポート
‘ 構文: DoCmd.TransferText [転送の種類], [インポート定義名], [テーブル名], [ファイル名], [見出しの有無]
DoCmd.TransferText acImportDelim, strSpecName, strTargetTable, strFullPath, True

Debug.Print strFileName & ” を ” & strTargetTable & ” へ (定義: ” & strSpecName & “) 取り込みました。”

NextFile:
‘ 次のファイルを取得
strFileName = Dir()
Loop

MsgBox “すべてのファイルのインポートが正常に完了しました!”, vbInformation, “処理成功”
Exit Sub

ErrorHandler:
‘ 予期せぬエラーをキャッチし、ユーザーに優しく通知する
MsgBox “エラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “致命的なエラー”

End Sub

コードの注目ポイントと「陥りやすい罠」

上記のコードには、Access VBAを極めるためのエッセンスが凝縮されています。特に初学者がハマりがちなポイントをいくつか解説しておきましょう。

1. `Dir`関数の挙動に注意せよ

`Dir(strFolderPath & “.csv”)` で最初のファイルを取得し、ループ内で引数なしの `Dir()` を呼ぶことで次のファイルを取得しています。この仕組みは非常に強力ですが、ループの途中で別の `Dir` を呼び出すようなネスト(入れ子)処理を行うと、ファイル名が狂うという致命的なバグを生みます。単一のループで完結させるのが鉄則です。

2. インポート定義名(スペック名)は大文字小文字・スペースに厳格

`strSpecName = “ImportSpec_Sales”` 部分で指定している文字列は、Accessのナビゲーションウィンドウ(または旧バージョンの「ファイル」タブ等で見られる外部データ定義)に登録されている名前と一字一句一致していなければなりません。
もし名前が間違っていると、`TransferText` は冷酷にエラーを吐き出します。不安な場合は、あらかじめAccess上で手動インポートをウィザードで行い、そこで保存した正確な定義名をコピペしてください。

3. トランザクションとエラーハンドリング

外部ファイルを取り込む処理は、途中でCSVの列数が足りなくなったり、データ型の不一致(数値を入れるべき場所に文字列が入っているなど)で止まるリスクが常にあります。
今回のコードでは `On Error GoTo ErrorHandler` を仕込んでいますが、実務の現場ではさらに `CurrentDb.BeginTrans` などを駆使して、「すべて成功するか、一切変更しないか(ロールバック)」のトランザクション制御を組み合わせると、よりプロフェッショナルなシステムになります。

さいごに:マクロからの卒業は、業務の自由度を爆発させる

「マクロの記録」ボタンを押して作られた自動処理は、言わば「決まったレールの上を走るトロッコ」です。便利ですが、少しでもレイアウトが変わったり、ファイルが増えたりすると脱線してしまいます。

今回紹介したように、ファイル名や条件をVBAの変数(`String`型など)で受け渡し、`DoCmd.TransferText` の引数を動的にコントロールする。たったこれだけのことで、あなたのAccessシステムはどんな変則的なCSVの要求をも軽々と受け止める「柔軟なモンスターマシン」へと生まれ変わります。

ここをクリアしたあなたなら、もうAccess VBAの基礎はバッチリです。ぜひ自分の開発環境に組み込んで、その快適さを体感してみてください。
エンジニアとしての次のステージへ、一緒に進んでいきましょう!

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