简体   繁体   English

Excel VBA FormulaArray太慢

[英]Excel VBA FormulaArray Too Slow

I have a macro that populates start and complete dates based upon the accounting period. 我有一个宏,它根据会计期间填充开始日期和完成日期。 For example: Product X has sales in Jan12 - Dec12. 例如:产品X在1月12日-12月12日销售。 The macro would use a vlookup/min array to find the start and a vlookup/max array to find the finish. 该宏将使用vlookup / min数组查找开始,并使用vlookup / max数组查找结束。 The dates are in a YYYYMM format, so the vlookup is looking at a calendar tab that maps the corresponding YYYYMM to a start or finish date. 日期采用YYYYMM格式,因此vlookup正在查看日历选项卡,该选项卡将对应的YYYYMM映射到开始或结束日期。 The coding works fine, but in some instances there are 30,000 - 100,000 lines and it can take upward of 15-20 minutes to run. 编码工作正常,但在某些情况下,存在30,000-100,000行,可能需要15-20分钟才能运行。 Does anyone have any ideas on how to make this run faster? 是否有人对如何使其运行更快有任何想法?

Here is the code: 这是代码:

Cells(Rcnt, 5).FormulaArray = "=VLOOKUP(MIN(IF('Normalized'!A:A= " & Cells(Rcnt, 1).Address(False, False) & ", 'Normalized'!J:J)),'Calendar'!A:C,2,FALSE)" Cells(Rcnt,5).FormulaArray =“ = VLOOKUP(MIN(IF('Normalized'!A:A =”&Cells(Rcnt,1).Address(False,False)&“,'Normalized'!J:J )),'Calendar'!A:C,2,FALSE)“

Any help would be greatly appreciated. 任何帮助将不胜感激。

Don't use a formula in your macro. 不要在宏中使用公式。 You can probably make the code much faster by writing the code in VBA yourself. 您可以通过自己在VBA中编写代码来使代码更快。 You could loop through all values in a line and store the smallest and largest values (you can keep max and min so you only need one loop). 您可以遍历一行中的所有值并存储最小值和最大值(可以保留max和min,因此只需要一个循环)。 Then write these values to wherever is appropriate. 然后将这些值写入适当的位置。 This should already be a speed up over the excel formula. 这应该已经超过了excel公式。

To get started with writing macros in VBA look here . 要开始用VBA编写宏,请看这里 You will specifically want to look at how to loop through the cells. 您将特别想看看如何在单元格之间循环 You will want to set max = Jan 1 and min = Dec 31 and then if the value you are currently inspecting is greater than max you set max equal to the value and likewise for min. 您将需要设置max = Jan 1和min = Dec 31,然后如果当前检查的值大于max,则将max设置为等于该值,同样将min设置为最小值。 After looping through that row you will have the max and min values in that row. 遍历该行后,您将在该行中具有最大值和最小值。 You can then write these values into some other column, reset max and min and move to the next row. 然后,您可以将这些值写入其他列,重置最大和最小,然后移至下一行。

My understanding of your issue is that your data lists each product's sales in each month, so for each product, you are searching for the first and last months. 我对您的问题的理解是,您的数据列出了每个月每个产品的销售额,因此对于每个产品,您都在搜索前几个月和最后几个月。 Can you sort the data by product and by date? 您可以按产品和日期对数据进行排序吗? That would be the easiest way to implement a loop as Emschorsch described, because you'd only be dealing with one product at a time. 如Emschorsch所述,这将是实现循环的最简单方法,因为您一次只能处理一种产品。

A couple other things to try to speed this up: 尝试加快速度的其他几件事:

  • set the first line of your code to: 将代码的第一行设置为:

     Application.Calculation = xlCalculationManual 

    and your last line to: 最后一行是:

     Application.Calculation = xlCalculationAutomatic 

    (you still have tons of lookups, but they will calculate all at once, not one at a time as you create each row's formula) (您仍然有大量的查询,但是它们将一次计算全部,而不是在创建每一行的公式时一次计算一次)

  • If sorting the data won't fly, you can Autofilter on each product in succession and use the SUBTOTAL() function, referencing the date column, to get the min and max. 如果无法对数据进行排序,则可以连续对每个产品进行自动过滤,并使用SUBTOTAL()函数(引用日期列)来获取最小值和最大值。 (You can place the SUBTOTAL() formula in an unused cell and reference that cell in your code, or use it directly in the code using Application.WorksheetFunction) (您可以将SUBTOTAL()公式放在未使用的单元格中,并在您的代码中引用该单元格,或者使用Application.WorksheetFunction在代码中直接使用它)

The other part that seems unnecessary (without seeing your data we can't be sure) is using a lookup to turn YYYYMM into a date, if that is truly the format all of your dates are in. That can easily be done without VBA using the DATE() formula, or if you need it inside a macro: 似乎没有必要的另一部分(如果无法看到您的数据,我们无法确定)是使用查找将YYYYMM转换为日期,如果这确实是所有日期都采用的格式的话,那么无需使用VBA即可轻松实现DATE()公式,或者如果您需要在宏中使用它:

cells(Rcnt, 5).Value = DateSerial(Left(x, 4), Right(x, 2), 1)  'x is your date in YYYYMM format

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM