想要Excel中的VBA读取非常大的CSV并创buildCSV的一小部分的输出文件

我有一个120万条文本logging的csv文件。 字母数字字段用引号括起来,date/时间或数字字段不是。

例如“Fred”,“Smith”,01/07 / 1967,2,“7,High Street”,“Anytown”,“Anycounty”,“LS1 7AA”

我想要做的是在Excel中编写一些VBA(或多或less是我可以使用的唯一合适的工具),通过logging来读取CSVlogging,执行检查(就像在最后一个字段上发生的那样,邮政编码),然后将1.2mlogging的一小部分输出到新的输出文件。

我知道如何打开这两个文件,读取logging,做我需要做的数据并写出来(我只是输出inputlogging的前缀表示exceptiontypes)

我不知道的是如何正确parsingVBA中的CSV。 我不能做一个简单的文本扫描和search逗号,因为文本有时有逗号(因此为什么文本字段是文本分隔)

有没有一个非常棒的命令能让我快速从logging中的第n个字段获取数据?

我想要的是s_work =字段(s_input_record,5)其中5是CSV中的字段编号….

非常感谢,C

下面的代码应该做的伎俩。 我没有在我面前的Excel,所以我没有testing它,但概念是健全的。

如果结果太慢,我们可以想办法提高效率。

Sub SelectSomeRecords() Dim testLine As String Open inputFileName For Input As #1 Open outputFileName For Output As #2 While Not EOF(1) Line Input #1, testLine If RecordIsInteresting(testLine) Then Print #2, testLine End If Wend Close #1 Close #2 End Sub Function RecordIsInteresting(recordLine As String) As Boolean Dim lineItems(1 to 8) As String GetRecordItems(lineItems(), recordLine) ''// do your custom checking here: RecordIsInteresting = lineItems(8) = "LS1 7AA" End Function Sub GetRecordItems(items() As String, recordLine as String) Dim finishString as Boolean Dim itemString as String Dim itemIndex as Integer Dim charIndex as Long Dim inQuote as Boolean Dim testChar as String inQuote = False charIndex = 1 itemIndex = 1 itemString = "" finishString = False While charIndex <= Len(recordLine) testChar = Mid$(recordLine, charIndex, 1) finishString = False If inQuote Then If testChar = Chr$(34) Then inQuote = False finishString = True charIndex = charIndex + 1 ''// ignore the next comma Else itemString = itemString + testChar End If Else If testChar = Chr$(34) Then inQuote = True ElseIf testChar = "," Then finishString = True Else itemString = itemString + testChar End If End If If finishString Then items(itemIndex) = itemString itemString = "" itemIndex = itemIndex + 1 End If charIndex = charIndex + 1 Wend End Sub 

如何VBScript,虽然这也可以在Excel中工作:

 Set cn = CreateObject("ADODB.Connection") 'Note HDR=Yes, that is, first row contains field names ' 'and FMT delimted, ie CSV ' strCon="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\Docs\;" _ & "Extended Properties=""text;HDR=Yes;FMT=Delimited"";" cn.open strcon 'You would not need delimiters ('') if last field is numeric: ' strSQL="SELECT FieldName1, FieldName2 INTO New.csv FROM Old.csv " _ & " WHERE LastFieldName='SomeTextValue'" 'Creates new csv file cn.Execute strSQL 

这不会直接回答你的问题,但grep (或其中一个Windows的等价物)真的会为此发光,例如,

 grep -e <regex_filter> foo.csv > bar.csv 

我使用以上给出的代码的以下派生成功地从Excel中的VBA打开任意csv文件。

选项显式
公共cn作为连接
Public Sub DoIt()
Dim strcon As String
昏暗的strsql作为string
Dim rs As Recordset

Set cn = CreateObject(“ADODB.Connection”)

strcon =“Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\ bin \ HomePlanet \;” _
&“Extended Properties =”“text; HDR = Yes; FMT = Delimited”“;”

打开strcon

strsql =“SELECT * FROM astuname.csv”
设置rs =新的ADODB.Recordset
rs.Open strsql,cn
DoEvents'暂停在这里检查对象和属性rs.Close
结束小组

rs(logging集)有一个字段集合,具有Count属性。 每个字段作为一个Type属性。

您可以通过序列号引用字段…

Debug.Print rs.Fields(rs.Fields.Count – 1).Type

这足够吗?

如果没有,发布input文件的前几行,我将采取其余的方式。

看看Excel帮助中的Input #语句

示例用法是:

 Input #fnInput, s_Forename, s_Surname, dt_DOB, i_Something, s_Street, s_Town, s_County, s_Postcode 

然后使用Write #语句再次写入匹配的logging

唯一的问题可能是输出中的date格式最终会变成#1967-07-01#,但是与01/07/1967不同的是,这个格式是明确的,这将代表7月1日在英国和1月7日在美国。 如果你需要保留date的格式,然后把它写成一个string:

 s_DOB = Format(dt_DOB, "dd/mm/yyyy") 

任何你可以在Excel中使用vba进行一次一行的操作,你可以使用vba进行访问; 加上更多,因为它是一个数据库而不是电子表格。 访问不可用吗?

处理逻辑表,logging和字段比逻辑工作表,行和列要容易得多。

对于input,为什么“/ Data / Import External Data / Text / csv”不起作用? input是不是真正的便携式CSV?

我build议看看正则expression式库(你应该在“工具…参考”中看到它为“Microsoft VBScript Regular Expressions 5.5”或类似的东西。

在这个位置有Reg Exp和一个相当全面的字符样本: http : //www.xbeat.net/vbspeed/c_ParseCSV.php 。 请注意,正则expression式版本更短!

玩的开心…