拆分分隔符必须设置为“,”,但返回的值可能包含逗号

Posted

技术标签:

【中文标题】拆分分隔符必须设置为“,”,但返回的值可能包含逗号【英文标题】:Split delimiter has to be set to "," but value returned may include a comma 【发布时间】:2017-04-22 01:40:06 【问题描述】:

我正在尝试运行一个程序,该程序应该从电子表格中提取数据,将数据拆分为多个块,然后根据它的“值”变体将其导入我的表中。拉入的数据格式如下所示:

"HL","Hecla Mining Company Mining Stock","NSM",12.52,8.69,14.07,6.18

分割行、定义值、赋值给列的代码目前编写如下:

Dim Resp As String: Resp = Http.ResponseText
    Dim Lines As Variant: Lines = Split(Resp, vbLf)
    Dim sLine As String
    Dim Values As Variant
    For i = 0 To UBound(Lines)
        sLine = Lines(i)
        If InStr(sLine, ",") > 0 Then
            Values = Split(sLine, ",")
            W.Cells(i + 2, 2).Value = Replace(Values(1), Chr(34), "")
            W.Cells(i + 2, 5).Value = Replace(Values(2), Chr(34), "")
            W.Cells(i + 2, 6).Value = Values(3)
            W.Cells(i + 2, 7).Value = Values(4)
            W.Cells(i + 2, 8).Value = Values(5)
            W.Cells(i + 2, 9).Value = Values(6)
            W.Cells(i + 2, 10).Value = Values(7)
            W.Cells(i + 2, 11).Value = Values(8)
            W.Cells(i + 2, 13).Value = Values(9)
        End If

问题出现在某些行返回的名称中包含逗号,例如:

"CDE","Coeur Mining, Inc.","NSM",7.59,16.25,9.52,7.01

这导致 Values(2) = "Coeur Mining" 和 Value(3) = "Inc."而不是 Values(2) = "Coeur Mining, Inc."和值(3)=“NSM”

我已尝试将代码更新为以下内容:

Dim Resp As String: Resp = Http.ResponseText
    Dim Lines As Variant: Lines = Split(Resp, vbLf)
    Dim sLine As String
    Dim Values As Variant
    For i = 0 To UBound(Lines)
        sLine = Lines(i)
        If InStr(sLine, ",") > 0 Then
           ***If InStr(sLine, ",Inc.") Then
            sLine = Replace(sLine, ",inc.", "")
        End If***
            Values = Split(sLine, ",")
            W.Cells(i + 2, 2).Value = Replace(Values(1), Chr(34), "")
            W.Cells(i + 2, 5).Value = Replace(Values(2), Chr(34), "")
            W.Cells(i + 2, 6).Value = Values(3)
            W.Cells(i + 2, 7).Value = Values(4)
            W.Cells(i + 2, 8).Value = Values(5)
            W.Cells(i + 2, 9).Value = Values(6)
            W.Cells(i + 2, 10).Value = Values(7)
            W.Cells(i + 2, 11).Value = Values(8)
            W.Cells(i + 2, 13).Value = Values(9)
        End If

但是,即使使用嵌套的 If 语句查找“,Inc”,它似乎也无法正常工作。在 sLine 字符串中。

是否存在我没​​有得到的格式问题?我也尝试使用正则表达式函数,但我对 excel/VBA 非常陌生,无法弄清楚如何正确格式化它。

建议的正则表达式代码如下:

Public Function splitLine(line As String) As String()

Dim regex As Object     
Set regex = CreateObject("vbscript.regexp")
regex.IgnoreCase = True
regex.Global = True
regex.Pattern = ",(?=([^" & Chr(34) & "]" & Chr(34) & "[^" & Chr(34) & "]" & Chr(34) & ")(?![^" & Chr(34) & "]" & Chr(34) & "))"
splitLine = Split(regex.Replace(line, ";"), ";") End Function
Values = splitLine(sLine)

任何帮助将不胜感激,可根据要求提供更多信息或实际 excel 文件的副本。

【问题讨论】:

