【VBA】CSV読み込み。カンマを含む文字データをsplitで分割する。

VBA

CSVの文字データにカンマが含まれる場合

1,"カンマ,を含む文字"

これをVBAで読み込もうとする場合、Splitで単純に分割するとこんな感じの分割になってしまう。

1列目:1
2列目:"カンマ
3列目:を含む文字"

これをSplitで何とかやろうとする場合のサンプル。

Sub main()

    Dim InFilePath As String '入力ファイルパス
    Dim i, j As Integer
    Dim str As String
    Dim splitString As Variant
    
    InFilePath = ActiveWorkbook.Path & "\testdata.csv"
    Open InFilePath For Input As #1
    
    'ファイル読み込み
    Do While Not EOF(1)
        Line Input #1, str
        splitString = csvSplit(str)    
        For j = 0 To UBound(splitString) - 1
            Debug.Print i + 1 & "行目 " & j + 1 & "列目 : " & splitString(j)
        Next j    
        i = i + 1
    Loop
    Close #1
End Sub

'カンマ区切り分割処理
Function csvSplit(ByVal str As String) As Variant

    Dim i As Integer
    Dim arrayCnt As Integer
    Dim s As String '1文字分
    Dim data As String '1データ分
    Dim doubleQuoteFlag As Boolean 'True=ダブルクォートの中、False=ダブルクォートの外
    Dim retArray() As String

    For i = 1 To Len(str)
        '1文字ずつ判定
        s = Mid(str, i, 1)
        If s = """" Then
            'ダブルクォートの場合、中⇔外を反転
            doubleQuoteFlag = Not doubleQuoteFlag    
        ElseIf s = "," And doubleQuoteFlag Then
            'ダブルクォートの中のカンマはデータとして扱う
            data = data & s
        ElseIf s = "," And Not doubleQuoteFlag Then
            'ダブルクォートの外のカンマ発見で区切り
            arrayCnt = arrayCnt + 1
            ReDim Preserve retArray(arrayCnt)
            retArray(arrayCnt - 1) = data
            data = ""
        Else
            data = data & s
        End If
    Next i
    
    If Not data = "" Then
        '最終列のデータを配列に格納
        arrayCnt = arrayCnt + 1
        ReDim Preserve retArray(arrayCnt)
        retArray(arrayCnt - 1) = data
    End If
    
    csvSplit = retArray
End Function
testdata.csv
1,"テスト1行目"
2,"テスト,2行目"
出力結果
1行目 1列目 : 1
1行目 2列目 : テスト1行目
2行目 1列目 : 2
2行目 2列目 : テスト,2行目

ちなみに上記サンプルコードは、下記に書き換えることもできる(書き方が適当なので、少し汎用性が無くなるが)。

Sub main()

    Dim InFilePath As String '入力ファイルパス
    Dim i As Integer
    Dim col1, col2 As String
    
    'ファイル選択ダイアログ
    InFilePath = ActiveWorkbook.Path & "\testdata.csv"
    
    Open InFilePath For Input As #1
    
    '入力ファイル読み込み→出力ファイル書き込み
    Do While Not EOF(1)
        Input #1, col1, col2
        Debug.Print i + 1 & "行目 " & "1列目 : " & col1
        Debug.Print i + 1 & "行目 " & "2列目 : " & col2
        i = i + 1
    Loop
    
    Close #1
End Sub

Line Inputで行を抜き出さなくてもInputで値を抜き出せば、文字データに含まれるカンマもちゃんと文字として扱ってくれる。タブ区切りもこれでイケる。

コメント

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