VBAでCSVをシートに取り込む方法はいくつかあります。文字コード・区切り文字・列ごとのデータ型をまとめて指定したい場合は、QueryTables.Add が扱いやすい方法です。テキストファイルウィザードで手作業で指定する内容を、コードで固定できます。ここでは、指定したシートにCSVを読み込み、取り込んだ行数を確認するところまでを作ります。

ほかの方法との違いも押さえておきます。

  • Workbooks.Open:CSVを手軽に開けますが、文字コードや列の型を細かく指定できません。
  • Workbooks.OpenText:文字コードや列の型を指定できますが、新しいブックとして開きます。既存のシートに入れるには転記が必要です。

完成形のコード

標準モジュールに貼り付け、先頭の定数を自分の環境に合わせて書き換えます。例として、「顧客コード, 顧客名, 取引日, 金額」の4列を持つCSVを「取込」シートに読み込みます。

Option Explicit

Sub ImportCsvToSheet()
    Const CSV_PATH As String = "C:\data\sales.csv"
    Const SHEET_NAME As String = "取込"
    Const CODE_PAGE As Long = 65001   ' UTF-8。Shift_JISなら932

    Dim ws As Worksheet
    Dim qt As QueryTable
    Dim expected As Variant
    Dim importedRows As Long
    Dim fileLines As Long
    Dim i As Long

    If Dir(CSV_PATH) = "" Then
        MsgBox "ファイルが見つかりません:" & CSV_PATH, vbExclamation
        Exit Sub
    End If

    Set ws = ThisWorkbook.Worksheets(SHEET_NAME)

    ' 前回の取り込みで残ったクエリテーブルと値を消す
    Do While ws.QueryTables.Count > 0
        ws.QueryTables(1).Delete
    Loop
    ws.Cells.Clear

    Set qt = ws.QueryTables.Add( _
        Connection:="TEXT;" & CSV_PATH, _
        Destination:=ws.Range("A1"))

    With qt
        .TextFilePlatform = CODE_PAGE
        .TextFileParseType = xlDelimited
        .TextFileCommaDelimiter = True
        .TextFileTabDelimiter = False
        .TextFileSemicolonDelimiter = False
        .TextFileSpaceDelimiter = False
        .TextFileConsecutiveDelimiter = False
        .TextFileTextQualifier = xlTextQualifierDoubleQuote
        .TextFileStartRow = 1
        ' 左の列から順に:顧客コード、顧客名、取引日、金額
        .TextFileColumnDataTypes = Array(xlTextFormat, xlTextFormat, xlYMDFormat, xlGeneralFormat)
        .RefreshStyle = xlOverwriteCells
        .AdjustColumnWidth = True
        .Refresh BackgroundQuery:=False
        importedRows = .ResultRange.Rows.Count
        .Delete   ' 値は残し、ファイルとのつながりを外す
    End With

    ' 見出しが想定どおりか(列の順番が変わっていないか)
    expected = Array("顧客コード", "顧客名", "取引日", "金額")
    For i = 0 To UBound(expected)
        If CStr(ws.Cells(1, i + 1).Value) <> expected(i) Then
            MsgBox i + 1 & "列目の見出しが想定と違います:" & ws.Cells(1, i + 1).Value, vbExclamation
            Exit Sub
        End If
    Next i

    ' シートの行数とファイルの行数を比べる
    fileLines = CountFileLines(CSV_PATH)
    If importedRows = fileLines Then
        MsgBox "取り込み完了:見出しを除いて " & (importedRows - 1) & " 件", vbInformation
    Else
        MsgBox "行数が一致しません。" & vbCrLf & _
               "シート:" & importedRows & " 行/ファイル:" & fileLines & " 行", vbExclamation
    End If
End Sub

' ファイルの物理行数を数える(LFの数。最終行の末尾に改行がなければ1行足す)
Function CountFileLines(ByVal path As String) As Long
    Dim f As Integer
    Dim buf() As Byte
    Dim i As Long
    Dim n As Long

    f = FreeFile
    Open path For Binary Access Read As #f
    If LOF(f) = 0 Then
        Close #f
        Exit Function
    End If
    ReDim buf(0 To LOF(f) - 1)
    Get #f, , buf
    Close #f

    For i = 0 To UBound(buf)
        If buf(i) = 10 Then n = n + 1
    Next i
    If buf(UBound(buf)) <> 10 Then n = n + 1

    CountFileLines = n
End Function

指定している項目の意味

