読み込みたいCSVデータ要素に「、(カンマ)」や「”(ダブルクォート)」がある場合の対処方法について簡潔に紹介します。
通常、システム等からダウンロードしたCSVデータは、メモ帳などで開くと上図のような形かと思います。引用符:ダブルクォート(データ要素ごとにダブルクォート(引用符)で囲まれた形)
この要素内にダブルクォートやカンマが含まれているものをマクロで読み込む場合の対処法です。(上手の赤枠)
ダブルクォート、カンマの判別のサンプルコード
ネット上でダブルクォートとカンマを判別して、読み込む方法はたくさん掲載されていました。
ウェブサイト「エクセルの神髄」に掲載されていたサンプルコードを解説していきたいと思います。
Sub CSV入力2()
Dim varFileName As Variant
Dim intFree As Integer
Dim strRec As String
Dim strSplit() As String
Dim i As Long, j As Long, k As Long
Dim lngQuote As Long
Dim strCell As String
varFileName = Application.GetOpenFilename(FileFilter:="CSVファイル(*.csv),*.csv", _
Title:="CSVファイルの選択")
If varFileName = False Then
Exit Sub
End If
intFree = FreeFile '空番号を取得
Open varFileName For Input As #intFree 'CSVファィルをオープン
i = 0
Do Until EOF(intFree)
Line Input #intFree, strRec '1行読み込み
i = i + 1
j = 0
lngQuote = 0
strCell = ""
For k = 1 To Len(strRec)
Select Case Mid(strRec, k, 1)
Case "," '「"」が偶数なら区切り、奇数ならただの文字
If lngQuote Mod 2 = 0 Then
Call PutCell(i, j, strCell, lngQuote)
Else
strCell = strCell & Mid(strRec, k, 1)
End If
Case """" '「"」のカウントをとる
lngQuote = lngQuote + 1
strCell = strCell & Mid(strRec, k, 1)
Case Else
strCell = strCell & Mid(strRec, k, 1)
End Select
Next
'最終列の処理
Call PutCell(i, j, strCell, lngQuote)
Loop
Close #intFree
End Sub
Sub PutCell(ByRef i As Long, ByRef j As Long, ByRef strCell As String, ByRef lngQuote As Long)
j = j + 1
'「""」を「"」で置換
strCell = Replace(strCell, """""", """")
'前後の「"」を削除
If strCell = """" Then
strCell = ""
ElseIf Left(strCell, 1) = """" And Right(strCell, 1) = """" Then
strCell = Mid(strCell, 2, Len(strCell) - 2)
End If
Cells(i, j) = strCell
strCell = ""
lngQuote = 0
End Sub
コード解説
コードのロジックとしては、CSVのデータ要素は必ず「””(ダブルクォート)」で囲まれているので、ダブルクォートが奇数の場合はデータ要素の始めのダブルクォート、偶数の場合はデータ要素の終わりのダブルクォートとなります。そして、偶数のダブルクォートの後のカンマで1つのデータ要素を判別しています。
偶数ダブルクォート後のカンマ以外
Mid(strRec, k, 1)
変数strRec(1行分のデータ)をMid関数を使って、左から1文字ずつ「、カンマ」を検索しています。
For k = 1 To Len(strRec)
Select Case Mid(strRec, k, 1)
Case "," '「"」が偶数なら区切り、奇数ならただの文字
If lngQuote Mod 2 = 0 Then
Call PutCell(i, j, strCell, lngQuote)
Else
strCell = strCell & Mid(strRec, k, 1)
End If
Case """" '「"」のカウントをとる
lngQuote = lngQuote + 1
strCell = strCell & Mid(strRec, k, 1)
Case Else
strCell = strCell & Mid(strRec, k, 1)
End Select
Next
条件として「””(ダブルクォート)」が偶数であり(1データ要素)、且つ「、(カンマ)」をであると判別した場合は、Call PutCell(i, j, strCell, lngQuote)でPutCellプロシージャへ引数を渡します。
引数は、読込先の行と列の変数「i」、「j」とダブルクォートで囲まれた1要素が格納された変数strCell、ダブルクォートをカウントするための変数lngQuoteを引数として渡します。
偶数ダブルクォート後のカンマ判別以外
strCell = strCell & Mid(strRec, k, 1)
「条件:偶数ダブルクォート後のカンマを判別」以外は、変数strCellに1文字ずつ格納されます。
PutCellプロシージャ
1データ要素と判別された変数strCellは、PutCellプロシージャに渡されます。
Sub PutCell(ByRef i As Long, ByRef j As Long, ByRef strCell As String, ByRef lngQuote As Long)
j = j + 1
'「""」を「"」で置換
strCell = Replace(strCell, """""", """")
'前後の「"」を削除
If strCell = """" Then
strCell = ""
ElseIf Left(strCell, 1) = """" And Right(strCell, 1) = """" Then
strCell = Mid(strCell, 2, Len(strCell) - 2)
End If
Cells(i, j) = strCell
strCell = ""
lngQuote = 0
End Sub
「””」を「”」で置換します。
strCell = Replace(strCell, """""", """")
条件分岐にて、データ要素が空欄の場合は、「””」で空欄表示にします。
If strCell = """" Then
strCell = ""
それ以外の場合は、前後の「”(ダブルクォート)」を削除します。
ElseIf Left(strCell, 1) = “””” And Right(strCell, 1) = “””” Then strCell = Mid(strCell, 2, Len(strCell) – 2) End Ifそして、変数strCellのセルへの代入、変数strCellを空にして、ダブルクォートをカウントするための変数lngQuoteをゼロにします。
Cells(i, j) = strCell
strCell = ""
lngQuote = 0
読み込み結果
まとめ
読み込みたいCSVデータ要素に「、(カンマ)」や「”(ダブルクォート)」がある場合の対処方法について、ウェブサイト「エクセルの神髄」に掲載されていたサンプルコードを詳細に解説しました。
是非参考にしてみてください。
コメント