Performance VBA性能问题-迭代

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

我正在读一个有5000个字符串的文本文件。每个字符串包含日期+时间,然后是3个值。日期和时间之间的分隔符是空格,然后这三个值以制表符分隔。第一个字符串(strData(0))只是一个头,所以我不需要它。最后一个字符串只是一个简单的“结束”

下面的代码可以工作,但导入工作表需要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)
应该可以。我很高兴这有帮助。