VBA

【VBA】UTF-8のCSVを扱う方法

エクセルVBAでCSVファイルを操作していると、必ずと言っていいほど遭遇する文字コードの問題があります。従来の方法では、UTF-8で保存されたCSVファイルを読み込むと文字化けが発生してしまうことがあります。

そこで今回は、FilesystemObjectとADODB.Streamオブジェクトを用いて、エクセルVBAでUTF-8のCSVファイルを正しく扱う方法をご紹介します。

従来のCSV取り込み方法で発生する問題

従来の方法でUTF-8のCSVファイルを読み込むと、文字コードの違いにより、日本語部分が文字化けしてしまうことがあります。これは、ExcelがデフォルトでShift-JISという文字コードを使用しているためです。

ExcelはCSVファイルを開く際に 「Shift_JIS」 の文字コードを識別するされます。
ExcelでのCSVファイル読み込みで文字化けが多いのは、UFT-8でエンコードしたものをShift_JISで読みこむ事により、対応していない文字が化けてしまいます。

FileSystemObject

FileSystemObject(ファイル システム オブジェクト)は、VBA(Visual Basic for Applications)やVBScriptなどのマイクロソフトのスクリプト言語でファイルおよびフォルダを操作するためのオブジェクトモデルです。FileSystemObject を使用すると、ファイルやフォルダの作成、読み書き、コピー、削除などの操作を簡単に行うことができます。

FileSystemObject は、Scripting ランタイム ライブラリに含まれており、Scripting.FileSystemObjectとして参照されます。このオブジェクトを使用するには、まず CreateObject メソッドを使用してオブジェクトを作成する必要があります。

以下に、FileSystemObject の主な機能とその使い方について説明します。

  1. ファイル操作:
    • ファイルの作成 (CreateTextFile)
    • ファイルの読み込み (OpenTextFile)
    • ファイルの書き込み (Write, WriteLine)
    • ファイルのクローズ (Close)
    • ファイルの存在確認 (FileExists)
    • ファイルの削除 (DeleteFile)
  2. フォルダ操作:
    • フォルダの作成 (CreateFolder)
    • フォルダの存在確認 (FolderExists)
    • フォルダ内のファイルやサブフォルダのリストアップ
  3. その他の操作:
    • ファイルやフォルダのコピー、移動
    • ファイルやフォルダの属性の取得や設定(読み取り専用、隠しファイルなど)

例えば、以下のコードは、FileSystemObject を使用してファイルを読み込んで内容を表示する例です。

Dim fso As Object
Dim ts As Object
Dim fileContent As String

' FileSystemObjectを作成してファイルを開く
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile("C:\example.txt", 1) ' 1: 読み取りモード

' ファイルの内容を読み込む
fileContent = ts.ReadAll

' ファイルを閉じる
ts.Close

' 読み込んだ内容を表示する
MsgBox fileContent

以上が FileSystemObject の基本的な機能とその使い方についての解説です。FileSystemObject は、VBA でファイルやフォルダの操作を行う際に非常に便利なツールであり、ファイルシステムに関連する多くのタスクを効率的に処理するのに役立ちます。

ADODB.Stream

ADODB.Stream は、ActiveX Data Objects (ADO) ライブラリの一部であり、ファイルの読み書きやメモリ内のデータの処理などを行うためのオブジェクトです。主に、VBA や VBScript などのスクリプト言語で利用されます。ADODB.Stream を使用すると、テキストやバイナリデータをファイルに書き込んだり、ファイルから読み取ったりすることができます。