項目 指定内容
Connection "TEXT;" の後にCSVのフルパス。テキストファイルとして読む指定
Destination 取り込み先の左上のセル
TextFilePlatform 文字コード。UTF-8なら 65001、シフトJISなら 932
TextFileParseType xlDelimited で区切り文字形式
TextFileCommaDelimiter True でカンマ区切り。ほかの区切り文字は明示的に False にする
TextFileConsecutiveDelimiter False にする。True だと空欄の項目が詰められ、列がずれる
TextFileTextQualifier xlTextQualifierDoubleQuote で " を引用符として扱う
TextFileStartRow 読み込みを始める行。見出し行から読むなら 1
TextFileColumnDataTypes 列ごとのデータ型(次の節で説明)
RefreshStyle xlOverwriteCells で既存のセルを上書き。既定のままだとセルが挿入されてずれることがある
Refresh BackgroundQuery:=False 読み込みが終わるまで次の行に進まない

特に重要なのが BackgroundQuery:=False です。指定しないと、読み込みが終わる前に行数の確認や後続の処理が動き出します。その結果、空のシートを相手に処理してしまうことがあります。

列ごとのデータ型を指定する

TextFileColumnDataTypes には、左の列から順に型を並べた配列を渡します。

定数 意味 使う列の例
xlGeneralFormat 標準(Excelが自動で判定) 金額・数量
xlTextFormat 文字列 顧客コード・郵便番号・電話番号
xlYMDFormat 年月日の順の日付 2026/10/05 形式の日付
xlMDYFormat / xlDMYFormat 月日年・日月年の順の日付 海外システムの日付
xlSkipColumn 読み込まない 不要な列

注意点は3つあります。

  • 配列の要素は、先頭の列から順に対応します。要素数より列が多い場合、残りの列は標準として扱われます。先頭0を残したい列が後ろの方にあるときは、その列までの型をすべて並べます。
  • CSVの列の順番が変わると、型の指定もずれます。完成形のコードには見出しのチェックを入れてあり、出力元の仕様変更に気づけるようにしています。
  • xlTextFormat を指定した列は、数値に見える値も文字列として入ります。その列で計算したい場合は、標準にするか、取り込んだ後に数値へ変換します。

取り込んだ行数と見出しを確かめる

完成形のコードでは、シートに入った行数(ResultRange.Rows.Count)とCSVファイルの行数を比べています。CountFileLines はファイルをバイト列として読み、改行(LF)の数を数えるので、UTF-8でもシフトJISでも同じように使えます。ただしファイル全体をメモリに読み込むため、非常に大きなファイルでは時間がかかります。

行数が一致しない場合は、次のような状態が考えられます。

  • ファイルの末尾に空行がある
  • 値の中に改行を含むセルがある(ファイル上の行数がレコード数より多くなる)
  • 改行コードにLFが使われていない

改行が原因で行がずれる場合の対処は、VBAでCSVを読み込むと行がずれるときの記事で扱っています。

見出しのチェックは、列の順番が変わったCSVを、ずれた型の指定のまま取り込む事故を防ぐためのものです。不一致に気づいた時点で処理を止めますが、取り込んだデータはシートに残っています。後続の処理を自動で動かす場合は、見出しと行数の両方の確認を通過したときだけ進むようにしておきます。

よくあるつまずき

  • 日本語が文字化けする:TextFilePlatform の値がファイルの文字コードと合っていません。65001 と 932 を入れ替えて試します。
  • すべてA列に入る:区切り文字の指定を確認します。セミコロン区切りやタブ区切りのファイルなら、該当する区切り文字を True にします。
  • 先頭の0が消える:該当の列が xlTextFormat になっているか、配列の位置が列の順番と合っているかを確認します。
  • 実行するたびに列が右へずれる:前回のクエリテーブルが残ったまま追加している可能性があります。コードのように、既存のクエリテーブルを削除してシートをクリアしてから取り込み、RefreshStyle を xlOverwriteCells にします。
  • 「クエリと接続」や「名前の管理」に項目が増えていく:Excelのバージョンによっては、クエリテーブルを削除しても接続や名前が残ることがあります。不要なら、「データ」タブの「クエリと接続」や、「数式」タブの「名前の管理」から削除します。
  • 取り込み時にエラーになる:取り込み先の範囲にExcelのテーブル(ListObject)が重なっていると、うまく追加できないことがあります。取り込み専用のシートを用意し、そこから別のシートへ転記する形にすると安定します。
おすすめの記事