【Excel VBA入門】基本的なCSVファイルの読み込みと書き出し方法

【Excel VBA入門】基本的なCSVファイルの読み込みと書き出し方法

ITを使った業務効率化の相談ができるコミュニティ「業務自動化推進ラボ」を公開しました。

こんにちは、業務自動化ツール開発担当の吉池(@valmore_myoshi)です。

CSVは各フィールドがカンマ「,」で区切られたファイル形式です。システムからデータをエクスポートするときにCSV形式がよく使われます。

出力したCSVファイルはExcelで開き、データ編集する方が多いのではないでしょうか?Excel上でも読み書きできますが、VBAプログラムのなかでもCSVを取り込みたいといったニーズもあるはずです。

そこで今回はVBAを使ったCSVファイルの読み込み、書き出しを解説します。外部データを扱う基礎にもなるので、ぜひこの機会に習得しましょう!

VBAでCSVを読み込む方法

CSVを簡単に開ける方法を2つ解説します。一つ目はOpenステートメントを使ってCSVデータを一行ずつ読み込む方法。二つ目はQueryTableオブジェクトを使ってCSVをワークシートに読み込む方法です。

CSVサンプルとして下記のような売上データを想定しています。ダウンロードはこちらから。

CSVサンプル

OpenステートメントでCSVを開く方法

CSVを読み込む方法一つ目はOpenステートメントです。

  1. Dim filePath As String
  2. # CSVファイルのパスを指定
  3. filePath = ThisWorkbook.Path & "\Book1.csv"
  4. Open filePath For Input As #1
Dim filePath As String

# CSVファイルのパスを指定
filePath = ThisWorkbook.Path & "\Book1.csv"
    
Open filePath For Input As #1

Openステートメントでは、読み込みたいCSVファイルパスアクセスモードファイル番号を指定します。アクセスモードはAppend(追記)やOutput(書き込み)など複数ありますが、今回はInput(読み込み)を指定します。ファイル番号は読み込むファイルを識別するもので、1から始まる番号を指定します。

CSVにアクセスできたらLine Inputステートメントで一行ずつ読み込みます。

  1. Dim line As String
  2. Dim lineItems As Variant, item As Variant
  3. Do Until EOF(1)
  4. Line Input #1, line
  5. lineItems = Split(line, ",")
  6. For Each item In lineItems
  7. ‘ CSVの各フィールドに対する処理
  8. Debug.Print (item)
  9. Next
  10. Loop
  11. Close #1
Dim line As String
Dim lineItems As Variant, item As Variant

Do Until EOF(1)
    Line Input #1, line
    lineItems = Split(line, ",")
    For Each item In lineItems
        ‘ CSVの各フィールドに対する処理
        Debug.Print (item)
    Next
Loop

Close #1

Line Inputステートメントにファイル番号と変数(ここではline)を指定することで、読み込んだ一行分の文字列が変数に代入されます。そのままだとカンマ区切りの文字列なので、Split関数で区切り文字にカンマを指定して文字列を分割します。

ファイルの終端に到達したらループ処理から抜けるよう、EOF関数にファイル番号を指定します。終端に到達するとTrueを返してDo Until ~ Loopを抜け、Closeステートメントで読み込みを終了します。

全体のコードは下記の通り。

  1. Dim filePath As String, line As String
  2. Dim lineItems As Variant, item As Variant
  3. # CSVファイルのパスを指定
  4. filePath = ThisWorkbook.Path & "\Book1.csv"
  5. Open filePath For Input As #1
  6. Do Until EOF(1)
  7. Line Input #1, line
  8. lineItems = Split(line, ",")
  9. For Each item In lineItems
  10. ‘ CSVの各フィールドに対する処理
  11. Debug.Print (item)
  12. Next
  13. Loop
  14. Close #1
Dim filePath As String, line As String
Dim lineItems As Variant, item As Variant

# CSVファイルのパスを指定
filePath = ThisWorkbook.Path & "\Book1.csv"

Open filePath For Input As #1

Do Until EOF(1)
    Line Input #1, line
    lineItems = Split(line, ",")
    For Each item In lineItems
        ‘ CSVの各フィールドに対する処理
        Debug.Print (item)
    Next
Loop

Close #1

QueryTablesで高速に開く方法

QueryTableオブジェクトは外部データの接続やデータ形式を管理するオブジェクトです。今回はCSVに接続し、データ形式として文字コードや区切り文字を設定します。

  1. Dim connection As String
  2. Dim qt As QueryTable
  3. connection = "TEXT;" & ThisWorkbook.Path & "\Book1.csv"
  4. Set qt = ActiveSheet.QueryTables.Add( _
  5. Connection:=connection, Destination:=Range("B2") _
  6. )
Dim connection As String
Dim qt As QueryTable

connection = "TEXT;" & ThisWorkbook.Path & "\Book1.csv"

Set qt = ActiveSheet.QueryTables.Add( _
    Connection:=connection, Destination:=Range("B2") _
)

まずは接続先を指定する文字列の作成から始めます。DBやWebなどさまざまな外部データと接続できますが、今回はCSV、つまりテキストファイルと接続します。「TEXT;」のあとに続けてCSVファイルパスを指定します。

QueryTablesオブジェクトのAddメソッドの引数Connectionに接続先文字列、 DestinationにCSVデータの展開先を指定することでQueryTableオブジェクトを取得できます。ここで展開先として指定しているB2を基準にCSVが読み込まれます。

