【问题标题】:How to improve the speed of loop a file如何提高循环文件的速度
【发布时间】:2014-01-20 03:20:47
【问题描述】:

下面是我的代码,虽然不完美,但可以运行,循环一个文本文件需要 30 多分钟。如何使用其他代码或方法提高循环文件的速度。请帮忙。

Open "C:\Users\steven.EOPESTATE\Desktop\Sharp Sales\TRMSAVE01.txt" For Input As #1

            Do Until EOF(1)
                Dim ITEMSQL As String
                Line Input #1, varLine
                testvarline = Split(varLine, ",")

                If testvarline(0) = "$ITEM" Then
                'Debug.Print testvarline(0), testvarline(1), testvarline(2), testvarline(3), testvarline(4), testvarline(5), testvarline(6), testvarline(7), testvarline(8), testvarline(9)
                testvarline(0) = Replace(testvarline(0), "$", " ")
                testvarline(7) = Replace(testvarline(7), ",,", " ")

                ITEMSQL = "Insert into SalesItem([ITEMID], [2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12]) Values (" & Chr(34) & "" & (testvarline(0)) & "" & Chr(34) & "," & (testvarline(1)) & "," & (testvarline(2)) & "," & (testvarline(3)) & "," & (testvarline(4)) & "," & (testvarline(5)) & "," & Chr(34) & "" & (testvarline(6)) & "" & Chr(34) & "," & (testvarline(9)) & "," & (testvarline(10)) & "," & (testvarline(11)) & "," & (testvarline(12)) & "," & (testvarline(14)) & ")"

                Debug.Print ITEMSQL
                DoCmd.RunSQL ITEMSQL
                DoCmd.SetWarnings False
                DoCmd.Echo False




                End If

            Loop

    Close #1

【问题讨论】:

  • 循环和读取文件真的很慢吗?我怀疑 SQL 插入是您花费最多时间的地方。
  • 为什么不直接将文件导入新表,然后进行插入查询?
  • 我认为读取文件没有任何问题,但是将每条记录插入数据库需要时间。可以使用 DoCmd.TransferText 命令导入。
  • 您可以使用来自this page 的 MicroTimer 函数来测量循环不同部分所花费的时间。这将允许您确定需要优化的部分:SQL 或文件 IO。尽可能删除 Debug.Print 语句,这也有助于减慢速度。
  • 嗯,home文件里有多少行?

标签: vba loops


【解决方案1】:

您可以在 PC 上执行的最慢的操作之一是从硬盘驱动器加载。 CPU 和 RAM 比硬盘快得多(请参阅this SO question),因此它们最终会等待硬盘读取完成。因此,一次将整个文件读入内存将显着加快您的程序。

与其再次使用Split函数拆分行进行处理,我建议使用Mid函数自己解析它们,这实际上避免了正常字符串处理的很多开销,因为它不会创建临时副本内存中的子字符串。这是未经测试的示例代码:

Dim strFileText As String
Dim lngCurrIndex As Long
Dim lngEndOfLine As Long

Open "C:\Users\steven.EOPESTATE\Desktop\Sharp Sales\TRMSAVE01.txt" For Binary As #1

strFileText = Space(LOF(1)) 'create space for the whole file'

Get 1, , strFileText        'read in the whole file at once'
lngCurrIndex = 1

Do While lngCurrIndex < Len(strFileText)
    Dim ITEMSQL As String

    lngEndOfLine = InStr(lngCurrIndex, strFileText, vbCrLf, vbBinaryCompare) 'find the end of this line. NOTE: This assumes that this text files uses the MS convention of CrLf line endings'

    varLine = Mid(strFileText, lngCurrIndex, lngEndOfLine - lngCurrIndex) 'get the line'

    lngCurrIndex = lngEndOfLine + 2 'set lngCurrIndex to the start of the next line'

    testvarline = Split(varLine, ",")

    If testvarline(0) = "$ITEM" Then
        'Debug.Print testvarline(0), testvarline(1), testvarline(2), testvarline(3), testvarline(4), testvarline(5), testvarline(6), testvarline(7), testvarline(8), testvarline(9)'
        testvarline(0) = Replace(testvarline(0), "$", " ")
        testvarline(7) = Replace(testvarline(7), ",,", " ")

        ITEMSQL = "Insert into SalesItem([ITEMID], [2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12]) Values (" & Chr(34) & "" & (testvarline(0)) & "" & Chr(34) & "," & (testvarline(1)) & "," & (testvarline(2)) & "," & (testvarline(3)) & "," & (testvarline(4)) & "," & (testvarline(5)) & "," & Chr(34) & "" & (testvarline(6)) & "" & Chr(34) & "," & (testvarline(9)) & "," & (testvarline(10)) & "," & (testvarline(11)) & "," & (testvarline(12)) & "," & (testvarline(14)) & ")"

        Debug.Print ITEMSQL
        DoCmd.RunSQL ITEMSQL
        DoCmd.SetWarnings False
        DoCmd.Echo False
    End If
Loop
Close #1

根据文件的大小,可能无法一次将其全部加载到内存中。如果是这样的话,你可以把它分成大块,一次一个地做。

【讨论】:

  • 我尝试了您的代码并以运行时错误 54 告终,该错误显示“Get 1, , strFileText”以黄色突出显示。
  • @Steve Ah,抱歉,将打开模式从Input 更改为BinaryOpen "C:\Users\steven.EOPESTATE\Desktop\Sharp Sales\TRMSAVE01.txt" For Binary As #1
猜你喜欢
  • 1970-01-01
  • 2017-10-06
  • 2015-03-24
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 2019-08-01
  • 2014-07-27
  • 1970-01-01
相关资源
最近更新 更多