【VBScript極意】列順変更に負けない!ヘッダー名による動的マッピングでCSVを完全掌握する
こんにちは。自動化の現場で泥臭く、かつエレガントなコードを追求し続けているエンジニアです。
皆さんは、CSVの処理でこんな経験はありませんか?
「昨日まで動いていたバッチが、列の順番が少し変わっただけでエラーを吐くようになった……」
これはVBScriptでCSVを扱う際、列番号を直書き(`Split(line, “,”)(2)` のように)していることが最大の原因です。列番号に依存したコードは、仕様変更という名の爆弾を抱えているようなもの。
今回は、「ヘッダー名をキーにして、列の順番が変わってもビクともしない堅牢なCSV解析術」を伝授します。ここをマスターすれば、あなたの書くスクリプトは一気に「プロの品質」へと進化します。
—
なぜ「Dictionaryオブジェクト」を使うのか?
VBScriptには、データを管理するための最強の武器「`Scripting.Dictionary`」が存在します。
これは「キー」と「値」のペアを保存する連想配列です。
- 列番号で管理: 「3番目のデータを取り出す」→ 順序が変わると崩壊する。
- ヘッダー名で管理: 「”単価”という名前のデータを取り出す」→ 順序が変わっても名前さえ合っていれば安全。
この考え方を実装に落とし込みます。
—
【実戦コード】動的マッピングCSVパーサー
以下のコードは、1行目のヘッダーを読み取り、どの列名が何番目にあるかを自動的に記憶(マッピング)する設計です。
‘ — CSV解析エンジンの核心部分 —
Option Explicit
Dim fso, file, line, headers, colMap
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set colMap = CreateObject(“Scripting.Dictionary”)
‘ CSVを開く
Set file = fso.OpenTextFile(“data.csv”, 1) ‘ 1 = ForReading
‘ 1. ヘッダー行を読み取り、マッピングを作成
If Not file.AtEndOfStream Then
line = file.ReadLine
headers = Split(line, “,”)
Dim i
For i = 0 To UBound(headers)
‘ 列名をキーに、インデックス(番号)を値として登録
colMap(Trim(headers(i))) = i
Next
End If
‘ 2. データ行を読み取り、安全に取得
Do Until file.AtEndOfStream
line = file.ReadLine
Dim data : data = Split(line, “,”)
‘ 列番号を直接書かず、colMap経由で取得する
‘ これにより、CSV側の列順が変わってもコード修正は不要!
If colMap.Exists(“商品名”) Then
WScript.Echo “商品名: ” & data(colMap(“商品名”))
End If
If colMap.Exists(“単価”) Then
WScript.Echo “単価: ” & data(colMap(“単価”))
End If
Loop
file.Close
—
コードのここがポイント!
1. `colMap(Trim(headers(i))) = i` の魔法
ここで、CSVの1行目にある「列名」と「その位置(インデックス)」を辞書に登録しています。`Trim`を入れているのは、CSV作成ソフトによって混入する不要な空白(スペース)を除去し、マッチング精度を高めるための「プロの配慮」です。
2. `colMap.Exists(“商品名”)` での安全確認
万が一、CSVから特定の列が削除されていた場合、いきなりデータへアクセスすると「添字が範囲外です」というエラーでスクリプトが停止します。`Exists`で確認することで、エラーを未然に防ぎ、必要に応じて「列がありません」とログを出すような柔軟な制御が可能になります。
—
初学者が陥りやすい罠と解決策
罠:ダブルクォーテーションで囲まれたカンマ
CSVの中に `”, “` のようなカンマが含まれている場合、単純な `Split` 関数では分割が狂います。
現場で本格的なCSVを扱う場合は、`Split` ではなく、正規表現(`RegExp`)を使うか、ADO(ActiveX Data Objects)を使って「データベースとしてCSVを開く」手法を推奨します。
罠:エンコーディング問題
日本語が含まれるCSVの場合、VBScriptの標準的な読み込みでは文字化けすることがあります。特にUTF-8のCSVを扱う際は、`ADODB.Stream` オブジェクトを使ってエンコーディングを指定して読み込むのが、トラブルを避ける鉄則です。
—
最後に:一歩先のエンジニアへ
今回紹介した「Dictionaryを使った動的マッピング」は、VBScriptだけでなく、PythonやPowerShellなど、あらゆる言語で通用する「データ処理の定石」です。
「動くコード」を書くのは簡単です。しかし、「仕様変更に強く、誰が読んでも意図が伝わるコード」を書くことが、私たちエンジニアの価値です。
まずはこのコードをコピペして、お手元のCSVで実験してみてください。列の順番を入れ替えても、あなたのスクリプトが涼しい顔でデータを抽出した瞬間、あなたはVBScriptを一つ上の段階で使いこなせているはずです。
何か不明点があれば、いつでも聞いてくださいね。あなたの自動化ライフを心から応援しています!
