「配列」を「CSV」へ。Excelで保存。タブ区切りに対応。

タイトルのサンプルマクロは、以下です。

'**********************************
'* 二次元配列をCSVファイルに出力する高速化されたマクロ
'* 引数:
'*   arr       : 二次元配列(出力するデータ)
'*   fileName  : 保存先のCSVファイルのフルパス
'*   delimiter : 区切り文字。デフォルトは「カンマ」(Comma)。タブ区切りの場合は「Tab」を設定。
'* 
'* 解説:
'* - 配列内の全データを文字列化してから一度にシートに書き出すため、高速化を実現しています。
'* - 「指数表示」に対応するため、すべてのデータを文字列化し、シートに配置します。
'* - 出力ファイルがすでに存在している場合、ユーザーに確認を取って削除後、書き込みを行います。
'* - 区切り文字がカンマ(Comma)かタブ(Tab)かを判定し、適切な形式でCSVファイルとして保存します。
'* - 最後に、新規で作成したブックは保存せずに閉じられ、メモリが解放されます。
'**********************************

Sub array_to_csv_Excel_r2(ByRef arr As Variant, ByVal fileName As String, Optional ByVal delimiter As String = "Comma")
    ' CSVファイルのフルパスを指定
    Dim csvFile As String
    csvFile = fileName
    
    ' FileSystemObjectを作成し、ファイル存在確認、削除処理
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    ' もし既にCSVファイルが存在する場合、削除する処理
    If fso.FileExists(csvFile) Then
        ' ファイルが開いているか確認
        If IsBookOpened(csvFile) Then
            Dim rc As Integer  ' メッセージボックスの戻り値
            rc = MsgBox("ファイルが開いています。" & vbCrLf & _
                        "はい:閉じて、削除して、処理を続けます。" & vbCrLf & _
                        "いいえ:処理を中断します", vbYesNo + vbQuestion, "確認")
            If rc = vbYes Then
                Dim FileNameOnly As String
                FileNameOnly = fso.GetFileName(csvFile)
                Windows(FileNameOnly).Close   ' 該当ファイルのウィンドウを閉じる
            Else
                End   ' ユーザーが「いいえ」を選んだ場合、処理を中断
            End If
        End If
        fso.DeleteFile csvFile  ' 古いファイルを削除
    End If
    
    ' 新規ブックを作成(出力用に一時的に使用)
    Dim wb As Workbook
    Set wb = Workbooks.Add
    
    ' 配列内容をすべて文字列化して新しい配列に格納
    ' 数値や日付などのセルの書式により指数表示になるのを防ぐ
    Dim i As Long, j As Long
    Dim newArr As Variant
    ReDim newArr(1 To UBound(arr), 1 To UBound(arr, 2))  ' 新しい配列を準備
    For i = 1 To UBound(arr)  ' 各行を処理
        For j = 1 To UBound(arr, 2)  ' 各列を処理
            newArr(i, j) = "'" & CStr(arr(i, j))  ' 文字列化し、先頭に「'」を追加して数値として認識されないようにする
        Next j
    Next i
    
    ' 文字列化したデータを新規ブックのA1から書き込み(シートの範囲に)
    wb.Worksheets(1).Range("A1").Resize(UBound(arr), UBound(arr, 2)).Value = newArr
    
    ' 区切り文字の指定によってCSV形式を選定
    Dim fileFormat As Long
    Select Case LCase(delimiter)  ' 引数を小文字に変換して判定
        Case "comma"               ' カンマ区切り
            fileFormat = xlCSV      ' Excel標準のCSV形式(Shift_JIS, カンマ区切り)
        Case "tab"                 ' タブ区切り
            fileFormat = xlText     ' Excel標準のTXT形式(Shift_JIS, タブ区切り)
    End Select
    
    ' 新規ブックを指定した形式で保存
    wb.SaveAs fileName:=csvFile, fileFormat:=fileFormat, Local:=True
    ' Local:=TrueはExcel言語設定に基づいて保存される。日付の形式なども日本語設定で保存されます。
    
    ' 新規ブックを保存せずに閉じ、メモリを解放
    wb.Close SaveChanges:=False
    
    ' 後処理:オブジェクトを解放
    Set fso = Nothing
End Sub

