【问题标题】: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 合并到我的工作表中。我通常是一个快速学习者,但是我对这个话题仍然很陌生,以至于我不知道我使用的大多数功能是如何工作的,即使我知道如何使用它们。

标签: excel string vba split


【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-07
      • 2015-09-23
      • 2012-11-12
      • 2010-10-23
      • 1970-01-01
      • 2015-03-13
      • 1970-01-01
      相关资源
      最近更新 更多