スポンサーリンク
はじめに
CSVファイルなどのテキストファイルをExcel VBAで扱う(内容を読み取る、書き込む)方法について、記事を書いてきた。
さてCSVファイルというのは、カンマ文字で区切られたテキストファイルのことだけど、通常はカンマで区切られた項目数が各行で一定になっている。
たとえば下の例なら、各項目を
姓,名,生年月日,都道府県,電話番号
の順でカンマで区切って、各行の項目数が5個で一定になっている。
末永,文一,1961/8/28,岐阜県,090-4144-1812
金澤,揚子,1979/11/1,青森県,080-7267-7926
山之内,英明,1982/12/19,熊本県,090-7050-8296
浜田,友香,1980/7/17,高知県,090-9782-2847
そして私がCSVファイルを扱うときは、特定の列の項目に加工を施したいということが多い。
たとえば上記の例なら、4列目の項目「都道府県」の末尾に「出身」という文字を加えて
末永,文一,1961/8/28,岐阜県出身,090-4144-1812
金澤,揚子,1979/11/1,青森県出身,080-7267-7926
山之内,英明,1982/12/19,熊本県出身,090-7050-8296
と書き換えたCSVにしてしまいたいという感じだ。
縦に何十行もある複雑なCSVファイルなんかでは、たったこれだけのことが意外に難しい。
ソースコード
そこで今回は、これまでの記事で扱ったことの組み合わせで、
(1)CSVファイルをInputで読み込み用に開き、Line Inputで1行ずつ読み込む
(2)CSVファイルをOutputで書き込み用に開き、Printで書き込む
と、読み込みと書き込みを一連の流れで実施して、CSVファイルの4列目の項目の末尾に「出身」という文字を加える処理を実施するマクロを書いてみた。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
Option Explicit Dim arrOpenFiles As Variant Dim fileNum As Long Function fncCSVOpen() As Boolean '処理する前に、ファイルを開くか確認する Dim i As Long With Application.FileDialog(msoFileDialogFilePicker) .Filters.Clear .Filters.Add "CSVファイル", "*.csv" .AllowMultiSelect = True '複数選択可能 If Not .Show Then Exit Function '選択されたファイル数に合わせ、配列の要素数を定義 fileNum = .SelectedItems.Count ReDim arrOpenFiles(1 To fileNum) '選択されたファイルを配列に格納 For i = 1 To fileNum arrOpenFiles(i) = .SelectedItems(i) Next i End With fncCSVOpen = True '実行フラグをセット End Function Sub writeToNewCSV() '******************************************************* '複数のCSVファイルについて、 '1)内容を1行ずつ読み込んで、 '2)4カラム目の末尾全てに「出身」の文字を追加していき、 '3)新規ファイルに結合して書き込む '******************************************************* 'Functionで処理実行を確認 If Not fncCSVOpen Then Exit Sub 'ファイル名に現在時刻を入れたテキストファイルを新規作成 '拡張子は ".txt"や ".csv"など適宜変更する。 Dim newTextFile As String newTextFile = ThisWorkbook.Path & "\新規" & Format(Now, "yyyymmddhhmmss") & ".csv" Open newTextFile For Output As #1 '書き込み用ファイルとして開く Dim eachFile As Variant Dim var As Variant Dim arrCommaSplit As Variant For Each eachFile In arrOpenFiles Open eachFile For Input As #2 '内容取得用に開く var = FreeFile Do Until EOF(2) 'Line Input で1行ずつ読み込み Line Input #2, var 'カンマ区切りで配列に格納する。 '配列の添字を1開始にするため、先頭に余分なカンマ文字を追加している arrCommaSplit = Split("," & var, ",") '4カラム目の末尾に「出身」の文字を追加 arrCommaSplit(4) = arrCommaSplit(4) & "出身" '修正を加えた配列を、Joinで再度、カンマ文字で結合 'ただし先頭に余分なカンマ文字を1つ加えてあるので、Midで2文字目から開始することでそれを削除 '書き込み用テキストファイル(#1)に書き込み var = Join(arrCommaSplit, ",") Print #1, Mid(var, 2) Loop Close #2 '読み込み用CSV(#2)を閉じる Next eachFile Close #1 '書き込み用CSV(#1)を閉じる End Sub |
解説
今回はそこそこ長いソースコードなので、CSVファイルを開く処理について、fncCSVOpenというプロセス(Function)に別途分けてみた。こういうやり方については、こちらを参照。
テキストファイルを開くに当たっては、ファイルの空き番号というやつ取得しないといけなくて、通常は#1として取得すれば良い。
しかし今回は、読み込み用と書き込み用の2つを同時に開くので、#1・#2の2つを割り当てた。
Joinで1次元配列の中身を結合した文字を作成
また今回は、Joinという処理を使っている。
このJoinは、配列(正確には1次元配列)の中身を、区切り文字を指定して結合するものだ。
今回、arrCommaSplitという配列の、4個目の項目の末尾に「出身」という文字を追加する修正を施したわけだが、それにより配列arrCommaSplitは次のような感じになる。
arrCommaSplit(1)= “谷野”
arrCommaSplit(2)= “聡美”
arrCommaSplit(3)= “1976/12/19”
arrCommaSplit(4)= “兵庫県出身”
arrCommaSplit(5)= “080-0608-0695”
これだけなら配列arrCommaSplitは、「谷野」とか「兵庫県出身」とかいう要素を個別に含んでいるだけの代物だ。
CSVファイルに書き込むに当たってこれら個別の要素を、カンマ文字を媒介として繋げた文字列にしないといけない。つまり
var = Join(arrCommaSplit, “,“)
という処理で、配列arrCommaSplitの各要素をカンマ文字「,」で繋ぎ合わせた
そしてそれを、Print によって書き込み用CSVファイルに書き込んでいる。
スポンサーリンク