【入門編】VBAで「バイナリデータ」を扱う:CSV以外のファイル形式を読み書きする技術 – Excel VBA解析バイブル

スポンサーリンク

Excel VBAで「バイナリデータ」を自在に操る!ADODB.Streamで広がるファイル操作の世界

皆さん、こんにちは!Excel VBAの世界へようこそ。
マクロの記録で「なんとなく動く」から一歩踏み出して、もっと自由自在にファイルを扱えるようになりたい。そんな熱い想いを持ったあなたのための記事です。

今回は、Excel VBAで「バイナリデータ」を扱う、ちょっと高度だけど、知ると世界が広がるテクニックをご紹介します。「CSV以外のファイル形式」となると、なんだか難しそう…と感じるかもしれませんが、大丈夫!私が丁寧に、そして分かりやすく解説していきますね。

このテクニックをマスターすれば、テキストファイルだけでなく、画像や設定ファイルなど、様々な形式のファイルをVBAから直接読み書きできるようになります。まるで、Excel VBAが「ファイル操作の万能選手」になるような感覚ですよ!

なぜ「バイナリデータ」を扱う必要があるの?

普段、Excelで作業していると、どうしても「CSV」形式のファイルを扱うことが多いですよね。CSVは表形式のデータを表現するのに便利ですが、世の中にはもっと多様なファイル形式が存在します。

例えば、

  • 設定ファイル (JSON, XMLなど): アプリケーションの設定情報や、Web APIとのやり取りでよく使われます。
  • 画像ファイル (BMP, JPG, PNGなど): Excel VBAで直接画像を操作したい場面もあります。
  • 実行ファイルやライブラリ: バイナリ形式でプログラムそのものが記述されています。
  • 独自のバイナリフォーマット: 特定のソフトウェアが使用する、独自のファイル形式。

これらのファイルを、単にテキストとして扱うだけでは、その本来の構造や意味を理解することができません。そこで登場するのが、「バイナリデータ」としてファイルを直接扱う技術なのです。

ADODB.Streamが「ファイル操作の秘密兵器」である理由

「バイナリデータを直接扱う」と聞くと、なんだか難しそうですよね。でも、Excel VBAには強力な味方がいます。それが `ADODB.Stream` オブジェクト です!

`ADODB.Stream` は、もともとデータベース接続などで使われるADO (ActiveX Data Objects) ライブラリの一部ですが、その柔軟性から、ファイル操作にも非常に強力な機能を提供してくれます。

このオブジェクトを使うことで、以下のことが可能になります。

1. 文字コードを気にせず、生のバイト列としてファイルを読み込める:

  • UTF-8、Shift_JIS、EUC-JPなど、様々な文字コードで保存されたテキストファイルを、文字化けすることなく正確に読み込めます。

2. バイナリモードでファイルを書き込める:

  • テキストデータだけでなく、画像データなどの「バイトの羅列」をそのままファイルに書き込めます。

3. ファイルの一部だけを読み書きできる:

  • 大きなファイルの一部だけを効率的に処理することも可能です。

「ここをクリアすれば、Excel VBAのファイル操作の基本はバッチリですよ」と言えるほど、この `ADODB.Stream` は重要で、そして強力なツールなのです。

VBEの設定:まずは準備を整えよう

`ADODB.Stream` を使うためには、VBE (Visual Basic Editor) で参照設定を行う必要があります。これは、VBAが「この機能を使いたいんですけど、どこにありますか?」とシステムに教えてあげるための大切なステップです。

1. VBEを開く:
Excelで `Alt` + `F11` キーを押して、VBEを開きます。
2. 参照設定:
メニューバーの「ツール」→「参照設定」を選択します。
3. ライブラリの選択:
表示されたダイアログボックスの中から、「Microsoft ActiveX Data Objects x.x Library」を探してチェックを入れます。(x.x はバージョン番号です。最新のものを選ぶのがおすすめです。)

  • 💡ポイント: もし見つからない場合は、少し下にスクロールしてみてください。

