ExcelマクロでテキストファイルやCSVファイルを書き出すのは簡単です。
- Open でファイルを開く
- Print でファイルに1行書き出す
- Close でファイルを閉じる
が基本的な流れです。
複数行の書き出しは、2番を繰り返します。
しかし、書き出しが大量になるとネックは遅さです。
1行にどれくらいの文字数があるか、で異なりますが、1,000行で5分程度、10万行ならば数十分かかります。
テストデータを作成するときに、数十分も待てません。
(パソコンのCPUやメモリが占有状態になるので、パソコンで他の作業をしながら待つのも無理です)
そこで今回は、Excelマクロの大量書き出しを高速化する「ADODB.Stream」を紹介します。
この機能を使うと10万行が1分で書き出されます。
ExcelCSVでUTF-8を扱う場合にも、このADODB.Streamが使えます。
基本構文は次のとおりです。
- object.Open で、ADODBのstreamオブジェクトを開く
- object.WriteText で、stream内(メモリ内)にデータを溜める
- object.SaveToFile で、stream内のデータを外部ファイルに書き出す
- object.Close で、streamオブジェクトを閉じる
複数行の書き出しは、2番を繰り返します。
処理は、Print で一行ずつファイル書き出しするのとは異なり、WriteText(上記2番) でメモリ内に処理データを全て溜め込んでから SaveToFile(上記3番) で一気に書き出します。
処理速度のボトルネックは外部ストレージに対するI/O(Input/Output)なので、ここを一度で済ませれば速度改善になるのです。そのため、数行~数十行程度の処理では速度の差が分かりませんが、数万件とデータ量が多くなればなるほど顕著な差が出ます。
オプション指定も色々できます。
よく使われるのが、Charset プロパティ(文字コード指定)です。
デフォルトはUnicodeですが、それ以外にUTF-8、Shift_JIS、euc-jp、ISO-2022-JPなどが使えます。
ADODBを使うときは、マクロの参照設定が必要です。
このコードエディタのメニューの「ツール」⇒「参照設定」を開きます。

「Microsoft ActiveX Data Objects x.x Library」を選びます。(x.xの部分は一番大きな数字でOK)

サンプルコードを載せます。
私がよく使う「Excelで作成した(システム開発時の)テストデータを、CSVファイルとして書き出す」処理です。
A1⇒テーブル名 ※処理中では使っていない
2行目⇒論理名 ※処理中では使っていない
3行目⇒属性 ※処理中では使っていない
4行目⇒桁数 ※処理中では使っていない
5行目⇒物理名
6行目以降で、テストデータ
50カラムある場合はA~AX列
1,000レコードある場合は6~1,006行
にテストデータが記載されているものと想定します。
Option Explicit
Public Sub BULK_INSERT用のCSV作成()
'ADODB.Streamを使う
Dim ado As Object
Set ado = CreateObject("ADODB.Stream")
'変数
Dim i As Long 'データ開始行
Dim j As Integer '列
Dim ColNRow As Integer '何行目にカラム物理名を記載しているか
Dim eCol As Integer '一番右の列の位置(要素数が不明な場合でも処理可能)
Dim eRow As Long '一番下の行の位置( 〃 )
'定数
Const SaveF = "C:\test.csv" '保存ファイル名
'カラム物理名の行
ColNRow = 5 '5行目に物理名を書いている(右端を取得する基準として使用)
'一番下の行の位置を取得する
eRow = Cells(ColNRow, 1).End(xlDown).Row
'一番右の列の位置を取得する
eCol = Cells(ColNRow, 1).End(xlToRight).Column
'処理開始
ado.Open 'ADODB.Streamを開く
ado.Charset = "UTF-8" '文字コード指定(UTF-8)
'メイン処理(A列の値がある間はループする)
For i = 6 To eRow
'A列のみ(先頭にカンマを付けたくないから)
j = 1
ado.WriteText Cells(i, j)
'B列より右側
For j = 2 To eCol
ado.WriteText "," & Cells(i, j)
Next
'行の最後で改行コード
ado.WriteText "", adWriteLine
Next
'ADODB.Streamに保管されている内容を、ファイルに保存する
ado.SaveToFile SaveF, 2
'ADODB.Streamを閉じる
ado.Close
MsgBox "完了"
End Sub

