如何在将多个工作簿合并为一个时添加一些查找数据

时间:2012-10-01 20:26:31

标签: vba excel-vba excel

我现在有一个程序,它合并了多个工作簿中的特定工作表。该程序必须处理大约300个工作簿并创建一个合并的工作簿。在合并的工作簿中,我必须向从其他工作簿复制的每一行添加一些数据点。目标工作簿中的行数可能约为100,000。

我有另一个XL,其中包含许多与客户相关的其他数据,例如姓名,国家/地区,货币等,我必须将其添加为其他列。

一个工作簿仅包含来自一个客户的数据。因此,对于从一个工作簿复制的数据,所有这些列的数据基本上是相同的。

现在,我正在考虑打开customerData工作簿并根据customerID选择性地复制数据,并在粘贴每个工作表中的数据时将其粘贴到目标工作簿中。

现在代码将是这样的:

For each workbook in the source Folder
    Open source workbook
    Copy the range from worksheet1
    Copy the customerID from worksheet2
    Open target workbook
    Paste range from source.worksheet1 in the target worksheet
    Fill the range in the target worksheet with the first column as customerID
    Open workbook with customer master data
    Copy data based on customerID
    Paste in the target worksheet using fill range

其他方法是完成粘贴所有工作表中的所有数据,然后查找客户数据 - 这里的优点是可以在多个文件中为客户提供数据,因此避免多个文件有一定的效率查找。客户主数据文件只能打开一次。

我想知道我采取的方法是否正确以及我是否可以做任何改进。

具体来说,我有以下问题:

  • 有没有办法避免打开每个源文件?
  • 将源工作簿中的所有数据添加到内存中的数组并将其复制到目标工作簿中是否更好?
  • 如果我采用数组方法,我应该在粘贴之前将查找添加到数组中,还是应该在粘贴目标范围内的数据后执行此操作?

1 个答案:

答案 0 :(得分:1)

我将此作为回复来写,因为评论可能太长。

1)无法避免打开源文件来检索数据。 对于这样的操作,非常重要的是,对于打开以进行检索的每个工作簿,您都可以创建一个新的Excel实例(CreateObject方法),并在完成后通过应用.Quit方法从内存中完全清除它。 Workbook.close并不像你期望的那样完美无缺(内存没有被清除),并且你试图在一个循环中打开/关闭的工作簿数量越多,你的应用程序崩溃/冻结的可能性就越大点。

2)阅读/写作操作花费的时间最多,因此确实建议您尝试将频率降至最低。确实最好的是将每个检索到的工作簿的所有数据一次读入单个范围(和数组)并在内存中执行所有操作。 当您执行了想要执行的操作时,可以将检索到的数组写入单个范围 你可以像你建议的那样在一个数组中一次加载所有工作簿(据我所知,数组的大小仅限于可用内存量。为了实用,我建议你写一下每次关闭文件时都会向目标工作簿发送数据。如果出现意外情况,则无需重新运行整个代码,但可以从上次的位置设置for next循环。

3)如果您想要防止每次遇到错误时应用程序停止(这很可能在您检索此数据量时),请使用

On Error goto ErrHandler
Err.Handler: 
    'Display error number / Description + place in logfile 
    Resume next 

建议您创建一个小错误处理程序,将错误代码,描述和发生错误的位置写入单独的“日志”文件中,以便您可以跟踪错误。但是这样你可以在代码运行时拿到咖啡。

4)至于查找,我不确定我是否正确理解你要做的事情。 最快的查找自然是具有最短循环的查找。嵌套循环通常相当昂贵,当它们很长时 我会提到(就像我通常那样),建议将来使用MS Access作为用户数据库(或任何其他RDBMS)(当我听到“客户ID”时,这是我想到的第一件事)。性能领域的主要优点是您可以通过应用索引直接访问记录。使用简单的SQL语句查询很容易,比使用VBA编程所有内容并循环遍历数组要容易得多。 SQL语句可用于执行常规CRUD(创建,检索,更新,删除记录)操作,还可用于执行更多操作。此外,您可以应用VBA来处理任何其他转换。

我希望我的回复对你有任何帮助,虽然我没有提供任何真正的代码。