![VBE参照設定画面のイメージ](https://via.placeholder.com/600×300?text=VBE+参照設定画面+イメージ)
(※これはイメージです。実際の画面とは異なる場合があります。)

「OK」をクリックして閉じれば、準備完了です!

基本構文:ADODB.Streamオブジェクトの生成と操作

では、いよいよ `ADODB.Stream` を使った具体的なコードを見ていきましょう。まずは、ファイルを開いて内容を読み込む基本的な流れです。

‘ — 変数宣言 —
Dim stream As Object ‘ ADODB.Streamオブジェクトを格納する変数
Dim filePath As String ‘ 読み込むファイルのパス
Dim fileContent As String ‘ 読み込んだファイルの内容を格納する変数 (テキストの場合)
Dim binaryData() As Byte ‘ 読み込んだバイナリデータを格納する変数

‘ — ファイルパスの設定 —
filePath = “C:\path\to\your\file.txt” ‘ ここに実際に読み込みたいファイルのパスを指定してください

‘ — ADODB.Streamオブジェクトの生成 —
‘ Late Binding (参照設定をしていない場合でも使える方法)
Set stream = CreateObject(“ADODB.Stream”)

‘ Early Binding (参照設定をした場合、より高速でコード補完が効く)
‘ Set stream = New ADODB.Stream ‘ この行を使う場合は、参照設定が必要です

‘ — ストリームのプロパティ設定 —
‘ 1. オープンモードの設定
‘ adModeRead = 1: 読み込み専用
‘ adModeWrite = 2: 書き込み専用
‘ adModeReadWrite = 3: 読み書き両方可能
stream.Mode = 1 ‘ 読み込み専用で開く

‘ 2. ストリームタイプの設定
‘ adTypeText = 1: テキストモード
‘ adTypeBinary = 2: バイナリモード
stream.Type = 1 ‘ テキストモードで開く (文字コードを意識する場合)
‘ stream.Type = 2 ‘ バイナリモードで開く (生のバイト列として扱いたい場合)

‘ — ファイルを開く —
‘ Open メソッド: ファイルを開きます
‘ Parameter 1: File Name (ファイルパス)
‘ Parameter 2: Mode (モード: adModeRead, adModeWrite, adModeReadWrite)
stream.Open filePath, 1 ‘ filePath を読み込みモード(1)で開く

‘ — ファイルの内容を読み込む —
‘ テキストモードの場合
If stream.Type = 1 Then
‘ CharSet プロパティで文字コードを指定 (省略するとシステムデフォルト)
‘ stream.CharSet = “Shift_JIS” ‘ 例: Shift_JISで読み込む場合
‘ stream.CharSet = “UTF-8” ‘ 例: UTF-8で読み込む場合

‘ ReadText メソッド: ファイルの内容を文字列として読み込みます
fileContent = stream.ReadText
Debug.Print “ファイル内容 (テキスト):”
Debug.Print fileContent
Else
‘ バイナリモードの場合
‘ Read メソッド: ファイルの内容をバイト配列として読み込みます
binaryData = stream.Read ‘ 戻り値は Variant/byte() 型
Debug.Print “ファイル内容 (バイナリ):”
Debug.Print UBound(binaryData) + 1 & ” バイト読み込みました。”
‘ バイナリデータは直接表示できないため、バイト数を表示
End If

‘ — ファイルを閉じる —
‘ Close メソッド: ファイルを閉じます
stream.Close

‘ — オブジェクトの解放 —
‘ Set stream = Nothing ‘ オブジェクトへの参照を解放します
‘ Late Binding の場合は、解放しないとメモリリークの原因になることがあります
‘ Early Binding の場合も、明示的に解放するのが良い習慣です
Set stream = Nothing

MsgBox “ファイル読み込み処理が完了しました!”

コードのポイント解説:

  • `Dim stream As Object` / `Set stream = CreateObject(“ADODB.Stream”)`:

これは「Late Binding」と呼ばれる方法です。参照設定をしなくても、`CreateObject` 関数で `ADODB.Stream` オブジェクトを生成できます。コード補完は効きませんが、環境に依存しにくいというメリットがあります。
もし参照設定をした場合は、`Dim stream As ADODB.Stream` と `Set stream = New ADODB.Stream` と書くことで、「Early Binding」となり、より高速に動作し、コード補完も効くようになります。

  • `stream.Mode`:

ファイルを「読み込み専用」にするか、「書き込み専用」にするか、あるいは「両方」可能にするかをここで決めます。今回は読み込みなので `adModeRead` (値は `1`) を指定しています。

  • `stream.Type`:

ここが「バイナリデータ」を扱う上で最も重要な設定の一つです!

  • `adTypeText` (値は `1`): テキストファイルとして扱います。この場合、`stream.CharSet` プロパティで文字コード(`”Shift_JIS”`, `”UTF-8″` など)を指定することが重要です。指定しないと、システムのデフォルトの文字コードで読み込まれ、文字化けの原因になります。
  • `adTypeBinary` (値は `2`): バイナリファイルとして扱います。文字コードを気にする必要がなく、生のバイト列として読み書きできます。画像ファイルなどを扱う場合に選びます。
  • `stream.Open filePath, 1`:

指定したパスのファイルを開きます。第2引数には `stream.Mode` で指定したモードを渡します。

  • `stream.ReadText` / `stream.Read`:
  • `ReadText`: テキストモード (`stream.Type = 1`) の場合に、ファイルの内容を文字列として読み込みます。
  • `Read`: バイナリモード (`stream.Type = 2`) の場合に、ファイルの内容をバイト配列 (`Byte()`) として読み込みます。
  • `stream.Close`:

開いたファイルを閉じます。必ず実行しましょう。

  • `Set stream = Nothing`:

使用しなくなったオブジェクトをメモリから解放します。これを怠ると、予期せぬエラーやメモリリークの原因になることがあります。

陥りやすいエラーとその回避策

`ADODB.Stream` を使う上で、いくつか注意しておきたい点があります。

  • 文字化け:
  • 原因: テキストファイルを `adTypeBinary` で読み込んだり、`adTypeText` で読み込む際に `CharSet` を正しく指定しなかったりする場合に発生します。
  • 回避策:
  • テキストファイルは `adTypeText` で開く。
  • `adTypeText` で開く場合は、ファイルの実際の文字コードに合わせて `stream.CharSet` を正しく設定する。
  • もし文字コードが不明な場合は、一度 `adTypeBinary` で読み込み、バイト列を解析して文字コードを判定する、という高度なテクニックもありますが、まずは既知の文字コードで試しましょう。
  • ファイルが見つからない (エラー 76: パスが見つかりません):
  • 原因: 指定した `filePath` が間違っている、ファイルが存在しない、またはアクセス権がない場合に発生します。
  • 回避策:
  • `filePath` が正しいか、大文字・小文字も含めて確認する。
  • エクスプローラーで実際にファイルが存在するか確認する。
  • VBAを実行しているユーザーに、そのファイルへの読み取り権限があるか確認する。
  • `Dir()` 関数などで、ファイルが存在するか事前にチェックするのも有効です。
  • ファイルがロックされている:
  • 原因: 他のプログラムがそのファイルを排他的に開いている場合に発生します。
  • 回避策:
  • 対象のファイルを開いている他のプログラムを閉じる。
  • しばらく待ってから再試行する。
  • (高度)ファイルロックの解除を試みるプログラムを自作する。

実践!バイナリファイルを読み込んでみる

それでは、実際にバイナリファイルを読み込む例を見てみましょう。ここでは、簡単なテキストファイル(UTF-8エンコーディング)をバイナリモードで読み込み、そのバイト数を確認してみます。

Sub ReadBinaryFileExample()

Dim stream As Object
Dim filePath As String
Dim binaryData() As Byte
Dim fileSize As Long

‘ — 読み込むファイルのパスを指定 —
‘ ★★★ 実際のファイルパスに置き換えてください ★★★
filePath = ThisWorkbook.Path & “\sample.txt” ‘ このExcelファイルと同じフォルダにあるsample.txtを想定

‘ — sample.txt を作成する処理 (テスト用) —
‘ 実行前に、このExcelファイルと同じフォルダに “sample.txt” という名前で
‘ 何かテキストファイルを作成しておいてください (UTF-8エンコーディングが望ましい)
‘ 例: 「これはテストファイルです。」と入力したUTF-8ファイル

‘ — ファイルが存在するか確認 —
If Dir(filePath) = “” Then
MsgBox “指定されたファイルが見つかりません: ” & filePath, vbExclamation
Exit Sub
End If

‘ — ADODB.Stream オブジェクトの生成 —
On Error GoTo ErrorHandler ‘ エラーハンドリングを設定
Set stream = CreateObject(“ADODB.Stream”)

‘ — プロパティ設定 —
stream.Mode = 1 ‘ 読み込みモード
stream.Type = 2 ‘ バイナリモード

‘ — ファイルを開く —
stream.Open filePath, 1

‘ — ファイルの内容をバイト配列として読み込む —
binaryData = stream.Read

‘ — ファイルサイズを取得 —
fileSize = UBound(binaryData) + 1 ‘ 配列のインデックスは0から始まるため +1

‘ — 結果を表示 —
Debug.Print “ファイルパス: ” & filePath
Debug.Print “ファイルサイズ: ” & fileSize & ” バイト”
‘ バイナリデータそのものを表示するのは困難なので、サイズだけ確認

‘ — クリーンアップ —
stream.Close
Set stream = Nothing
MsgBox “バイナリファイル読み込み完了!詳細はイミディエイトウィンドウを確認してください。”, vbInformation

Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical
‘ エラー発生時も、オブジェクトを解放する
If Not stream Is Nothing Then
stream.Close
Set stream = Nothing
End If

End Sub

このコードのポイント:

  • `filePath = ThisWorkbook.Path & “\sample.txt”`:

`ThisWorkbook.Path` は、現在開いているExcelファイルが保存されているフォルダのパスを取得します。これにより、Excelファイルと同じ場所にある `sample.txt` を指定しやすくなります。

  • `If Dir(filePath) = “” Then … Exit Sub`:

`Dir()` 関数は、指定したファイルが存在すればファイル名を、存在しなければ空文字列を返します。これにより、ファイルが存在しない場合にエラーで処理が中断するのを防いでいます。

  • `On Error GoTo ErrorHandler`:

VBAでは、エラーが発生したときにプログラムが強制終了するのを防ぐために、エラーハンドリングを設定できます。`On Error GoTo` で、エラー発生時にジャンプするラベルを指定します。

  • `stream.Type = 2`:

バイナリモードで開くことを指定しています。

  • `binaryData = stream.Read`:

ファイルの内容が `Byte()` 型の配列として `binaryData` 変数に格納されます。

  • `fileSize = UBound(binaryData) + 1`:

`UBound()` 関数は、配列の最大インデックスを返します。バイト配列は0から始まるので、要素数を取得するには `+1` が必要です。

  • `ErrorHandler:` ラベル:

エラーが発生した場合に、ここに処理がジャンプしてきます。エラー番号 (`Err.Number`) とエラー内容 (`Err.Description`) を表示し、後処理(オブジェクトの解放)を行います。

実践!バイナリファイルを書き込んでみる

次に、バイナリモードでファイルに書き込む例を見てみましょう。ここでは、VBAの配列で持っているバイトデータをファイルに書き出します。

Sub WriteBinaryFileExample()

Dim stream As Object
Dim filePath As String
Dim binaryData() As Byte
Dim i As Long

‘ — 書き込むファイルパスを指定 —
‘ ★★★ 書き込みたいパスを指定してください ★★★
filePath = ThisWorkbook.Path & “\output.bin” ‘ このExcelファイルと同じフォルダにoutput.binとして保存

‘ — 書き込むバイナリデータを作成 (例として簡単なバイト列) —
‘ 実際には、他のファイルから読み込んだデータや、生成したデータなどが入ります
ReDim binaryData(0 To 9) ‘ 10バイトの配列を確保
For i = 0 To 9
binaryData(i) = i + &H30 ‘ ASCIIコードで ‘0’ から ‘9’ の文字に相当するバイト列
Next i
‘ binaryData は [48, 49, 50, 51, 52, 53, 54, 55, 56, 57] となります (10進数)

‘ — ADODB.Stream オブジェクトの生成 —
On Error GoTo ErrorHandler
Set stream = CreateObject(“ADODB.Stream”)

‘ — プロパティ設定 —
stream.Mode = 3 ‘ 読み書き両方可能 (書き込みなのでWriteでも可)
stream.Type = 2 ‘ バイナリモード

‘ — ファイルを開く (存在しない場合は新規作成される) —
‘ 既存のファイルに追記したい場合は、モードを adModeWrite + adModeAppend (値は 6) などにする必要がありますが、
‘ 今回は新規作成または上書きを想定して Open し、Write で書き込みます。
stream.Open filePath, 3 ‘ 読み書き両方で開く (既存ファイルは上書きされる)

‘ — バイナリデータをファイルに書き込む —
‘ Write メソッド: バイト配列を書き込みます
stream.Write binaryData

‘ — ファイルを保存して閉じる —
‘ SaveToFile メソッドは ADODB.Stream には直接ありません。
‘ Close メソッドでファイルが保存・閉じられます。
stream.Close

‘ — オブジェクトの解放 —
Set stream = Nothing

MsgBox “バイナリファイルへの書き込みが完了しました: ” & filePath, vbInformation

Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical
If Not stream Is Nothing Then
stream.Close
Set stream = Nothing
End If

End Sub

このコードのポイント:

  • `ReDim binaryData(0 To 9)`:

書き込みたいバイトデータを格納するための配列を準備します。`ReDim` で配列のサイズを変更しています。

  • `binaryData(i) = i + &H30`:

この例では、0から9までの数字をASCIIコードの文字(’0’~’9’)に対応するバイト値として配列に格納しています。`&H30` は16進数で48(10進数)であり、ASCIIコードで文字「0」のコードです。

  • `stream.Mode = 3`:

読み書き両方のモードで開いています。書き込みが目的なので `adModeWrite` (値は `2`) でも良いですが、`adModeReadWrite` (値は `3`) の方が汎用性が高いです。

  • `stream.Type = 2`:

バイナリモードを指定します。

  • `stream.Open filePath, 3`:

ファイルを読み書きモードで開きます。もし `filePath` で指定したファイルが既に存在する場合、この `Open` 操作で 上書きされます ので注意してください。

  • `stream.Write binaryData`:

`Write` メソッドにバイト配列を渡すことで、その内容がファイルに書き込まれます。

  • `stream.Close`:

ファイルを閉じます。このタイミングで、書き込み内容がディスクに確定します。

まとめ:ADODB.StreamでVBAの可能性を広げよう!

いかがでしたでしょうか?
`ADODB.Stream` を使うことで、Excel VBAは単なる表計算ソフトの自動化ツールから、より汎用的なファイル操作ツールへと進化します。

  • 文字コードを気にせず、どんなテキストファイルでも正確に読み書きできる。
  • 画像ファイルなどのバイナリデータを直接扱える。
  • 設定ファイルや、外部システムとの連携もスムーズになる。

最初は少し難しく感じるかもしれませんが、この `ADODB.Stream` の使い方をマスターすれば、あなたのVBAスキルは格段に向上します。マクロの記録だけでは決して到達できない、新しい世界が開けるはずです。

ぜひ、色々なファイルを `ADODB.Stream` で読み書きしてみてください。きっと、VBAでできることの幅がぐんと広がるのを実感できるはずですよ!

「ここをクリアすれば、Excel VBAの基本はバッチリですよ」という言葉を胸に、ぜひこの `ADODB.Stream` を使いこなしてくださいね。応援しています!

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