I am currently trying to optimize a VBA code with extreme execution time (56 hours and more on high end PC). The main problem is nested loops (up to 8) due to complicated iterative calculations and referencing ranges in formulas.
I have two questions:
1)
What loops are most preferred in VBA (based on their hardware strain for lack of better word)
2)
Is there a way to reference variable range of cells in a formula? For example in formula:
=AGGREGATE(15,6,SQRT((R2C10:R500000C10-RC[10])^2+(R2C11:R500000C11-RC[11])^2+(R2C12:R500000C12-RC[12])^2),1)
I am referencing relative cell: "R500000C10". There are two main issues: For one, the half milion cells might not capture all data - though in most cases there is less active cells than that, in same cases that might be an issue. Second, it takes forever to scan through so many cells (same reference is used in multiple of VLOOKUPs).
The first issue could be solved by referencing the whole column, but that makes the second problem worst.
I would like to reference it in a similar way that xlDown works:
Range().End(xlDown).Select
The problem there is I would need to reference it within the Active.Cell.FormulaR1C1. Is there a way to do that?
Thanks!
Well you wrote that you have a code with 8 loops and try to optimize it maybe you can edit and put part of that code, because your description is very general, however, with information that you put i speculate that about your point
1)it depend what do you want to do? because each "loop" have their own use for specifyc scenaries
2)there are tricks to do that but all depend what are you trying to do and why you want to use .formulaR1C1
again im speculating but you can try tu separate your loops in indenpendent function, and maybe you are putting a formula inside cells, and question is why? you can create functoins and Sub in your VBA code and do your "extrem execution" without use xtra "resours"
There is a file that contains mathematical operations that are a bit complicated.
When the file is opened on my laptop the value of 500,000,000 changes to 500,000,001, an excess of 1 number.
What exactly should I do?
I use Excel 2013, using an Asus X441U
This is commonly a formatting problem.
Please make sure that you are obtaining the real value of the result, not the displayed value.
This is best done by changing the cell number formatting. I would recommend adding a helper cell or two to and use =CELL("contents",yourcellwithchangingvalue) as one test.
Another method is to make a second result cell and wrap it in =TEXT(yourcellwithchangingvalue, "#.###") to see if that causes it to change.
Lastly, be sure all of your formulas are using functions or addins that are available on both machines.
I am working on an elongated IF statement that produces different outputs depending on the start of a part number e.g. 3XXXXXXX = Software, 4XXXXXXX = Hardware.
The problem I am having is that the formula outputs FALSE when a part number is yet to be given to the row.
=IF(B2>0,IF(LEFT(D2,1)="1","Assembly",IF(LEFT(D2,1)="2","Sub-Assembly",IF(LEFT(D2,1)="3","Software",IF(LEFT(D2,1)="4","Hardware",IF(LEFT(D2,1)="5","Chemical",IF(LEFT(D2,1)="6","Spare",IF(LEFT(D2,1)="7","Spare",IF(LEFT(D2,1)="8","Document",IF(LEFT(D2,1)="9","Misc",""))))))))))
Please let me know if you can spot where I am going wrong!
You have at least two other options, both of them providing you better maintainable code.
If you use Excel 2016 or higher, there is the SWITCH function. Your formula will then look much more readable:
=IF(B2>0,SWITCH(LEFT(D2,1),"1","Assembly","2","Sub-Assembly","3","Software","4","Hardware","5","Chemical","6","Spare","7","Spare","8","Document","9","Misc",""))
Even in earlier Excel versions, you may use a lookup table, which provides you much higher versatility. Create a table of your categories, you may place them in a separate sheet Categories:
Use VLOOKUP function together with IFERROR to provide the default value when not found:
=IFERROR(VLOOKUP(LEFT(D2,1),Categories!$A$1:$B$9,2,FALSE),"")
You're not putting any value for the first big condition (if B2 is not > 0)
Try this instead:
=IF(B2>0,IF(LEFT(D2,1)="1","Assembly",IF(LEFT(D2,1)="2","Sub-Assembly",IF(LEFT(D2,1)="3","Software",IF(LEFT(D2,1)="4","Hardware",IF(LEFT(D2,1)="5","Chemical",IF(LEFT(D2,1)="6","Spare",IF(LEFT(D2,1)="7","Spare",IF(LEFT(D2,1)="8","Document",IF(LEFT(D2,1)="9","Misc",""))))))))),"")
You can simplify your formula like this:
=IF(B2<=0,"",CHOOSE(LEFT(D2,1),"Assembly","Sub-Assembly","Software","Hardware",
"Chemical","Spare","Spare","Document","Misc"))
I would like to create a report that look like this picture below.
My data has around 500,000 cells (it will continue to grow larger)
Right now, I'm using countifs function from excel but it takes a very long time to calculate. (cannot turnoff automatic calculate)
The main value is collected as date and the range of date is about 3 years, so I have to put a lot of formula to cover all range of value.
result
The picture below is the datasource the top one cannot be changed. , while the bottom is the one I created by myself (can change). I use weeknum to change date to week number.
data
Are there any better formula or any ways to make this file faster? Every kinds of suggestions are welcome!
I was thinking about using Pivot Table, but I don't know how to make pivot table from this kind of datasource.
PS. VBA is the last option.
You can download example file here: https://www.mediafire.com/?t21s8ngn9mlme2d
I will post this answer with the disclaimer that it is entirely dependent on the size of the data set. That turning on and off the auto calculate is the best way, but your question doesn't let me do that, so keep reading.
Your question made me curious, so I gave it a try and timed it. I essentially set up two columns of over 100,000 rand numbers choosing from 1-1000 and then tried to do a countif on the two columns if they were equal. I made a macro that I can run that turns off the autocalculate, inserts the start time, calculates, and then inserts the finish time. I highlighted in yellow the time difference.
First I tried your way, two criteria, countifs:
Then I tried to combine (concatenate) the two columns to see if I could make it easier by only having one countif criteria and data set. It doesn't. see result below:
Finally, realizing what was going on. I decided to make the criteria only match the FIRST value in the number to look for. I was essentially reducing the number of characters to check per cell. This had a positive result. See below:
Therefore my suggestion is to limit the length of the words you are comparing in anyway possible. You are mostly looking at dates, so you might have to get creative, but this seems to be the best way possible without going to manual calculation.
I have worked with Excel sheets of a similar size. Especially if you are using the data on a regular basis, I would heartily recommend switching to a proper database SQL based, Access, or whatever fits your purpose. I does wonders for the speed and also you won't run into the size limits of Excel. :-)
You can import the data you have now fairly easy.
I am happy as a clam with my postgresql db.
I´ve a very large file that I reduced as much as possible to 3 columns and 80k rows.
I need to perform a vlookup in order to bring values from column 1 or 2 match some other spreadsheets values.
The thing is Excel doesn´t seem to support such large searches, and it stops responding - the computer has 4GB and a Quad core, and not much more running at the same time.
As far as I understand, as I´m not looking for exact matches, I should not use match-index.
The only thing I thouhgt could help but not sure about that, is dividing the file in 2-4, and asking Excel many parallel searches instead of a big one. Could this work?
What else should I try?
Thanks!!!
Sort your data and use True as the 4th VLOOKUP argument. This makes VLOOKUP use binary search rather than linear search and is lightning fast.
If you need to handle missing data you will need to use the double VLOOKUP trick, see
http://fastexcel.wordpress.com/2012/03/29/vlookup-tricks-why-2-vlookups-are-better-than-1-vlookup/