Function IsBookOpened(ByVal FilePath As String) As Boolean
    On Error Resume Next  ' エラートラップを設定。エラーが発生した場合、次の行へ処理を続ける。
    
    Open FilePath For Append As #1   ' 指定されたファイルを "Append"(追加書き込みモード)で開く
    Close #1  ' 開いたファイルを閉じる
    
    If Err.Number > 0 Then   ' エラーが発生した場合(ファイルが開かれていない場合)
        IsBookOpened = True   ' ファイルが開かれていると判定してTrueを返す
    Else
        IsBookOpened = False  ' エラーが発生しなければ、ファイルが開かれていないと判定してFalseを返す
    End If
End Function

コメントの解説

  1. 引数 arrfileName
    • arr は、CSVに出力したい2次元配列です。行と列のデータを保持します。
    • fileName は、保存先のフルパスを指定する引数で、出力するCSVファイルの名前です。
  2. FileSystemObject の利用
    • FileSystemObject を利用して、指定されたファイルの存在を確認し、もし既に存在していれば削除します。
  3. 配列内容の文字列化処理
    • CStr() で配列の値をすべて文字列に変換し、Excelでの自動変換(特に指数表示)を防止します。
    • 文字列として扱うことで、Excelにおいて数値や日付が指数形式で表示されるのを防ぎます。
  4. 区切り文字の処理(カンマ or タブ)
    • 引数 delimiter により、CSVファイルの区切り文字を カンマ または タブ に変更できます。
  5. ファイルの保存
    • wb.SaveAs メソッドでファイルを保存する際、fileFormat を指定し、保存形式を変更します。
    • 例えば、カンマ区切りのCSV形式を保存するためには、xlCSV を使用します。
  6. 後処理
    • 保存が完了した後、ワークブックは保存せずに閉じられ、メモリを解放します。

💡 このマクロの特徴

  • 配列データを直接書き出すため、大量のデータを高速で処理できます。
  • 「指数表示」のようなExcelの自動フォーマットを防ぐため、すべてのデータを文字列として処理します。
  • 出力形式をカンマ区切り(CSV)やタブ区切り(TXT)から選べる柔軟性があります。

使用例

以下は、上記の array_to_csv_Excel_r2 マクロを使用した具体的な例です。このサンプルでは、2次元配列を作成し、それをCSVファイルに出力します。

Sub ExampleUsage()
    ' 2次元配列の作成
    Dim arr(1 To 5, 1 To 3) As Variant
    arr(1, 1) = "名前"
    arr(1, 2) = "年齢"
    arr(1, 3) = "住所"
    
    arr(2, 1) = "山田太郎"
    arr(2, 2) = 30
    arr(2, 3) = "東京都"
    
    arr(3, 1) = "鈴木花子"
    arr(3, 2) = 25
    arr(3, 3) = "大阪府"
    
    arr(4, 1) = "田中一郎"
    arr(4, 2) = 40
    arr(4, 3) = "福岡県"
    
    arr(5, 1) = "佐藤二郎"
    arr(5, 2) = 35
    arr(5, 3) = "北海道"
    
    ' ファイル名を指定
    Dim fileName As String
    fileName = "C:\temp\sample_output.csv"
    
    ' 配列をCSVファイルに出力(カンマ区切り)
    Call array_to_csv_Excel_r2(arr, fileName, "Comma")
    
    ' 配列をCSVファイルに出力(タブ区切り)
    ' Call array_to_csv_Excel_r2(arr, fileName, "Tab")
    
    MsgBox "CSVファイルが保存されました: " & fileName
End Sub

解説:

  1. 2次元配列の作成
    配列 arr は 5 行 3 列のデータを持つ、簡単なサンプルデータです。最初の行(1行目)はヘッダーとして「名前」、「年齢」、「住所」とし、残りの行は人々の情報を格納しています。
  2. ファイル名の指定
    fileName 変数には、保存先のCSVファイルのフルパスを指定します。必要に応じてパスやファイル名は変更してください。
  3. CSVファイルへの出力
    array_to_csv_Excel_r2 マクロを呼び出して、配列 arr の内容をCSVファイルとして保存します。ここではカンマ区切りで保存する例を示していますが、タブ区切りに変更したい場合はコメントを外して array_to_csv_Excel_r2 をタブ区切りで呼び出します。
  4. 処理完了のメッセージ
    ファイルの保存が完了したことを知らせるメッセージボックスを表示します。

出力されるCSVファイルの内容(カンマ区切り):

名前,年齢,住所
山田太郎,30,東京都
鈴木花子,25,大阪府
田中一郎,40,福岡県
佐藤二郎,35,北海道

このコードを実行することで、配列の内容が指定した場所にCSV形式で出力されます。

Follow me!