中小企業情報化塾

CSV to Excelサンプル

今回はCSVを読み込んで、そのままExcelに書き込むサンプルを紹介します。このままでは当然Excelを開いて読み込んだのと同じです。
しかし、一度プログラムでセルを解析していますので、書き込み時に自由に手を加えることが可能です。列幅を調整したり、列の並びを変えたり、数値を加工したり特定の列同士の合計の列を加えたりと様々な加工を読み込み時に加えられるのがメリットです。

const DQ = """"  'ダブルクォート
const Delimita = ","
const HeaderLine = 1
set fso = CreateObject("Scripting.FileSystemObject")
set currentfolder = fso.GetFolder(".")
set args = WScript.Arguments
 
CSVtoExcel  args(0)
 
WScript.Quit
 

Sub CSVtoExcel( fileName )
  DIM line, fileo, lineCount, schema, oneLine, excelfilename
  dim col, row
  Set ExcelApp = CreateObject("Excel.Application")
  set oBook = ExcelApp.Workbooks.Add
  set oSheet = oBook.WorkSheets(1)
  set Header = CreateObject("Scripting.Dictionary")
 
  if fso.FileExists( filename ) then
      set fileo = fso.OpenTextFile(fileName , 1, false, false)
      set schema = CreateObject("Scripting.Dictionary")
      set oneLine = CreateObject("Scripting.Dictionary")
      linecount = 0
      row = 2
      do until fileo.AtEndofStream
        line = fileo.ReadLine()
        if left( line, 1) <> "#" then
            linecount = linecount + 1
            if linecount = HeaderLine then  'タイトル行
                call ParseSchema( line, schema ) 
                col = 1
                for each key in schema.keys
                   col = SetHeader( oSheet, Header, key, 20, "G/標準", col )   '標準
                next
            elseif linecount > HeaderLine then
                  if ParseLine( line, oneLine ) = 1 then '解析有効
                     '   処理したい内容をここに記述
                     for each key in schema.keys
                        oSheet.Cells( row, Header.item( key )).value = Trim( oneLine.Item(schema.Item(key)))
                     next
                     row = row + 1
                  end if
            end if
        end if
      loop
      fileo.close
      excelfilename = Replace( filename, ".csv", ".xlsx" )
      oBook.saveas currentfolder.path & "\" & excelfilename
     oBook.close
  else
        WScript.echo "Can't file " & filename
  end if
end sub
 

Function SetHeader(oSheet, Header, colname, colwidth, ViewType, colnum )
  oSheet.Cells(1,colnum).value = colname
  oSheet.Columns(colnum).ColumnWidth  = colwidth
  if ViewType <> "" then
    oSheet.Columns(colnum).NumberFormatLocal = ViewType
  end if
  Header.Add colname, colnum
  colnum = colnum + 1
  SetHeader = colnum
end function
 

Sub ParseSchema( line, schema )
  dim columns, i
  line = Replace( line, DQ, "" )
  schema.removeall
  columns = split(line, Delimita , -1)
  for i = 0 to Ubound(columns)
    if Trim(columns(i)) <> "" then
      schema.add Trim(columns(i)), i+1
    end if
  next
end sub
 
Function ParseLine( line, rowData )
  dim c, cp, qp, q, l, tmp
  rowData.RemoveAll()
  ParseLine = 0
  c = 1          'column ID
  q = 0          'quote mode
  if left(line,1) = "#" then
    ParseLine = false
    exit function
  end if
  l = trim(line)
  do while len(l) > 0
    if Left(l, 1) = DQ then
      q = 1
      l = Mid( l, 2, len(l)-1)    '左端の"をカット
    else
      q = 0
    end if
    if q then
      qp = InStr(l, DQ)
      if qp = 0 then 
         WScript.echo "フォーマットエラー:" & line
         exit function
      else
         tmp = left(l, qp -1 )
         if len(trim(tmp)) = 0 then
           rowData.add c, ""
         else
           rowData.add c, tmp
         end if
         l = mid( l, qp + 1, len(l)- qp )
         cp = InStr(l, ",")
         if cp = 0 then
           ParseLine = 1
           exit function
         end if
         l = mid( l, cp + 1, len(l)- cp )
         c = c + 1
      end if
    else
      cp = InStr(l, ",")
      if cp = 0 then
        rowData.add c, trim(l)
        ParseLine = 1
        exit function
      end if
      tmp = left(l, cp - 1)
      if len(trim(tmp)) = 0 then
        rowData.add c , ""
      else
        rowData.add c, tmp
      end if
      l = mid( l, cp + 1, len(l)- cp ) 
      c = c + 1
    end if
  loop
  ParseLine = 1
end Function

今回はサンプルCSVは示しません。1行目がヘッダーになるCSV(ファイル形式はS-JIS)であれば、なんでもかまいません。
 >cscript <スクリプトファイル名>
で実行してください。
プログラムのポイントは

    col = 1
      for each key in schema.keys
            col = SetHeader( oSheet, Header, key, 20, "G/標準", col )   '標準
      next

で、ヘッダー行を書き込み

       for each key in schema.keys
           oSheet.Cells( row, Header.item( key )).value = Trim( oneLine.Item(schema.Item(key)))
       next
       row = row + 1

でデータ行を追加しています。いずれも”key”が列名であることが分かれば、変更は容易だと思います。
結構応用の広いパターンだと思います。是非試してみてください。

*Excelは、米国Microsoft Corporationの米国およびその他の国における登録商標または商標です。