ADODB.Stream の主な特徴や機能を以下に示します。

  1. ファイルの読み書き:
    • バイナリデータやテキストデータをファイルに書き込む (Write メソッド)
    • ファイルからバイナリデータやテキストデータを読み取る (Read メソッド)
    • ファイルの内容をメモリ内のバッファに一括して読み込む (LoadFromFile メソッド)
  2. メモリ内のデータの処理:
    • バイナリデータやテキストデータをメモリ内のストリームに書き込む (Write メソッド)
    • メモリ内のストリームからバイナリデータやテキストデータを読み取る (Read メソッド)
  3. データの形式:
    • テキスト形式 (adTypeText) または バイナリ形式 (adTypeBinary) のいずれかを指定してデータを操作できる
    • テキスト形式の場合、文字エンコーディング(UTF-8、Shift_JIS など)を指定できる
  4. ストリームの位置やサイズの管理:
    • 現在の読み取り/書き込み位置を取得・設定できる (Position プロパティ)
    • ストリームのサイズを取得できる (Size プロパティ)
  5. その他の操作:
    • ファイルの内容を別のファイルにコピーする (SaveToFile メソッド)
    • メモリ内のデータを別の ADODB.Stream オブジェクトにコピーする (CopyTo メソッド)
    • メモリ内のデータをクリアする (Flush メソッド)

以下は、VBAでADODB.Stream を使用してファイルを読み書きするサンプルです。

Sub ReadWriteFileWithADODBStream()
    Dim stream As Object
    Dim filePathIn As String
    Dim filePathOut As String

    ' 入力ファイルパスと出力ファイルパスを設定
    filePathIn = "C:\path\to\input.txt"
    filePathOut = "C:\path\to\output.txt"

    ' ADODB.Stream オブジェクトを作成
    Set stream = CreateObject("ADODB.Stream")

    ' 入力ファイルを読み込みモードで開く
    stream.Open
    stream.Type = 2 ' テキスト形式
    stream.LoadFromFile filePathIn

    ' 出力ファイルを書き込みモードで開く
    stream.SaveToFile filePathOut, 2 ' 上書きモード
    stream.Close

    ' オブジェクトを解放
    Set stream = Nothing
End Sub

このコードでは、ADODB.Stream オブジェクトを使用してテキストファイルを読み取り、別のファイルに書き込んでいます。読み取りモードと書き込みモードを適切に設定し、LoadFromFile メソッドと SaveToFile メソッドを使用してファイルの読み書きを行っています。

UTF-8形式のCSVを扱う

それでは、VBAでUTF-8のCSVファイルを取り扱う方法について解説します。UTF-8形式のCSVファイルの読み込み、UTF-8形式でのCSVファイルの出力、およびUTF-8形式のCSVファイルへの追記方法を説明します。

UTF-8形式のCSVファイルの読み込み

まず、UTF-8形式のCSVファイルをVBAで読み込む方法です。以下の手順で行います。

  1. FileSystemObjectを使用して、CSVファイルを開きます。
  2. CSVファイルの内容を文字列として読み込みます。
Sub ReadUTF8CSV()
    Dim fso As Object
    Dim ts As Object
    Dim filePath As String
    Dim fileContent As String
    
    ' 読み込むCSVファイルのパスを指定します
    filePath = "C:\path\to\file.csv"
    
    ' FileSystemObjectを作成してCSVファイルを開きます
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts = fso.OpenTextFile(filePath, 1, False, -1) ' 1: 読み取りモード, -1: UTF-8
    fileContent = ts.ReadAll ' CSVファイルの内容を読み込みます
    ts.Close ' ファイルを閉じます
    
    ' 読み込んだCSVファイルの内容が変数fileContentに格納されます
End Sub

UTF-8形式でのCSVファイルの出力

次に、UTF-8形式でCSVファイルを出力する方法です。以下の手順で行います。

  1. 出力するCSVファイルの内容を文字列として作成します。
  2. ADODB.Streamを使用して、UTF-8形式でファイルに書き込みます。
Sub WriteUTF8CSV()
    Dim content As String
    Dim filePath As String
    
    ' CSVファイルに書き込む内容を設定します
    content = "Header1,Header2,Header3" & vbCrLf
    content = content & "Data1,Data2,Data3"
    
    ' 出力するCSVファイルのパスを指定します
    filePath = "C:\path\to\output.csv"
    
    ' UTF-8でCSVファイルを出力する関数を呼び出します
    WriteTextToFile content, filePath
End Sub