次にデータ形式を指定していきます。

  1. Dim dataTypes As Variant
  2. dataTypes = Array( _
  3. xlYMDFormat, _
  4. xlTextFormat, _
  5. xlTextFormat, _
  6. xlGeneralFormat, _
  7. xlGeneralFormat _
  8. )
  9. With qt
  10. .TextFilePlatform = 65001
  11. .TextFileParseType = xlDelimited
  12. .TextFileCommaDelimiter = True
  13. .TextFileColumnDataTypes = dataTypes
  14. .Refresh BackgroundQuery:=False
  15. .Delete
  16. End With
Dim dataTypes As Variant

dataTypes = Array( _
    xlYMDFormat, _
    xlTextFormat, _
    xlTextFormat, _
    xlGeneralFormat, _
    xlGeneralFormat _
)

With qt
    .TextFilePlatform = 65001
    .TextFileParseType = xlDelimited
    .TextFileCommaDelimiter = True
    .TextFileColumnDataTypes = dataTypes
    .Refresh BackgroundQuery:=False
    .Delete
End With

取得したQueryTableオブジェクトのプロパティやメソッドを使っていくので、変数名の記述を省略するためにWithステートメントを使います。

QueryTableオブジェクトのTextFilePlatformプロパティでは文字コードを指定できます。区切り文字としてカンマを指定する場合、TextFileParseTypeプロパティにxlDelimited(カンマ区切り)、TextFileCommaDelimiterプロパティにTrueを指定します。

TextFileColumnDataTypesプロパティはCSVの各フィールドのデータ型を配列で指定します。今回想定しているCSVサンプルは下記のように5つのフィールドがあり、特に商品番号は普通に開くと先頭の0が消えてしまいます。そのため、データ型としてテキストを選択し、先頭の0が消えないようにしています。

CSVサンプル

TextFileColumnDataTypesでよく使う4つのデータ型を覚えておきましょう。

データ型説明
xlGeneralFormat一般形式
xlYMDFormatYMD日付形式
xlTextFormatテキスト
xlSkipColumnフィールドをスキップ

データをワークシートに展開するときはRefreshメソッドを使います。引数のBackgroundQueryはバックグラウンドでのデータ更新を許可するものです。データ更新が終わってから次の処理に進みたいのでFalseを指定します。

最後のDeleteメソッドは外部データ、ここではCSVデータとの接続を削除しています。QueryTableは外部データとの接続設定を保存しているので、外部データに変更があったあとにRefreshするとワークシートにも変更が反映されます。継続的に更新する必要がないのなら接続を削除しましょう。

全体のコードは下記の通りです。

  1. Dim filePath As String, connection As String
  2. Dim qt As QueryTable
  3. Dim dataTypes As Variant
  4. connection = "TEXT;" & ThisWorkbook.Path & "\Book1.csv"
  5. Set qt = ActiveSheet.QueryTables.Add( _
  6. Connection:=connection, Destination:=Range("B2") _
  7. )
  8. dataTypes = Array( _
  9. xlYMDFormat, _
  10. xlTextFormat, _
  11. xlTextFormat, _
  12. xlGeneralFormat, _
  13. xlGeneralFormat _
  14. )
  15. With qt
  16. .TextFilePlatform = 65001
  17. .TextFileParseType = xlDelimited
  18. .TextFileCommaDelimiter = True
  19. .TextFileColumnDataTypes = dataTypes
  20. .Refresh BackgroundQuery:=False
  21. .Delete
  22. End With
Dim filePath As String, connection As String
Dim qt As QueryTable
Dim dataTypes As Variant

connection = "TEXT;" & ThisWorkbook.Path & "\Book1.csv"

Set qt = ActiveSheet.QueryTables.Add( _
    Connection:=connection, Destination:=Range("B2") _
)

dataTypes = Array( _
    xlYMDFormat, _
    xlTextFormat, _
    xlTextFormat, _
    xlGeneralFormat, _
    xlGeneralFormat _
)
    
With qt
    .TextFilePlatform = 65001
    .TextFileParseType = xlDelimited
    .TextFileCommaDelimiter = True
    .TextFileColumnDataTypes = dataTypes
    .Refresh BackgroundQuery:=False
    .Delete
End With

ExcelファイルをCSVに書き出す方法

CSVをExcelファイルに読み込むときは長々とコードを書きましたが、ExcelファイルをCSVに書き出すのはとてもシンプル!WorkbookオブジェクトのSaveAsメソッドの引数FileFormatにCSV形式を表すxlCSVを指定して保存するだけです。

  1. Dim filePath As String
  2. Dim wb As Workbook
  3. filePath = ThisWorkbook.Path & "\Book1.xlsx"
  4. Set wb = Workbooks.Open(filePath)
  5. ‘ データの編集処理
  6. wb.SaveAs Filename:=ThisWorkbook.Path & "\csv-test.csv", FileFormat:=xlCSV
Dim filePath As String
Dim wb As Workbook

filePath = ThisWorkbook.Path & "\Book1.xlsx"

Set wb = Workbooks.Open(filePath)

‘ データの編集処理

wb.SaveAs Filename:=ThisWorkbook.Path & "\csv-test.csv", FileFormat:=xlCSV

まとめ

VBAを使ったCSVの読み込み、書き出しの方法を解説しました。CSVの読み込みはOpenステートメントを使った基本的な方法とデータ接続を管理するQueryTableオブジェクトの2つ紹介しました。

Openステートメントでは文字列として、QueryTableはワークシートにCSVデータが読み込まれるので、用途に応じて使い分けましょう。書き込みはSaveAsだけなので簡単ですね。

CSVでデータを加工したり、分析することは多々あるので、CSVの読み書きから習得していきましょう。