最初からやる気をそいでしまいますが、「CSVはVBAを使わなくてもエクセルで読み込めます!」
しかしCSVにもいろいろなタイプの物があります。標準の機能で読み込むことが出来ないCSVもたくさん存在します。
マクロはあなたの書き方によって柔軟さを使い分けることが出来ます。決まったことを決まったようにさせるマクロも書けますし、状況に応じた挙動をさせることも出来ます。
今回は様々なCSV読み込みができるように柔軟性たっぷりのマクロをVBAで組んでいきましょう!
VBAで柔軟なCSV読み込み
まず標準の機能を呼び出すマクロを書きます。その後CSVの読み込みに柔軟さを加えながらVBAで記述していきます。
1.CSVを用意します
これをsample.csvとしてCドライブのルートに保存します。
2.VBAでのファイルの読み込み
VBAではLine Inputステートメントを用います。VBAのファイル関連の操作でFileSystemObjectを使うことも多いのですが、テキストファイルの読み込みに関してはVBAのLine Inputを使ったほうが簡潔に読み込みできます。
今回使用したファイルはこちらになります。
CSVParse.xlsm
型宣言等は割愛するとして3行目にLine Inputステートメントがあります。
定義は
Line Input #<>, <>
です。
<
で、<
最後にワークシートに読み込んだ結果を出力しています。
読み込みの終了条件はテキストファイルの最後まで読み込みが完了した時。その条件はDo Until制御文とEOF(<
次はVBAで得られた文字列を整形していきましょう。
3.CSVを表データに直して読み込みをする
CSVは次のような形になっています。このデータを読み込みましょう。
CSVはこちら→sample.csv
マクロデータはこちら→CSVParse.xlsm
1010047,東京都,千代田区,内神田
つまりデータが「 , 」で区切られている状態です。こういった時のために用意してあるのがSplit()関数です。
Split(expression[, delimiter[, count[, compare]]])
expression 区切り対象文字列です。String型
delimiter 区切り文字です。String型
注意点としてSplit関数は配列を返します。配列を返す関数はVariant型の変数で受け取るのがルールになっています。
修正したマクロが次になります。
Line Inputステートメントで読み込みしたデータを受け取る変数をBufに変更しました。そしてBufをSplit関数により「 , 」で区切った結果をTargetに渡しています。
Targetは配列になり、配列の末尾インデックスはUBound(variable)関数で取得できるためFor文で回しています。最初のインデックスは特に設定しない限り0と決まっているので、そのようにしました。ちなみに最初のインデックスは
LBound(variable)で取得できます。
しかしカンマ区切りのCSVだけではありません。中にはカンマとスペースを組み合わせた区切りのCSVやタブ区切りのCSVも存在します。次ではVBAでそれらを読み込みしてみようと思います。
4.特殊な区切りのCSVへ対応するには
特殊な区切りのCSVを読み込みするにはSplit関数の区切り文字を変数にして、VBAで動的に変化させる他、あらかじめ置換によってフォーマットを整えておく方法もあります。今回は後者で読み込みましょう。
置換はReplace()関数で可能です。
Replace(expression, find, replace [, start[, count [, compare]]])
expression 置換対象の文字列です。String型
find 検索対象文字列です。String型
replace 置き換える文字列です。String型
これで特殊な区切りに対応しました。しかしタブ文字を打とうと思ったらフォーカスが移動してしまいますね。そのため「合言葉」を定義してマクロのほうで更に置換してあげましょう。
これでタブ文字にも対応しました。例えばタブ文字とカンマが組み合わせてある場合は「