エクセル(Excel) | エクセルマクロVBAサンプル集 | CSVの出力(書き出し)方法




CSVの出力(書き出し)方法


シート内容をCSV出力(書き出し)する方法です。

CSVの読込は、

CSVの読込方法」「CSVの読込方法(改)

こちらを参照して下さい。


2通りの方法を紹介します。

まずは、エクセルの機能をそのまま利用します。

Sub CSV出力(ByVal sht As Worksheet, Optional ByVal rngStart As Range = Nothing)
  Dim varFile As Variant
  
  varFile = Application.GetSaveAsFilename(InitialFileName:=sht.Name & ".csv", _
                      FileFilter:="CSVファイル(*.csv),*.csv", _
                      FilterIndex:=1, _
                      Title:="保存ファイルの指定")
  If varFile = False Then
    Exit Sub
  End If
    
  sht.Select
  sht.Copy
  

  '不要な先頭の行列を削除します。
  If Not rngStart Is Nothing Then
    If rngStart.Row > 1 Then
      Range(Rows(1), Rows(rngStart.Row - 1)).Delete
    End If
    If rngStart.Column > 1 Then
      Range(Columns(1), Columns(rngStart.Column - 1)).Delete
    End If
  End If
  
  ActiveWorkbook.SaveAs Filename:=varFile, FileFormat:=xlCSV, CreateBackup:=False
  ActiveWindow.Close
  
  MsgBox ("CSV出力しました。" & vbLf & vbLf & varFile)
End Sub


引数で、ワークシートと開始セルを指定できるようにしています。

これにより、どのシートからも使えるようになります。


Application.GetSaveAsFilename

保存ファイルを選択するダイアログを表示します。

シート名+「.csv」を初期のファイル名にしています。

拡張子は、csvのみ指定しています。

開始セルより上の行、左の列は削除して、CSVに出力されないようにしています。

処理の流れは、

保存ファイルの選択

シートの新規ブックへのコピー

不要な行列の削除

名前を付けて保存

これは簡単です。

しかし、これでは、いろいろ不都合な場合があります。

他システム、特にDB等へアップロードする場合には、このままでは出来ない事があるのです。

例えば、日付は、表示形式のままの文字列で出力されてしまいます。

また数値もカンマ付の場合は、"12,345"のように、文字列として出力されます。

CSV出力前に、当該シートの書式を全て直してから行えばよいのですが、

書式の変更も面倒なら、また元に戻す必要があり、何かと不都合です。


このような場合は、直接CSVを出力するようにします。

Sub CSV出力(ByVal sht As Worksheet, Optional ByVal rngStart As Range = Nothing)
  Dim varFile As Variant
  Dim FSO As New FileSystemObject
  Dim TS As TextStream
  Dim lngRowMin As Long, lngRowMax As Long
  Dim lngColMin As Long, lngColMax As Long
  Dim i As Long

  
  varFile = Application.GetSaveAsFilename(InitialFileName:=sht.Name & ".csv", _
                      FileFilter:="CSVファイル(*.csv),*.csv", _
                      FilterIndex:=1, _
                      Title:="保存ファイルの指定")
  If varFile = False Then
    Exit Sub
  End If
    
  '開始行列、終了行列を取得
  If rngStart Is Nothing Then
    lngRowMin = 1
    lngColMin = 1
  Else
    lngRowMin = rngStart.Row
    lngColMin = rngStart.Column
  End If
  lngRowMax = 最終行取得(sht)
  lngColMax = 最終列取得(sht)
  
  Set TS = FSO.CreateTextFile(Filename:=varFile, Overwrite:=True)
  
  For i = lngRowMin To lngRowMax
    TS.WriteLine CSV_EditRec(sht, i, lngColMin, lngColMax)
  Next
  
  TS.Close
  Set TS = Nothing
  Set FSO = Nothing

  MsgBox ("CSV出力しました。" & vbLf & vbLf & varFile)
End Sub


