VBAでセル内改行を含むUTF-8のCSVを取込む


やりたいこと

UTF-8のCSVをエクセルに取り込んで、CSVの値をブックに転記します。
元のCSVファイルにはセル内改行が含まれています。セル内改行コードを含んだままCSVファイルをインポートするVBAを作ります。

CSVを取込む方法

VBAでCSVを取込む方法はいくつかあります。
今回は、CSVの文字コードがUTF-8だったこと、セル内改行があること、ゼロ落ちを防ぐことから、CreateObject関数を使用します。

Openメソッド
Openメソッドで取り込むと、ゼロ落ちしてしまいます。携帯電話番号だと09012345678が9012345678となってしまい、もとのCSVデータと値が変わってしまうため採用しませんでした。

OpenTextメソッド
UTF-8のcsvを取込むと文字化けが発生します。おそらくエクセル固有のバグのようです。txtに変換すると文字化けしないようですが、変換は煩雑なので採用しませんでした。

QueryTables.Add関数
CSVの1項目ずつ読み込みます。セル内改行があると、ブックに転記する時に改行され、取り込んだCSVデータのレイアウトが崩れてしまいます。QueryTables.Addではセル内改行に対応できないため、採用しませんでした。

CreateObject関数
CSVの文字コード指定ができて、セル内改行でも取り込んだ際にレイアウトが崩れないため、CreateObject関数を採用しました。

ソースコード

Sub Sample1()
    Dim buf As String, Target As String
    Target = "C:\Users\xxxx\Desktop\list.csv"
    With CreateObject("ADODB.Stream")
        .Charset = "UTF-8" '文字コードの指定
        .Open
        .LoadFromFile Target
        buf = .ReadText
       .Close
    End With

    Dim AddressData As Variant
    Dim v As Variant
    Dim i As Long

    'AddressDataの改行コードは「vbLf」だったので、「vbLf」ごとに分割
    'サクラエディタで改行位置にカーソルを合わせるとフッターバーに改行コードを確認できる
    AddressData = Split(buf, vbLf)

    'Uboundは配列に入っている値の数を返す関数
    For i = 0 To UBound(AddressData)

        'AddressDataのCSVの最後の行にカラ行がある。カラ行になったら処理を終了する
        If Len(AddressData(i)) > 0 Then

            'AddressDataはセミコロン区切り。セミコロンで分割する
            v = Split(AddressData(i), ";")

            'Offsetプロパティを用いて、A1セルからi個をずらした行に値を入力
            'Ubound(v)で何個分データが入っているかを計測。Resizeを用いて、データに入っている項目分だけセル分割
            Range("A1").Offset(i).Resize(, UBound(v) + 1).Value = v
        End If
    Next
End Sub