エクセルVBAで文字コードUTF-8のCSVファイルを書き出す方法


write

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

エクセルのデータを様々なファイルに書き出す方法についてお伝えしています。

以前、こちらの記事でCSV形式で書き出す方法を紹介しました。

エクセルVBAでセルが結合されているかどうか、またそのセルの数を判定する方法
エクセルVBAでセルが結合されているかどうか、またその結合されているセルの数を判定する方法を紹介します。また結合セルがある場合のエクセル表をHTML形式に出力するプログラムも合わせて紹介します。

しかしながら、残念ながらこの方法で書き出すCSVファイルの文字コードは「Shift-JIS」なんです。

世の中のソフトウェアの多くはそれとは別の「UTF-8」に対応をしている場合が多いので、そこにデータを渡そうとしたらUTF-8に変換をして渡す必要があります。

そこで今回は、エクセルVBAでUTF-8の文字コードでCSVファイルを書き出す方法についてお伝えします。

スポンサーリンク

おさらい:Shift-JISでCSVを書き出す

こちらが以前紹介した、PrintでCSVを書き出すプログラムです。まずはこのプログラムのおさらいをします。

Sub writeCSV()

Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(1)

Dim csvFile As String
csvFile = ActiveWorkbook.Path & "\data.csv"

Open csvFile For Output As #1

Dim i As Long, j As Long
i = 1

Do While ws.Cells(i, 1).Value <> ""

    j = 1
    Do While ws.Cells(i, j + 1).Value <> ""

        Print #1, ws.Cells(i, j).Value & ",";
        j = j + 1

    Loop

    Print #1, ws.Cells(i, j).Value & vbCr;
    i = i + 1

Loop

Close #1

MsgBox "data.csvに書き出しました"

End Sub

9行目のOpenで書き出すファイルを出力用ファイルとしてオープンします。

14~27行目で対象となるシートのデータがある範囲を走査しながら、開いたファイルにデータをカンマ区切りで書き出していきます。書き出しにははPrintを使います。

最後に29行目でファイルを閉じて終了です。

冒頭でお伝えした通り、この方法では有無も言わさずShift-JISで書き出されます。

ADODB.StreamオブジェクトでUTF-8のCSVを書き出す

UTF-8でCSVを書き出すにはADODB.Streamオブジェクトを使います。

簡単に説明するとADODB.Streamオブジェクトにいったんデータを流し込むと、取り扱う文字コードがUTF-8の状態でCSVファイル保存ができるようになります。

ADODB.Streamオブジェクトとは何か、またそのライブラリの追加方法について詳しくはこちらの記事で解説していますのでご覧ください。

文字化けよさようなら!エクセルVBAでUTF-8のCSVを読み込む方法
エクセルVBAのLine Input命令でUTF-8のCSVファイルを取り込むと文字化けを起こします。今回は、ADODB.Streamを使ってUTF-8のCSVファイルを取り込む方法についてお伝えします。

UTF-8でCSVを書き出すプログラム

ADODB.Streamオブジェクトを使ってUTF-8でCSVを書き出すプログラムはこちらになります。

Sub writeCSV_utf8()

Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(1)

Dim csvFile As String
csvFile = ActiveWorkbook.Path & "\data_utf8.csv"

'ADODB.Streamオブジェクトを生成
Dim adoSt As Object
Set adoSt = CreateObject("ADODB.Stream")

Dim strLine As String
Dim i As Long, j As Long
i = 1

With adoSt
    .Charset = "UTF-8"
    .LineSeparator = adLF
    .Open

    Do While ws.Cells(i, 1).Value <> ""

        strLine = ""

        j = 1
        Do While ws.Cells(i, j + 1).Value <> ""

            strLine = strLine & ws.Cells(i, j).Value & ","
            j = j + 1

        Loop

        strLine = strLine & ws.Cells(i, j).Value

        .WriteText strLine, adWriteLine

        i = i + 1

    Loop

    .SaveToFile csvFile, adSaveCreateOverWrite
    .Close

End With

MsgBox "data_utf8.csvに書き出しました"

End Sub

見慣れないものが多く出てきている印象ですが、大まかな流れはそれほど変わりません。

  1. ADODB.Streamオブジェクトを生成
  2. ADODB.Streamオブジェクトの文字コード、改行コードを設定
  3. ADODB.Streamオブジェクトをオープン
  4. 1行ずつ文字列を生成し、ADODB.Streamオブジェクトに流し込む
  5. ADODB.Streamオブジェクト内のデータをCSVファイルに保存する
  6. ADODB.Streamオブジェクトをクローズ

という流れです。

書き出しの際に使うADODB.Streamオブジェクトのプロパティとメソッド

以下で本プログラムで使用しているADODB.Streamオブジェクトのプロパティとメソッドについて解説をします。

Charset:Streamオブジェクトで取り扱う文字コードを指定。
LineSeparator:Streamオブジェクトで取り扱う改行コードを指定します。規定値はadCRLF。
Open:Streamオブジェクトを開く。
WriteText:Streamオブジェクトに文字列を書き出す。オプションadWriteLineで改行コードを追加して書き込む。
SaveToFile:Streamオブジェクトから指定のファイルのデータを書き込む。オプションadSaveCreateOverWriteでファイルの上書きをします。
Close:Streamオブジェクトを閉じる。

意味さえわかれば対して難しい部分はないかと思います。

ADODB.Stream…恐れるに足らずです。

ちなみにですが、Unixなどでは改行コードはLFの場合が多いためLineSeparatorプロパティで設定をしています。

実行結果

このプログラムで出力したデータをテキストエディタで開いてみると

エクセルVBAで出力したUTF-8のCSVファイル

と、このようにきちんとUTF-8で書き出しがされていることがわかります。

まとめ

エクセルVBAでUTF-8のCSVファイルを書き出す方法についてお伝えしました。

Open,Print,Close命令とだいぶ雰囲気が異なるので少し戸惑うかも知れませんが、実際にやっていることはほぼADODB.Streamオブジェクトのメソッドへの置き換えとプラスでいくつかのプロパティ設定となります。

さて、次回はBOMなしUTF-8のCSV書き出しについてお伝えできればと思います。

エクセルVBAでBOM無しのUTF-8でCSVファイルなどを出力する方法
エクセルVBAでデータを様々なファイル形式に書き出す方法についてお伝えしています。今回は、エクセルVBAでBOMなしのUTF-8にてCSVファイルを書き出す方法についてお伝えしていきたいと思います。

どうぞお楽しみに!

連載目次:エクセルVBAでCSVや様々なテキストファイルを出力する

多くの企業では様々なデータをエクセル形式で保持しています。そのデータ群をCSVやHTMLなどで有効利用できたら便利ですよね?このシリーズでは、エクセルデータをテキストをはじめ様々な形式のファイルに出力する方法についてお伝えしています。
  1. エクセルVBAでテキストファイルに書き出す最も簡単なプログラム
  2. エクセルVBAでエクセルシート上のデータをCSVファイルに書き出す
  3. エクセルの表をHTMLのtableタグに変換して出力するVBAマクロ
  4. エクセルVBAでセルが結合されているかどうか、またそのセルの数を判定する方法
  5. エクセルVBAで文字コードUTF-8のCSVファイルを書き出す方法
  6. エクセルVBAでBOM無しのUTF-8でCSVファイルなどを出力する方法

タイトルとURLをコピーしました