Private Function CSV_EditRec(ByVal sht As Worksheet, _
                i As Long, _
                lngColMin As Long, _
                lngColMax As Long) As String
  Dim strRec As String
  Dim strCol As String
  Dim j As Long

  strRec = ""
  For j = lngColMin To lngColMax
    Select Case True
      Case IsNumeric(sht.Cells(i, j))
        strCol = CStr(CDbl(sht.Cells(i, j)))
      Case IsDate(sht.Cells(i, j))
        If InStr(sht.Cells(i, j), "-") Then
          strCol = sht.Cells(i, j)
        Else
          strCol = Format(sht.Cells(i, j), "yyyy/mm/dd")
        End If
      Case InStr(sht.Cells(i, j), ","), InStr(sht.Cells(i, j), """")
        strCol = """" & sht.Cells(i, j) & """"
      Case Else
        strCol = sht.Cells(i, j)
    End Select
    If strRec = "" Then
      strRec = strCol
    Else
      strRec = strRec & "," & strCol
    End If
  Next
  CSV_EditRec = strRec
End Function


Function 最終行取得(ByVal sht As Worksheet) As Long
  Dim ary As Variant
  Dim i As Long, j As Long
  ary = sht.Range(sht.Cells(1, 1), sht.Cells.SpecialCells(xlLastCell))
  Do
    For i = UBound(ary, 1) To LBound(ary, 1) Step -1
      j = 1
      For j = LBound(ary, 2) To UBound(ary, 2)
        If ary(i, j) <> "" Then
          最終行取得 = i
          Exit Function
        End If
      Next j
    Next i
  Loop
End Function

Function 最終列取得(ByVal sht As Worksheet) As Long
  Dim ary As Variant
  Dim i As Long, j As Long
  ary = sht.Range(sht.Cells(1, 1), sht.Cells.SpecialCells(xlLastCell))
  Do
    For i = UBound(ary, 2) To LBound(ary, 2) Step -1
      j = 1
      For j = LBound(ary, 1) To UBound(ary, 1)
        If ary(j, i) <> "" Then
          最終列取得 = i
          Exit Function
        End If
      Next j
    Next i
  Loop
End Function


かなり長いですが、

「最終行取得」、「最終列取得」は以前に作成済のモジュールです。

行列がでこぼこに入力されている場合でも、正しく最終判定をする為に使用しています。

通常の一覧なら、End(xlUp)等でも良いでしょう。


FileSystemObjectを使用していますが、昔からある、

Open ファイル For Output As #1

でも良いです。

処理内容は単純です。

要は、


Function CSV_EditRec

の内容だけでしょう。

セルの値を判定し、データ内容によって、編集処理を分けています。

ここでは、数値、日付、「"」や「,」を含む文字列、その他、の4通りです。

日付の場合は、「-」の入った電話番号が日付判定される場合があるので、除外しています。

「CSV_EditRec」での編集は、CSVの使い道により、変更を加える必要があります。

例えば、日付は、「#2011/05/17#」のようにする必要がある場合もでてくるでしょう。

いずれにせよ、上記モジュールはかなり汎用的に作成してありますので、

コピペで、いろいろ使い回しが可能です。


トップ > エクセルExcel > マクロVBAサンプル集 > CSVの出力(書き出し)方法

★同じテーマ「エクセルマクロVBAサンプル集」の記事★
CSVの読み込み方法
CSVの読み込み方法(改)
UTF-8でCSVの読み書き(ADODB.Stream)
ADOでマスタ付加と集計(SQL)
ADOでマスタ更新(SQL)
ADOでCSVの読み込み(SQL)
ユーザー定義関数でフリガナを取得する(GetPhonetic)

★ExcelマクロVBAセミナー中上級編開催!★
2日間のセミナーです。実務で使うExcelマクロVBAの全ての答えがここにあります!

★Excelセミナー・VBAセミナーのご案内!★
実務直結の実践型エクセルセミナー、エクセルマクロVBAセミナーです。
東京の銀座にて開催する、1日集中のセミナーです。
このサイトをご覧になってセミナー参加をお決めになられた方へは、
特別特典をお付けします。



★新着記事★ ・・・ 新着記事一覧を見る
VBAでのOutlook自動操作:ExcelマクロVBA技術解説(7月8日)
他のブックのマクロを実行(Runメソッド):ExcelマクロVBA入門(6月27日)
マクロをショートカットで起動(OnKeyメソッド):ExcelマクロVBA入門(6月27日)
ナンバーリンクを解くVBAのパフォーマンス改善3:ExcelマクロVBAサンプル集(5月28日)
ナンバーリンク(パズル)を解くVBAに挑戦8:ExcelマクロVBAサンプル集(5月23日)
練習問題29(ロット引き当て):ExcelマクロVBA練習問題(5月13日)
時間計算で困ったときの確実な対処方法:エクセル関数超技(5月6日)


★人気記事★
エクセル基本操作 | ひらがな⇔カタカナの変換
エクセル関数超技 | 徹底解説(VLOOKUP,MATCH,INDEX,OFFSET)
エクセル関数超技 | セルの参照範囲を可変にする(OFFSET,COUNTA,MATCH)
エクセル関数超技 | グラフのデータ範囲を可変にする
エクセル関数超技 | 【奥義】大量データでの高速VLOOKUP
マクロVBA入門 | 第18回.最終行の取得(End,Rows,Count)
マクロVBA入門 | 第29回.セル・行・列の削除・挿入(Delete,Insert)
マクロVBA入門 | 第91回.条件付き書式(FormatCondition)
マクロVBA入門 | 第93回.ピボットテーブル(PivotTable)
マクロVBA入門 | 第98回.Findメソッド,FindNextメソッド(検索,次を検索)
VBAサンプル集 | CSVの読み込み方法
VBAサンプル集 | CSVの出力(書き出し)方法
VBAサンプル集 | WEBデータの取得方法
VBA技術解説 | エクセルVBAのパフォーマンス・処理速度に関するレポート
VBA技術解説 | Dictionary(ディクショナリー)の使い方について