CSVとはカンマ・セパレート・バリューの名の通り値と値をカンマ( , ) で区切る約束のファイル形式ですが、業務をしていると値のなかにカンマが入っていることもあると思います。
そういうファイルはCSVとしての体裁を保つために値をダブルクォーテーションで囲っており、ダブルクォーテーションが閉じた次のカンマを区切り文字として使っています。
こういう形式のCSVでも、業務でCSVやエクセルを使っていると業務効率化のためスクリプトを組もうというのが自然の摂理ですよね。
ですが、値の中にカンマが入っていると困ってしまうのです。
というのも、VBAでは値をゴニョニョするときは変数に入れた方が早いという原則(思い込み)がありますから、カンマでsplitして要素を配列に入れていこうとする訳です。
そういうわけで、上述のようなファイルだと想定外の結果になってしまうわけですね。
そこで、ダブルクォーテーションとカンマの組み合わせに着目したCSV読み込みスクリプトを考えることにしたのです。
コード
Public Sub output_csv(CSV_path As String, sheet_name As String, dest_sheet As Worksheet)
' CSVヘッダー検査とCSVの中身が入った変数の用意し書き込み
' 引数:CSVのパス、 シート名、書き込み先シート
' 戻り値:CSVの内容が入った変数
Dim c As Long
Dim str_line As String
Dim arr_line() As String
Dim quot_line As String
Dim quot_cnt As Long
Dim quot_match As String
Dim index_cnt As Long
Dim result As Boolean
' csvファイルをオープン
Open CSV_path For Input As #1
' 文中のカンマに対応するためダブルクォーテーションで判定する
c = 1
Do Until EOF(1)
Line Input #1, str_line
index_cnt = 0
quot_line = ""
' ダブルクオーテーションの中のカンマを無視してquot_lineにいれる
quot_cnt = 0
Dim q As Long
For q = 1 To Len(str_line)
quot_match = Mid$(str_line, q, 1) ' Mid$でstring型で返せる
' ダブルクォーテーションの時カウントアップ
If quot_match = """" Then ' "は""で囲んで"でエスケープする
quot_cnt = quot_cnt + 1
' ダブルクォーテーションカウントが奇数なら文字結合
ElseIf quot_cnt Mod 2 = 1 Then
quot_line = quot_line & quot_match
' 偶数ならquot_lineをarr_lineにいれてから初期化
Else
ReDim Preserve arr_line(index_cnt)
arr_line(index_cnt) = quot_line
index_cnt = index_cnt + 1
quot_line = ""
End If
Next q
' 最後の列を格納
ReDim Preserve arr_line(index_cnt) ' 要素数を追加
arr_line(index_cnt) = quot_line ' 1レコードを配列に追加
' ヘッダーチェックしてFalseだったら終了
If c = 1 Then
result = check_headers(sheet_name, arr_line) 'ヘッダーチェック用の別関数
If result = False Then
to_end
End
End If
End If
' 書き込み
Dim i As Long
For i = 0 To UBound(arr_line)
dest_sheet.Cells(c, i + 1).Value = arr_line(i)
Next i
c = c + 1
Loop
Close #1
End Sub
CSVファイルの例としては
"属性1","属性2","属性3"
"2020/11/04","営業部","1,000円"
みたいなやつです。
“1,000円”なんてふうに来られちゃうとちょっと疲れますね。
紹介しといてなんですが、上記コード遅い気がしています。
ファイルを1行ずつチェックしてカウントして配列増やしたり値を分けたりなのでこんなもんかとも思いますが、もっと早い処理あるんでしょうか?
ところで、私は非IT系の企業で社内SEしているわけですが意外と皆さんCSVというものが何なのかは知っているんですよね。
私は新卒でSIer企業に入ってシステムに触れるようになって初めて知ったんですがうちの社員がどこでCSVに触れているのか謎・・・
コメント