Performance VBA性能问题-迭代
我正在读一个有5000个字符串的文本文件。每个字符串包含日期+时间,然后是3个值。日期和时间之间的分隔符是空格,然后这三个值以制表符分隔。第一个字符串(strData(0))只是一个头,所以我不需要它。最后一个字符串只是一个简单的“结束” 下面的代码可以工作,但导入工作表需要1分钟!我可以做些什么来改进这一点,以及什么需要时间?Performance VBA性能问题-迭代,performance,vba,excel,Performance,Vba,Excel,我正在读一个有5000个字符串的文本文件。每个字符串包含日期+时间,然后是3个值。日期和时间之间的分隔符是空格,然后这三个值以制表符分隔。第一个字符串(strData(0))只是一个头,所以我不需要它。最后一个字符串只是一个简单的“结束” 下面的代码可以工作,但导入工作表需要1分钟!我可以做些什么来改进这一点,以及什么需要时间? 屏幕更新已关闭 'open the file and read the contents Open strPpName For Binary As #1
屏幕更新已关闭
'open the file and read the contents
Open strPpName For Binary As #1
MyData = Space$(LOF(1))
Get #1, , MyData
Close #1
strData() = Split(MyData, vbCrLf)
'split the data and write into the correct columns
Row = 3
i = 0
For Each wrd In strData()
If i > 0 Then 'first string is only header
tmpData() = Split(wrd, vbTab)
DateString() = Split(tmpData(0), " ")
If DateString(0) <> "End" Then
ActiveSheet.Cells(Row, 5) = DateString(0) 'Date
ActiveSheet.Cells(Row, 6) = DateString(1) 'Time
ActiveSheet.Cells(Row, 2) = tmpData(1) 'Value1
ActiveSheet.Cells(Row, 3) = tmpData(2) 'Value2
ActiveSheet.Cells(Row, 4) = tmpData(3) 'Value3
Row = Row + 1
Else
GoTo Done
End If
End If
i = i + 1
Next wrd
Done:
”打开文件并读取内容
打开二进制文件的strPpName作为#1
MyData=空间$(LOF(1))
获取#1,MyData
关闭#1
strData()=拆分(MyData,vbCrLf)
'拆分数据并写入正确的列
行=3
i=0
对于strData()中的每个wrd
如果i>0,则“第一个字符串”仅为标题
tmpData()=拆分(wrd,vbTab)
DateString()=拆分(tmpData(0),“”)
如果日期字符串(0)“结束”,则
ActiveSheet.Cells(第5行)=日期字符串(0)的日期
单元格(第6行)=日期字符串(1)的时间
ActiveSheet.Cells(第2行)=tmpData(1)的值1
ActiveSheet.Cells(第3行)=tmpData(2)的值2
ActiveSheet.Cells(第4行)=tmpData(3)的值3
行=行+1
其他的
好了
如果结束
如果结束
i=i+1
下一个世界
完成:
Excel可以通过从文本获取数据来处理多种类型的分隔符(制表符和空格)。这是我从宏记录器得到的
Sub Macro1()
'
' Macro1 Macro
'
'
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;C:\Users\jeanno\Documents\random.txt", Destination:=Range("$A$1"))
.CommandType = 0
.Name = "random_1"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = True
.TextFileColumnDataTypes = Array(1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub
这将比VBA中的字符串操作快得多。我认为问题在于您可能正在读取二进制文件。尝试以下方法。我运行了5100多条记录,它在不到一秒钟的时间内解析了它
Public Sub ReadFileToExcel(filePath As String, rowNum As Long)
'******************************************************************************
' Opens a large TXT File, reads the data until EOF on the Source,
' adds the data in a EXCEL File, based on the row number.
' Arguments:
' ``````````
' 1. The Source File Path - "C:\Users\SO\FileName.Txt" (or) D:\Data.txt
' 2. The Row number you wish to start adding data.
'*******************************************************************************
Dim strIn As String, lineCtr As Long
Dim tmpData, DateString
'Open the SOURCE file for Read.
Open filePath For Input As #1
'Loop the SOURCE till the last line.
Do While Not EOF(1)
'Read one line at a time.
Line Input #1, strIn
lineCtr = lineCtr + 1
If lineCtr <> 1 Then
If InStr(strIn, "END") = 0 Then
tmpData = Split(strIn, vbTab)
DateString = Split(tmpData(0), " ")
ActiveSheet.Cells(rowNum, 5) = DateString(0) 'Date
ActiveSheet.Cells(rowNum, 6) = DateString(1) 'Time
ActiveSheet.Cells(rowNum, 2) = tmpData(1) 'Value1
ActiveSheet.Cells(rowNum, 3) = tmpData(2) 'Value2
ActiveSheet.Cells(rowNum, 4) = tmpData(3) 'Value3
rowNum = rowNum + 1
End If
End If
Loop
Debug.Print "Total number of records - " & lineCtr 'Print the last line
'Close the files.
Close #1
End Sub
Public Sub ReadFileToExcel(filePath为字符串,rowNum为长)
'******************************************************************************
'打开一个大的TXT文件,读取数据直到源上出现EOF,
'根据行号将数据添加到EXCEL文件中。
"论据:
' ``````````
' 1. 源文件路径-“C:\Users\SO\FileName.Txt”(或)D:\Data.Txt
' 2. 要开始添加数据的行号。
'*******************************************************************************
尺寸条纹为字符串,线条中心为长
Dim tmpData,日期字符串
'打开源文件进行读取。
将输入文件路径打开为#1
'循环源,直到最后一行。
不执行时执行EOF(1)
“一次读一行。
行输入#1,strIn
lineCtr=lineCtr+1
如果lineCtr为1,则
如果InStr(strIn,“END”)=0,则
tmpData=拆分(strIn,vbTab)
DateString=Split(tmpData(0),“”)
单元格(rowNum,5)=日期字符串(0)'Date
单元格(rowNum,6)=日期字符串(1)的时间
ActiveSheet.Cells(rowNum,2)=tmpData(1)'Value1
ActiveSheet.Cells(rowNum,3)=tmpData(2)'Value2
ActiveSheet.Cells(rowNum,4)=tmpData(3)'Value3
rowNum=rowNum+1
如果结束
如果结束
环
调试。打印“记录总数-”&lineCtr“打印最后一行
'关闭文件。
关闭#1
端接头
尝试以下方法:
Dim Values(), N, I
N = 100
ReDim Values(6, N)
...
Do While Not EOF(1)
I = I + 1
If I > N Then
N = N + 100
ReDim Preserve Values(6, N)
End If
Values(0, I) = ...
...
Loop
Range("A1:F" & i) = Values
循环将使用VBA中比使用工作表快得多的数组。您可以采用另一种方法,在Excel中复制整个文本文件,方法与手动(复制/粘贴)但以编程方式相同,然后删除Excel中的第一行和最后一行。我不确定是否完全理解。我如何以编程方式复制整个文本文件?谢谢Paul,但是对于这个解决方案,我有相同的时间安排!顺便说一句,末端检测功能不正常,但我知道如何修复。问题仍然是性能。我有一台相当好的机器,所以不是那样。谢谢!这很快!.CommandType=0不被接受,但我去掉了它,它成功了!然而,我现在有一个标题行,它有点偏离(因为我将日期和时间一分为二)。我能忍受的尽头的尽头。我想我可以将文件复制到一个工作区/工作表,然后从该工作区/工作表复制到我想要的工作表,不包括标题行和结束行。还有其他想法吗?或者我可以在数据导入后重写标题行,这可能是最简单的方法。。。。谢谢Jeanno,我会节省几个小时的等待时间!斯泰西,我喜欢这个样子!能够管理内存中的所有操作,然后一次性将其分配给工作表!我也会尝试一下。我必须添加一个值数组的转置,但这很有魅力。谢谢stenci,我想我会使用这个解决方案。
Application.Transpose(Values)
应该可以。我很高兴这有帮助。