【めざせExcelマスターへの道】CSVを開く方法について②

Excel
  • VBAを使ってCSVを開く際、「”」で囲まれていた中に「,」が入っている場合の対処法を検討します。
スポンサーリンク

前回までの復習

前回は、CSVのそもそもの性質や、一般的なExcelでの開き方、データ型が自動判定されることに対する対処法をまとめていきました。

このとき、一行ずつ読み込みつつ、「,」を区切り文字として区切り、一度配列格納した後セルに書き出すという手法を採りました。

問題は、「”」による引用符がついており、データの中身として、「,」が含まれるケースです。

具体的には、「”test Co., Ltd”, “aaa”, “3-2″」のような場合を指します。

対処法は?

その①~切り分けてくっつける~

この場合における対処法は、大きく二つあります。

その一つが、いったん切り分けてからくっつけるというやり方です。

前回は次のようなコードで処理をしました。

Sub OpenCSVBasic()
  Dim FileName As Variant
  Dim bufRec As String
  Dim bufSplit() As String
  Dim i As Long, j As Long

  FileName = Application.GetOpenFilename(FileFilter:="CSVファイル(*.csv),*.csv")
  If FileName = False Then Exit Sub

  Open FileName For Input As #1
  
  i = 0
  Do Until EOF(1)
    Line Input #1, bufRec 
    i = i + 1
    bufSplit = Split(bufRec, ",") 
    For j = 0 To UBound(bufSplit)
      Cells(i, j + 1) = bufSplit(j)
    Next
  Loop
  
  Close #1
End Sub

このような処理を、「”test Co., Ltd”, “aaa”, “3-2″」に対して行うと、「”test Co. | LTD” | “aaa” | “3-2″」という形でセルが分かれてしまいます。

そこで、「頭に「”」がついておりお尻についてないセル」のすぐ後に、「頭に「”」がついていなくてお尻についているセル」が続いた場合に、これら二つをつなげ、後ろのセルを削除する、という処理を入れてあげれば対応可能となります。

具体的には、次のようなコードで処理します。

Sub OpenCSVBasic()
  Dim FileName As Variant
  Dim bufRec As String
  Dim bufSplit() As String
  Dim i As Long, j As Long

  FileName = Application.GetOpenFilename(FileFilter:="CSVファイル(*.csv),*.csv")
  If FileName = False Then Exit Sub

  Open FileName For Input As #1
  
  i = 0
  Do Until EOF(1)
    Line Input #1, bufRec 
    i = i + 1
    bufSplit = Split(bufRec, ",") 
    For j = 0 To UBound(bufSplit)
      Cells(i, j + 1) = bufSplit(j)
    Next
        For j = 0 to UBound(bufSplit)
            If Left(Cells(i, UBound(bufSplit) + 1 - j), 1) = """" _
            and Right(Cells(i, UBound(bufSplit) + 1 - j), 1) <> """" _
            and Right(Cells(i, UBound(bufSplit) + 2 - j), 1) = """" _
            and Left(Cells(i, UBound(bufSplit) + 2 - j), 1) <> """" then
                Cells(i, UBound(bufSplit) + 1 - j) = Cells(i, UBound(bufSplit) + 1 - j), 1) & "," Cells(i, UBound(bufSplit) + 2 - j)
                Cells(i, UBound(bufSplit) + 2 - j).Delete Shift:=xlToLeft
            End if
        Next
  Loop
  
  Close #1
End Sub

少し処理は長いですが、要は右から順番にセルを見ていき、条件に合致したら、セルの中身を結合して、後ろのセルを削除するというものです。

もう一つのやり方は?

もう一つのやり方は、そもそもSplit関数を使わず、一つ一つ文字を見ていき、結合子かどうかを条件に応じて判定するというものです。

詳しくは次回解説していきます!

コメント

タイトルとURLをコピーしました