我以为您正在阅读 CSV 文件,但是,一旦我真正阅读了这个问题,我发现您正在从 http 获取信息。尝试将原始字符串放入某处的单元格中,然后使用 Text to Columns 指定文本以逗号分隔,文本分隔符为 "。然后处理 Excel 生成的单元格,这将正确地使文本字符串中的逗号保持不变。 在您给出的示例“Coeur Mining, Inc.”中,逗号和 Inc. 之间有一个空格。您的 If 语句省略了空格。这可能会使您的代码更好地工作,但这不是一个非常通用的解决方案。如果您有一家名为“Dewy, Cheatem, and Howe”的律师事务所怎么办?您需要一种方法来检测位于引号对之间的逗号。 谢谢 Rich,我相信您可能是对的,因为它可能是缺少空间。我刚刚查看了股票的网页,标题中似乎有一个空格。我将尝试更新代码行,看看是否有效果。根据我所看到的 50 个符号,我在名称中唯一带有“,”的名称是注册公司。不过我同意,最好找到一个更广泛的解决方案,专门在引号中查找逗号。不幸的是,我已经尝试了几个小时,但还没有找到可行的解决方案 YowE3K - 我也尝试为此使用文本到列功能,但无法让程序使用它,我不确定我是否没有正确的行代码的位置或是否存在其他问题。不幸的是,正如原始帖子中所述,除了非常基本的 excel 函数之外,我对任何东西都很陌生,并且最近(2 周前)开始尝试将 VBA 合并到我的工作表中。我通常是一个快速学习者,但是我对这个话题仍然很陌生,以至于我不知道我使用的大多数功能是如何工作的,即使我知道如何使用它们。 ***.com/questions/6780765/… 【参考方案1】:

看起来您将不得不通过一个模仿 Text-to-Columns 的“引用文本”参数的“帮助器”函数来处理字符串。

虽然不优雅(并且可能很容易改进),但它适用于您的示例。

Option Explicit

Sub test()
    Dim str As String, var As Variant

    str = """CDE"",""Coeur Mining, Inc."",""NSM"",7.59,16.25,9.52,7.01"
    With Worksheets("Sheet1")
        Debug.Print str
        str = cleanQuotedCommas(str)
        var = Split(str, Chr(44))
        With .Cells(2, "B").Resize(1, UBound(var) + 1)
            .Value = var
            .Replace what:=ChrW(8203), replacement:=Chr(44), lookat:=xlPart
            .Replace what:=Chr(34), replacement:=vbNullString, lookat:=xlPart
            .Value = .Value2
        End With
    End With
End Sub

Function cleanQuotedCommas(str As String) As String
    Dim i As Long, j As Long, k As Long
    i = InStr(1, str, Chr(34), vbBinaryCompare)
    Do While CBool(i)
        j = InStr(i + 1, str, Chr(34), vbBinaryCompare)
        k = InStr(i + 1, str, Chr(44), vbBinaryCompare)
        If k > i And k < j Then
            str = Replace(str, Chr(44), ChrW(8203), i, 1, vbBinaryCompare)
        End If
        Debug.Print str
        i = InStr(j + 1, str, Chr(34), vbBinaryCompare)
    Loop
    cleanQuotedCommas = str
End Function

注意双精度数的右对齐和文本的左对齐。

【讨论】:

【参考方案2】:

这是一个基于正则表达式的SplitLine 函数,它将返回一个字符串数组。它将从包含它的条目中排除周围的引号,并且不会在“包含”逗号上拆分:

Option Explicit

Public Function splitLine(line As String) As String()
  Dim regex As Object, matchcol As Object, match As Object
  Dim I As Long, S() As String

Set regex = CreateObject("vbscript.regexp")
With regex
    .Global = True
    .Pattern = """([^""\r\n]*)""|([^,\r\n]+)"
    If .test(line) = True Then
        Set matchcol = .Execute(line)
        ReDim S(0 To matchcol.Count - 1)
        I = 0

        'matches surrounded by quotes will be in 0
        'matches without quotes will be in 1
        For Each match In matchcol
            With match
                S(I) = .submatches(0) & .submatches(1)
            End With
            I = I + 1
        Next match
    End If
End With
splitLine = S
End Function

【讨论】:

以上是关于拆分分隔符必须设置为“,”,但返回的值可能包含逗号的主要内容,如果未能解决你的问题,请参考以下文章

如何将逗号分隔的值拆分为列

在逗号上拆分字符串但忽略双引号内的逗号?

拆分包含逗号分隔条目的字符串流

将一列拆分为多行

sql 将逗号分隔的字符串拆分为值列表(返回游标)

如何根据一个字段是不是包含oracle sql中的逗号分隔字符串将单行拆分为多行?