简体   繁体   中英

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. The macro would use a vlookup/min array to find the start and a vlookup/max array to find the finish. 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. 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. 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)"

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. 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). Then write these values to wherever is appropriate. This should already be a speed up over the excel formula.

To get started with writing macros in VBA look here . 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. 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.

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. (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)

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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