Sub WriteTextToFile(text As String, filePath As String)
    Dim stream As Object
    
    ' ADODB.Streamオブジェクトを作成してUTF-8形式でファイルに書き込みます
    Set stream = CreateObject("ADODB.Stream")
    stream.Type = 2 ' テキスト形式
    stream.Charset = "utf-8"
    stream.Open
    stream.WriteText text ' ファイルに文字列を書き込みます
    
    ' ファイルを保存してストリームを閉じます
    stream.SaveToFile filePath, 2 ' 2: 上書きモード
    stream.Close
End Sub

UTF-8形式のCSVファイルへの追記

最後に、UTF-8形式のCSVファイルに追記する方法です。既存のファイルを読み込み、新しいデータを追加して再度UTF-8形式で出力します。

Sub AppendToUTF8CSV()
    Dim content As String
    Dim filePath As String
    
    ' 追記するデータを設定します
    content = vbCrLf & "NewData1,NewData2,NewData3"
    
    ' 既存のCSVファイルのパスを指定します
    filePath = "C:\path\to\existing.csv"
    
    ' 既存のCSVファイルを読み込んで、追記するデータを追加します
    content = ReadTextFromFile(filePath) & content
    
    ' UTF-8でCSVファイルを出力します
    WriteTextToFile content, filePath
End Sub

Function ReadTextFromFile(filePath As String) As String
    Dim fso As Object
    Dim ts As Object
    Dim fileContent As String
    
    ' FileSystemObjectを作成してCSVファイルを開きます
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts = fso.OpenTextFile(filePath, 1, False, -1) ' 1: 読み取りモード, -1: UTF-8
    fileContent = ts.ReadAll ' CSVファイルの内容を読み込みます
    ts.Close ' ファイルを閉じます
    
    ' 読み込んだCSVファイルの内容を返します
    ReadTextFromFile = fileContent
End Function

Sub WriteTextToFile(text As String, filePath As String)
    Dim stream As Object
    
    ' ADODB.Streamオブジェクトを作成してUTF-8形式でファイルに書き込みます
    Set stream = CreateObject("ADODB.Stream")
    stream.Type = 2 ' テキスト形式
    stream.Charset = "utf-8"
    stream.Open
    stream.WriteText text ' ファイルに文字列を書き込みます
    
    ' ファイルを保存してストリームを閉じます
    stream.SaveToFile filePath, 2 ' 2: 上書きモード
    stream.Close
End Sub

これで、VBAでUTF-8形式のCSVファイルを読み込み、出力、および追記する方法が実装できました。ファイルの読み込みと出力にはFileSystemObjectADODB.Streamを使用しており、これらのオブジェクトを使うことで簡単にUTF-8形式のCSVファイルを扱うことができます。

ADODB.StreamオブジェクトでUTF-8のCSVを読み込む

先のサンプルでは、FileSystemObjectを使用してCSVを取り込みましたが ADODB.Streamを利用して読み込む事も可能です。

Sub ReadCSVFileWithADODBStream()
    Dim stream As Object
    Dim filePath As String
    Dim fileContent As String

    ' 読み込むCSVファイルのパスを設定
    filePath = "C:\path\to\your\file.csv"

    ' ADODB.Stream オブジェクトを作成
    Set stream = CreateObject("ADODB.Stream")

    ' バイナリモードで開く
    stream.Open
    stream.Type = 1 ' adTypeBinary

    ' ファイルを読み込む
    stream.LoadFromFile filePath

    ' 読み込んだ内容を文字列として取得(UTF-8でエンコードされていることを想定)
    fileContent = stream.ReadText

    ' メッセージボックスに表示
    MsgBox fileContent

    ' ADODB.Stream を閉じて解放する
    stream.Close
    Set stream = Nothing
End Sub

このコードでは、指定されたパスのCSVファイルをバイナリモードで開き、その内容を文字列として取得しています。取得した内容は、メッセージボックスに表示されます。最後に、ADODB.Stream オブジェクトを閉じて解放しています。

このコードを実行すると、指定したCSVファイルの内容がポップアップウィンドウに表示されます。

まとめ

今回の記事では、エクセルVBAでUTF-8のCSVファイルを正しく扱う方法について解説しました。従来の方法で文字化けが発生していた方は、ぜひ今回ご紹介した方法を試してみてください。