取り込み先のシステムから、「すべての項目をダブルクォーテーション(")で囲んだCSVで提出してください」と指定されることがあります。ところが、Excelで「CSV(コンマ区切り)」や「CSV UTF-8(コンマ区切り)」を選んで保存しても、ほとんどの項目は囲まれません。この記事では、その理由と、VBAや関数で全項目を囲んで出力する方法を説明します。出力後に引用符が二重になっていないか確かめる方法も紹介します。

標準の保存で全項目を囲めない理由

ExcelのCSV保存では、引用符が必要な項目だけが囲まれます。値にカンマ、ダブルクォーテーション、改行が含まれる項目は囲み、それ以外はそのまま書き出す仕組みです。保存画面には、「すべての項目を囲む」という設定はありません。

セルの値 Excelで保存した結果
山田商店 山田商店
東京都,港区 "東京都,港区"
19"モニター "19""モニター"

値の中の「"」は、「""」のように2つ重ねて書きます。CSVでよく使われる書き方です。

やってしまいがちなのが、セルの値そのものに「"」を付けてから保存する方法です。セルに "山田商店" と入力して保存すると、Excelはこの「"」を値の一部と見なします。その結果、"""山田商店""" のように引用符が重なったCSVになってしまいます。全項目を囲むには、Excelの保存機能を使わず、書き出す処理を自分で用意する必要があります。

先に取り込み先の仕様を確認する

「全項目を囲む」以外にも、取り込み先ごとに細かい決まりがあります。出力方法を作る前に確認しておくと、作り直しを減らせます。

  • 見出し行も引用符で囲むか。見出し行自体が必要か
  • 空欄は "" と書くか、何も書かないか
  • 数値・日付も囲むか
  • 日付の形式(例:2026/10/05、2026-10-05)
  • 文字コード(Shift_JISかUTF-8か。UTF-8ならBOMの有無)
  • 改行コード(CRLFかLFか)
  • 値に「"」が入っている場合の書き方(多くは "")

この記事の手順は、「見出しを含めて全項目を囲む」「空欄は ""」「改行コードはCRLF」という仕様を前提にしています。仕様が違う場合は、該当する部分を変更してください。

方法1:VBAで全項目を囲んで出力する

件数が多い場合や、毎回同じ形式で出力する場合は、VBAを使うのが確実です。次のマクロは、作業中のシートのA1から続く表を、全項目を「"」で囲んだCSVにして、ブックと同じフォルダーに保存します。元のブックは変更しません。

Sub ExportCsvAllQuoted()
    Dim ws As Worksheet
    Dim rng As Range
    Dim r As Long, c As Long
    Dim lines() As String
    Dim fields() As String
    Dim filePath As String
    Dim fileNo As Integer

    Set ws = ActiveSheet
    Set rng = ws.Range("A1").CurrentRegion   ' A1から続く表全体

    If ws.Parent.Path = "" Then
        MsgBox "先にブックを保存してください。"
        Exit Sub
    End If
    filePath = ws.Parent.Path & "\" & ws.Name & "_quoted.csv"

    ReDim lines(1 To rng.Rows.Count)
    ReDim fields(1 To rng.Columns.Count)

    For r = 1 To rng.Rows.Count
        For c = 1 To rng.Columns.Count
            fields(c) = QuoteField(rng.Cells(r, c))
        Next c
        lines(r) = Join(fields, ",")
    Next r

    ' 日本語版Windowsの既定の文字コード(Shift_JIS)で書き出す
    fileNo = FreeFile
    Open filePath For Output As #fileNo
    For r = 1 To UBound(lines)
        Print #fileNo, lines(r)
    Next r
    Close #fileNo

    MsgBox rng.Rows.Count & " 行を出力しました。" & vbCrLf & filePath
End Sub

Private Function QuoteField(ByVal cell As Range) As String
    Dim v As Variant
    Dim s As String

    v = cell.Value
    If IsError(v) Then
        s = cell.Text                     ' #N/A などは表示どおり
    ElseIf VarType(v) = vbDate Then
        s = Format(v, "yyyy/mm/dd")       ' 取り込み先の形式に合わせる
    Else
        s = CStr(v)
    End If

    ' 値の中の " を "" にしてから、全体を " で囲む
    QuoteField = """" & Replace(s, """", """""") & """"
End Function

使う前に確認すること:

  • 範囲:CurrentRegion は、A1から空行・空列で区切られるところまでの範囲です。表の途中に何も入っていない行があると、そこで範囲が終わります。範囲を固定したい場合は、ws.Range("A1:F200") のように直接指定してください。
  • 数値:CStr(v) は、セルの値をそのまま文字にします。表示形式で付けた桁区切り(1,234)や先頭の0(00123)は出力されません。表示どおりに出したい列は、cell.Text を使うか、Format で形式を指定します。ただし cell.Text は、列幅が狭いと「###」になるので、列幅も確認してください。
  • 日付:時刻を含む列は、"yyyy/mm/dd hh:nn:ss" のように形式を変えます。
  • 上書き:同じ名前のファイルがあると、上書きされます。
  • 文字コード:Open ... For Output と Print # で書き出すと、日本語版Windowsでは通常Shift_JISになります。Shift_JISにない文字(一部の記号や異体字など)は、「?」に変わることがあります。

UTF-8で出力したい場合は、Open から Close #fileNo までを次のコードに置き換えます。

    Dim st As Object
    Set st = CreateObject("ADODB.Stream")
    st.Type = 2                 ' テキスト
    st.Charset = "UTF-8"
    st.Open
    st.WriteText Join(lines, vbCrLf) & vbCrLf
    st.SaveToFile filePath, 2   ' 2 = 上書き保存
    st.Close

この書き方だと、ファイルの先頭にBOMが付きます。取り込み先がBOMなしを求めている場合は、BOMを取り除く処理を追加してください。

方法2:関数で1行分の文字列を作る

件数が少なく、一度だけ出力できればよい場合は、関数で1行分の文字列を作る方法もあります。A〜F列の表で、2行目からデータが入っているとします。空いている列(例:H2)に次の式を入れ、下の行までコピーします。Microsoft 365のように、範囲をまとめて計算できるExcelを前提にしています。

=TEXTJOIN(",",FALSE,""""&SUBSTITUTE(A2:F2,"""","""""")&"""")
  • """" は「"」1文字を表します。
  • SUBSTITUTE で値の中の「"」を「""」に変え、その前後を「"」で囲んでいます。
  • TEXTJOIN の2番目の引数を FALSE にしているので、空欄も "" として残ります。
  • 日付は数値(シリアル値)として扱われるため、「46300」のような数字になります。日付の列がある場合は、その列だけ TEXT(C2,"yyyy/mm/dd") で文字に変えてからつなぐ式にしてください。

作った文字列をファイルにするときは、次の点に気をつけます。

  • H列をExcelのCSV保存で保存しない:作った文字列にはカンマと「"」が含まれます。そのためExcelがさらに引用符で囲み、"""山田商店"",""..." のように二重になってしまいます。
  • メモ帳に貼り付けて保存する:H列をコピーしてメモ帳に貼り付け、「名前を付けて保存」で文字コードを選んで、拡張子を .csv にして保存します。ただし、セル内改行やタブを含むセルをコピーすると、Excelがそのセル全体を引用符で囲んで貼り付けることがあります。貼り付けた結果は、次の手順で必ず確認してください。

セル内改行を含む表や、毎回出力する表には、方法1のVBAを使うほうが安全です。

出力後に確認すること

出力したCSVは、Excelではなくメモ帳で開いて確認します。Excelで開くと引用符が外れた状態で表示されるので、項目が囲まれているかどうかわかりません。また、Excelで開いたまま上書き保存すると、標準の保存ルールで書き直されて、引用符が外れてしまいます。

引用符が二重になっていないか

  • 各項目が「"」1つで始まり、「"」1つで終わっているか。
  • メモ帳の検索(Ctrl+F)で """ を検索する。見つかったら、元のセルに「"」が入力されていないか、値の先頭や末尾が本当に「"」なのかを確認する。
  • 値の中の「"」だけが "" になっているか(例:"19""モニター")。

形式

  • 見出し行の扱いや空欄の書き方("" か、何も書かないか)が、仕様どおりか。
  • 1行目と最終行で、項目数がそろっているか。
  • 先頭の0、日付の形式、数値の桁区切りが想定どおりか。
  • メモ帳の下部(ステータスバー)に出る文字コード(UTF-8、UTF-8 (BOM 付き)、ANSIなど)が、仕様と合っているか。ステータスバーが表示されていない場合は、「表示」メニューから表示します。
  • 行数が元の表と合っているか。セル内改行を含む行はメモ帳では複数行に分かれて見えるので、その分を差し引いて数えます。

最後に、取り込み先に少ない件数で試しに取り込み、文字化けや列のずれがないか確認します。問題がなければ、本番のデータを出力してください。

おすすめの記事