ray88’s diary

お仕事で困ったとき用の自分用の覚書

CSVにダブルクォーテーションを付けて編集後、新たなCSVファイルに書き出し(文字コード日本語の場合)

■ダブルクォーテーションなしのCSVにダブルクォーテーションを付けて加工する。
 書き出す際にOpenメソッドのOutPutモードで書き出そうとすると
 ダブルクォーテーションが2重についてしまい失敗する(””項目”” の様になる)
 読み取りをOpenメソッドのInputモード、書き出しはFileSystemObjectの
 TextStreamのForWritingモードで開き、WriteLineで書き込んだところ、成功
■編集前CSV
f:id:ray88:20200201114112p:plain
■編集後CSV
f:id:ray88:20200201114130p:plain
■以下はFileSystemObjectを参照設定済の場合の書き方。遅延バインディングの場合の
 書き方はこのページの一番下に表記。

Sub editCsv()

    Dim FSO As New FileSystemObject
    Dim MyPath As String                '読込用CSVのPath
    Dim editPath As String              '書込用CSVのPath
    Dim editText As TextStream          'TextStreamオブジェクト格納用
    Dim intFileNumber As Integer        'ファイル番号格納用
    Dim intIndex As Long                '行番号取得用
    Dim temp As Variant                 '読取用ファイルのテキスト一時格納用
    Dim dataArray As Variant            '読込データ各様用配列
    Dim editData As Variant             '配列より取り出したデータ格納用
    Dim editLineData As Variant         'データ書き込み時に各データを結合して格納
    Dim maxNum As Integer               '配列最大値格納用
    Dim i As Integer                    '配列カウント用変数
    
    '読込用CSVのファイルパスを格納
    MyPath = "C:\Users\デスクトップ\編集前データ.csv"
    
    '書込用CSVのファイルパスを格納
    editPath = "C:\Users\デスクトップ\編集後データ.csv"
    
    '書込用CSVファイルを生成
    FSO.createtextfile (editPath)
    
    '書込みモードで書込用CSVファイルを開く
    Set editText = FSO.OpenTextFile(editPath, ForWriting)
    
    'ファイル番号を取得
    intFileNumber = FreeFile
    
    '読込モードでファイルを開く
    Open MyPath For Input As #intFileNumber

    'インデックス番号を初期化。このプログラムではインデックスを使用してないが
    '見出し行を飛ばして処理したり、最終行数を取得したりする際に使用する
    intIndex = 0

    'ファイルの最後まで繰り返し
    Do Until EOF(intFileNumber)
  
       '各フィールドの値を1行分参照して変数「temp」に格納
       Line Input #intFileNumber, temp
       
       '「temp」に格納した1行分の値をカンマで区切って配列「dataArray」に格納
       dataArray = Split(temp, ",")
       
       '配列「dataArray」の最大値を取得
       maxNum = UBound(dataArray)
       
       For i = 0 To maxNum       
            '配列の中身が空なら
            'ダブルクォーテーションで囲まずカンマのみつける
            If dataArray(i) = "" Then
                editData = dataArray(i)
                editLineData = editLineData & editData & ","
                
            '配列の中で数値や日付データなどダブルクォーテーションを
            '付けたくない列番号を指定(必要ない場合はコメントアウトして使用)
            ElseIf i = 3 Then
                editData = dataArray(i)
                editLineData = editLineData & editData & ","

            '上記以外の条件、または最終項目以外の時に
            'ダブルクォーテーションで項目を囲んでカンマをつける
            ElseIf i <> maxNum Then            
                editData = Chr(34) & dataArray(i) & Chr(34)
                editLineData = editLineData & editData & ","
            
            '配列の最大値(一番最後のカラム)の場合は
            'ダブルクォーテーションで囲んでカンマをつけない
            ElseIf i = maxNum Then            
                editData = Chr(34) & dataArray(i) & Chr(34)
                editLineData = editLineData & editData                
            End If            
       Next i
       
        '書込用CSVに編集後データを1行分書込み
        editText.WriteLine editLineData
        'デバック用
         Debug.Print editLineData
        '編集後データ格納用変数を初期化
        editLineData = ""
       intIndex = intIndex + 1
       
    Loop
    
    '終了処理
    Close #intFileNumber
    editText.Close
    Set editText = Nothing
    Set FSO = Nothing
    
End Sub

■FileSystemObjectを遅延バインディングで使用する際は以下の部分を変更してコードを書く
 ①変数「FSO」と「editText」をObject型で宣言する。CreateObjectでバインディングする。

Dim FSO As Object
Dim editText As Object          'TextStreamオブジェクト格納用
Set FSO = CreateObject("Scripting.FilesystemObject")

②書込用CSVを変数にセットする際、書込みモードをForWritingではなく、定数の「2」で指定する。

 Set editText = FSO.OpenTextFile(editPath, 2)