拆分分隔符必须设置为“,”,但返回的值可能包含逗号
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
【讨论】:
以上是关于拆分分隔符必须设置为“,”,但返回的值可能包含逗号的主要内容,如果未能解决你的问题,请参考以下文章