VBA 读取字符串中带分隔符的 CSV

VBA read CSV with delimiter in string

我正在尝试读取 .csv 以在 .accdb 中使用它

文件有;作为分隔符,“”作为字符串限定符。 年轻天真,我只是在分隔符处分割文件:

Set oFSO = New FileSystemObject
Set oStream = oFSO.OpenTextFile(sFilePath, ForReading)
Do Until oStream.AtEndOfStream
    sLine = oStream.ReadLine
        sArray = Split(sLine, ";")
        ....

现在我得到一行内容:

"String";"Str;ing";0;0;0;"String"

所以我在其中一个字符串中有分隔符,这使得上面的代码不起作用。有什么解决办法吗?

编辑:

我发现有人有类似的问题,只是用逗号作为分隔符。他们使用正则表达式解决了这个问题。 问题:我绝对不擅长正则表达式。在示例中使用了这个表达式和代码:

Function regLine(sLine As String) As String
Dim oRegEx As RegExp
    Set oRegEx = New RegExp
    oRegEx.IgnoreCase = True
    oRegEx.Global = True

    ' Pattern: ",(?=([^"]*"[^"]*")*(?![^"]*"))"
    oRegEx.Pattern = ",(?=([^" & Chr(34) & "]*" & Chr(34) & "[^" & Chr(34) & "]*" & Chr(34) & ")*(?![^" & Chr(34) & "]*" & Chr(34) & "))"

    regLine = oRegEx.Replace(sLine, ";")
End Function

所以我不是很理解这个表达。我的第一个想法是用分号代替逗号,但没有用。

我的第一个问题是:有没有“;”在字符串值中是一个有效的字符串?如果是这样,除了手动验证数据外,我看不到任何其他方法。

如果不是,输入文件有多大?如果它不是太大(对于 "too" 的各种定义 :-) )那么只需手动扫描它以查找错误。

如果它非常大,我会简单地编写一个预处理程序来读取字符串值,然后删除任何“;”在它发生的地方。这样的程序只有十几行。然后运行将干净的文件导入Access。

Option Explicit 

Dim line 
    line ="""String"";""Str;ing"";0;0;0;""String"""
    WScript.Echo line

Dim aFields
    With New RegExp
        .Pattern = "(""[^""]*"")?;"
        .Global = True 
        aFields = Split(.Replace(line, ""&Chr(0)),Chr(0))
    End With

Dim field
    For Each field In aFields
        WScript.Echo field
    Next 

代码是 .vbs,但展示了如何使用正则表达式将未包含在引号中的分号替换为空字符,并使用空字符将行拆分为其字段。

我现在通过编写一个循环解决了这个问题,如果它在字符串中则删除分隔符。

Function fixLine(sLine As String)
Dim i As Long
Dim bInString As Boolean

bInString = False
fixLine = ""
For i = 1 To Len(sLine)
    If Mid(sLine, i, 1) = Chr(34) Then
         If bInString Then
            bInString = False
        Else
            bInString = True
        End If
     End If
    If bInString And Mid(sLine, i, 1) = ";" Then
    Else
        fixLine = fixLine & Mid(sLine, i, 1)
    End If
Next
End Function

感觉有点快和肮脏,我不确定性能但它有效。

编辑: 我还使用了我发现的上述示例。它取代了字符串外一行中的定界符。所以我用 Chr(0) 替换了分隔符,我知道它不会出现在一行中,然后在新的分隔符处拆分。

Function regLine(sLine As String) As String()
Dim oRegEx As RegExp
Dim sLine2() As String
    Set oRegEx = New RegExp
    oRegEx.Global = True

    'Pattern: ";(?=([^"]*"[^"]*")*(?![^"]*"))"
    oRegEx.Pattern = ";(?=([^" & Chr(34) & "]*" & Chr(34) & "[^" & Chr(34) & "]*" & Chr(34) & ")*(?![^" & Chr(34) & "]*" & Chr(34) & "))"

    sLine2 = oRegEx.Replace(sLine, Chr(0))
    regLine = Split(sLine2, Chr(0))
End Function