【问题标题】:Excel VBA process csv string into arrayExcel VBA将csv字符串处理成数组
【发布时间】:2012-10-03 19:00:30
【问题描述】:

我有通过 http 下载获得的 csv 字符串 (utf-8)。

根据情况,字符串中的数据可能包含不同数量的列,但每次处理字符串时,它将包含相同数量的列并且是连续的。 (数据将是偶数)。

字符串可以包含任意数量的行。

第一行总是标题。

字符串字段将用双引号括起来,并且可以包含逗号、引号和换行符

字符串中的引号和双引号通过加倍“”和“'”进行转义

换句话说,这是一种格式良好的 csv 格式。 Excel 通过它的标准文件打开机制对这些数据进行格式化没有问题。

但是我想避免保存到文件然后打开 csv,因为在某些情况下我需要处理输出,甚至需要与工作表上的现有数据合并。

(通过编辑添加以下信息) Excel 应用程序将分发到各个目的地,如果可能的话,我想避免潜在的权限问题,似乎什么都不写到磁盘是一个好方法

我在想类似下面的伪:

rows = split(csvString, vbCrLf)  'wont work due to newlines inside string fields?

FOREACH rows as row
    fields = split(row, ',')     'wont work due to commas in string fields?
ENDFOR

显然不能处理包含特殊标记的字段。

解析这些数据的可靠方法是什么?

谢谢

编辑 13/10/2012 数据样本

csv 会出现在记事本中(注意不是所有的换行符都是 \r\n 有些可能是 \n)

LanguageID,AssetID,String,TypeID,Gender
3,50820,"A string of natural language",3,0
3,50819,"Complex text, with comma, "", '' and new line
all being valid",3,0
3,50818,"Some more language",3,0

Excel 2010 中的相同 csv - 从 shell 打开(双击 - 没有额外选项)

【问题讨论】:

  • 您需要逐个字符地遍历字符串并“手动”解析它。

标签: excel vba csv split


【解决方案1】:

我能想到三种可能:

  1. 使用正则表达式处理文本。在 SO 上和通过 google 有很多例子可以用来分隔这样的字符串。
  2. 使用 Excel 的强大功能:将文本保存到临时文件中,打开临时表并从表中读取数据。完成后删除文件和工作表。
  3. 使用 ADO 查询数据。将字符串保存到临时文件并对其运行查询以返回所需的字段。

为了提供更具体的建议,我需要输入数据和预期输出的样本

【讨论】:

  • 我喜欢临时文件选项的简单性,但是 Excel 应用程序将分发到各个目标,我希望避免可能的潜在权限问题,似乎不向磁盘写入任何内容是一个好方法去做。抱歉,我应该在我的问题中澄清这一点(并且会这样做)。我会看看我是否能找到一个可靠的正则表达式,谢谢你的建议。
  • 我星期六的大部分时间都在玩正则表达式,但没有成功,我在使用 vbScript 正则表达式引擎时遇到了一些限制问题,并且发现了许多几乎可以工作的示例。所以最后你是对的,让Excel做它擅长的事情。临时文件(用户 appdata 临时文件夹)和 QueryTable 为赢。感谢您的宝贵时间。
【解决方案2】:

如果您不介意将数据放入工作簿:您可以使用空白工作表,将数据添加到 1 列中,然后致电 TextToColumns。然后,如果您想将数据作为数组取回,只需从工作表的 UsedRange 加载它即可。

'Dim myArray 'Uncomment line if storing data to array.
'Assumes cvsString is already defined
'Used Temp as sheet for processing
With Sheets("Temp")
    .Cells.Delete
    .Cells(1, 1) = cvsString
    .Cells(1, 1).TextToColumns Destination:=Cells(1, 1), DataType:=xlDelimited, _
        TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
        Semicolon:=False, Comma:=True, Space:=False, Other:=False
    'myArray = .UsedRange 'Uncomment line if storing data to array
End With

【讨论】:

  • 这是否处理The string could contain any number of rows 即在字符串中由CrLf 字符分隔(我认为这就是OP 的意思)?
  • @chrisneilsen 你是对的,我可以在同一个字符串中由 crLf 分隔 1000 行,并且在字符串字段或每一行中另外将 crLf 作为有效(非行中断)序列。跨度>
  • @DanielCook 这很有趣,当然是部分解决方案,我想我需要像 TextToRows 这样的东西开始,或者我可以用 Transpose 做一些事情。我要玩这个谢谢。
  • 这还是有潜力的。首先对 vbCrLf 上的列做一个文本。将结果转置为一列,然后按照丹尼尔斯的回答对列进行文本处理
  • 假设 op 使用 xl2007+ 并且行数
猜你喜欢
  • 1970-01-01
  • 2010-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-28
  • 2017-12-23
相关资源
最近更新 更多