如何在excelvba中加速数据文件导入

如何在excelvba中加速数据文件导入,excel,vba,Excel,Vba,截至2019年6月11日的更新:我仍然没有弄清楚为什么我的延迟几乎都发生在这两条线路上,但目前的状况是我忍受了延迟。到目前为止,主控文档中大约有6000行数据,无论导入多少行,导入过程都需要大约20秒 - 我有一个“主文档”,我整天从很多小文档导入数据。我承认我在这里并不是一个超级天才,我的很多编码习惯都来自于“老派”,所以可能有我不知道(但想学!)的“Excel方法” 我看到的问题是数据文件导入需要多长时间 当我启动工具时,数据导入只需几秒钟 现在我有大约3500行数据,数据导入大约需要15-

截至2019年6月11日的更新:我仍然没有弄清楚为什么我的延迟几乎都发生在这两条线路上,但目前的状况是我忍受了延迟。到目前为止,主控文档中大约有6000行数据,无论导入多少行,导入过程都需要大约20秒

-

我有一个“主文档”,我整天从很多小文档导入数据。我承认我在这里并不是一个超级天才,我的很多编码习惯都来自于“老派”,所以可能有我不知道(但想学!)的“Excel方法”

我看到的问题是数据文件导入需要多长时间

当我启动工具时,数据导入只需几秒钟

现在我有大约3500行数据,数据导入大约需要15-20秒。不管我是导入一行还是一百行。我预计这一数字会继续上升。当我排到7000行或10000行时,我希望它会变得难以忍受

通过使用消息框(记住:“老派”),我已经能够将速度瓶颈缩小到两行代码。“步骤1”和“步骤2”之间大约是我延迟的30%,而“步骤2”和“步骤3”之间大约是我延迟的70%

我已经包括了下面的整个子部分,以确保我没有遗漏一些明显的内容,但我确保取消我的消息框,以便您可以转到我怀疑的代码。此外,我还包括了整个sub,因为通常第一个回答是“你能展示整个sub以便我有更好的上下文吗?”

感谢您提出的任何想法或建议。:)


看起来这里有很多好东西。我看到的一些事情可能会改变,以提高您的绩效


首先,在“步骤1”和“步骤2”之间:根据我的经验,添加行比使用已经存在的行花费更长的时间。看起来您基本上是在“向下推”所有内容,以便为新数据腾出空间,这样新输入的数据位于顶部,最旧的数据位于底部。(如果我在这方面有任何错误,请纠正我。)如果您只是简单地将数据添加到工作表的末尾,您可能会看到一些性能改进,尽管我不知道这会有多大的改进

第二,在“步骤2”和“步骤3”之间:我发现使用
.Value2
而不是
.Value2
可以提高性能,数据越大,改进越大。它有一个下边-Value2没有保留任何可能存在的格式,这意味着数字类型(日期、会计等)没有正确地靠边。如果这是您不需要的,那么可以使用Value2

最后,还有其他方法:当我运行大量宏时,我总是尽我所能提高性能。通过使用关闭屏幕更新之类的技巧(
Application.screenUpdate=False
),您可以获得全面的轻微提升,但请确保在宏结束时将其重新打开


我希望这能帮你解决这个问题!如果所有其他操作都失败,您可以手动执行一次或两次,以记住它使用宏的速度有多快!哈哈。祝你好运

尝试在脚本的开头和结尾添加此选项。一定要把一切都变回现实

Application.ScreenUpdating = False
Application.DisplayAlerts = False

...CODE HERE...

Application.ScreenUpdating = True
Application.DisplayAlerts = True

你试过使用.value2吗?在某些情况下,它可能会为您带来更好的性能。在此处检查一些性能比较:

如果没有原始表格,很难看出问题出在哪里。可能问题在于数据本身而不是VBA代码,有时可能需要清除源数据中的繁重内容,然后在需要时再次添加


您也可以考虑使用Python完成某些部分,但如果您不想在解决方案中添加其他软件层,我想这是不可能的。

问题在于您正在与应用程序的对象交互。遗憾的是,当您这样做时,文件越大,您将观察到的延迟就越大。不接触应用程序的对象将消除延迟。这意味着所有像“选择/激活/复制/粘贴”这样的事情,以及你所做的所有有趣的格式化。对“物理”excel对象所做的任何操作都会对性能产生巨大的影响,而且工作表/工作簿越大,其性能就越差。你需要格式化吗?excel是正确的工具吗?轻量级ms access不是更好吗?“您需要格式化吗?”字体格式化在延迟之后发生。“excel是正确的工具吗?”excel是我使用过的工具,也是我工作经验最多的工具。它是组织中其他所有人都在使用的工具。“一个轻量级的ms access不是更好吗?”我不太可能说服组织中的所有其他人转而使用access来创建关于事务性数据的报告。但是如果我知道的足够好,可以使UI非常流畅,那么我可能需要几个月的时间来学习它。在源工作簿或目标工作簿中有公式吗?可能值得在代码开始时禁用计算,然后在代码结束时再次启用。这将防止在insert语句和数据导入期间重新计算公式。如果公式重新计算是导致延迟的原因,这应该会减轻延迟。同样,如果您对工作簿或工作表事件进行了编码,则可以禁用事件以阻止这些事件运行,如果这可能是导致延迟的原因。“源工作簿或目标工作簿中是否有公式?”我有。这是个好主意,但我不得不放弃它“看起来您基本上是在“向下推”所有内容,以便为新数据腾出空间,这样新输入的数据位于顶部,最旧的数据位于底部。”正确。这使得以后的搜索速度大大加快,因为
    MsgBox ("Step 2")

        'Ive never moved large amounts of data using this method. Ive always just used arrays. I have moved smaller bits of data though.
        ' I suspect that this might take a moment if the data set is large. Again use arrays to grab the data and move it.
        ' Edward says “This step takes about 70% of my delay — even if bringing in only a single line of data.”

        targetSheet.Range("B2:AB" & ImportRecordCount + 1).Value = sourceSheet.Range("A3:AA" & ImportRecordCount + 2).Value ' Bring in the big pile of data

    MsgBox ("Step 3")

      ' this loop is probably your main culprit of your performance issue. 
      ' Edward says “Nope, this flies by. It is not the issue at all. I have verified this already.”
      ' Learn how to construct an array of data on the fly and then learn how to dump the entire array to 
      ' sheet using a simple method.

        For TransactionCounter = 2 To ImportRecordCount + 1 ' Create and add the new Transaction ID values
            targetSheet.Range("a" & TransactionCounter) = TransactionID + ImportRecordCount - TransactionCounter + 1
        Next
Application.ScreenUpdating = False
Application.DisplayAlerts = False

...CODE HERE...

Application.ScreenUpdating = True
Application.DisplayAlerts = True