I am using the formula to ~300 cells which takes the address dynamically using INDIRECT function, but it is slowing down the calculation time.
please suggest me an alternative method to make the calculation faster.
I have done basics as it has macro with screen updating= false and calculation=xlmanual.
=SUMIFS(Sheet1!$L:$L,Sheet1!$I:$I,Bookings_QTD!$F51,Sheet1!$B:$B,Bookings_QTD!I$2,INDIRECT($I$8),$K$8,Sheet1!$C:$C,$M$8)/1000000
here cell $I$8 is dynamic where values will varies based eg:-Sheet5!$A:$A, Sheet5!$B:$B...
$I$8=Sheet5!$E:$E
I need to use it for many cells ~400+ with other criterias in future.
kindly suugest me better formula or method which will decrease the calculation time.
Thanks in advance
INDIRECT() will be slow for many sheets as it is a Volatile function. i.e. every time there is a change in any cell in the workbook, it will get triggered.
If your cell values are relatively static. i.e. if you are indirectly referring to cell "B6" and you expect the content of B6 to remain the same and only expect the input of your function to change, say from "B6" to "Z8", you can use the following code:
Function MyIndirect(RangeStr as String) as Variant
MyIndirect = ActiveSheet.Range("RangeStr").Value
End Function
This should work. And should you need to 'refresh' this value, simply run an Application.Calculation (i.e. press Ctrl-Alt-F9)
Related
Is it possible to output the result of a formula on a different cell without the use of VBA and without directly reffering to the cell containing the formula (e.g. writting =C1 into the output cell)?
I know that this can be easily done with the help of VBA, but I was wondering if there really is no simpler way to achieve this.
I don't think so, if you dont want VBA then all I can think of is to lock the cells so they can't be updated.
How to lock just a range of cells
As far as I know all formulas display their results within the cell they occupy.
if you want to pull a value from a cell without directly referencing the cell address, you could indirectly by using the offset function. However even the offset function needs to reference at least one cell on the worksheet.
I am wondering if in Excel there is a way to change columns as described below?
=A1*(Formula that returns a letter)2
so for example the formula returns the letter F the result would be
=A1*F2
then if in cell A1 = 3, and F2 = 7. then where the Excel formula is the result would be 21.
I am hoping this approach is possible as I am hoping to use it in a SUMPRODUCT(SUMIFS(.......................................)) where the data I am analyzing is in a mess of columns and labels. and am confused with what else I can try.
The INDIRECT function can take text-that-looks-like-a-cell-reference and convert it into a valid cell reference.
=INDIRECT("A2")
=INDIRECT("A"&2)
=INDIRECT(<formula that returns a letter>&2)
=INDIRECT(<formula that returns a letter>&"2")
... each of these is the the same as,
=A2
All you have to do is pass along some constructed text string that can be interpreted as a cell reference into INDIRECT.
Caution should be exercised when using the INDIRECT function as it is considered a volatile¹ function. If they are used in calculation-intensive formulas or very prolifically, the user will experience calculation lag whenever anything in the workbook changes.
¹ Volatile functions recalculate whenever anything in the entire workbook changes, not just when something that affects their outcome changes. Examples of volatile functions are INDIRECT, OFFSET, TODAY, NOW, RAND and RANDBETWEEN. Some sub-functions of the CELL and INFO worksheet functions will make them volatile as well.
Is it possible to prevent calculations happening to a single cell in Excel sheet? Let's say I have 1001 cells that are very fast to calculate, but 1 cell slows sheet down, is it possible to disable calculations for that 1 cell only?
What I'm NOT trying to do:
Disabling all of cell calculation programically
Calculating specific cells programically while global calculation is set to manual
Use Excel's =IF() function. It is set up to "short-circuit" -- it only evaluates the second parameter if the first parameter is true, oppositely for the third parameter.
So, if the cell is C1, and the cell's formula is currently
=LOOKUP(2,1/(A1:A100000=666),B1:B100000)
and you want it to only be calculated when D1 is true, use
=IF(D1,LOOKUP(2,1/(A1:A100000=666),B1:B100000),C1)
Notice it's a circular reference -- it's how you keep the value the same when D1 is false. Turn on iteration if you want to get rid of the warning message.
Another way is to use one of the third-party Add-Ins out there that lets you store a global variable off-sheet and then retrieve it, which would use syntax like this:
=IF(D1,SetGlobal("C1StoredCalculation",LOOKUP(2,1/(A1:A100000=666),B1:B100000)),GetGlobal("C1StoredCalculation"))
SetGlobal() and GetGlobal() can also be written in VBA, though they'll be a tiny bit slower than an XLL, and they'll lose the value if you reset your VBA project.
Excel does not have a method to disable calculation for a single cell.
You could move the slow formula to a separate sheet and use worksheet.enablecalculation to disable calculation for that sheet.
Or you could store the formula somewhere as text, store the result as a value in the cell, then restore the formula when you want to calculate it.
You can use a replacement UDF and take advantage of a lack of volatility.
Say we have a formula like:
=LOOKUP(2,1/(A1:A100000=666),B1:B100000)
Excel will re-calculate this if any cell in cols A or B change, but the UDF
Public Function myudf(r As Range) As Variant
myudf = Evaluate("LOOKUP(2,1/(A1:A100000=666),B1:B100000)")
End Function
will only be re-calculated when its argument changes. So pick a cell and enter:
=myudf(Z100)
make any changes you want to cells in cols A or B and myudf will remain un-re-calculated until you change Z100
You can use the same tiny trick to make "quasi-volatile" versions of =TODAY() or =NOW() for =RAND()
I don't think this can be done. You can turn off automatic calculation in entire workbooks (as you mentioned), but I don't think there is a way to do this on an individual cell.
I have a spreadsheet which contains a massive IF then Formula and it's getting a bit out of control, the spreadsheet is getting slower and becoming more difficult to maintain.
Is it possible to move the formulas from the cells to VBA? Would this have any improvement on performance? I was thinking about using a Select Case but need some help as to whether a select case would work. The select case will need to look at multiple cells i.e. If A1 = Yes AND A2 = "Cash" AND A3 = No" then call the Index Match function to retrieve the value. Is this possible?
Is there a big performance gain moving formula's out of the worksheet into VBA?
Thanks for any advice.
Brett
I don't think you find any performance improvement simply from moving the same code from the cell into VBA.
However it will be easier to read, and you may then see that not all of the conditionals are necessary, so you may be able to simplify it - which would speed it up.
"Select Case" will probably not be helpful though as it can only be used for a single comparison, not three like you mention.
I would suggest taking it one step at a time, move the formula into VBA, and convert it to a VBA "if" statement. Then you may be able to see ways to tidy it up.
Yes and No.
The main advantage to using VBA is that you could then also use for or while loops.
So instead of writing the same formula for each cell, you can develop your code to do these calculations in as many cells as you need/want.
Its not an easy question to answer, due to the little amount of information provided in the question.
Having the code in Excel formulas mean that it will be recalculated when any of its parameters changes i.e. you change the value of one Excel cell -> all Excel cells that use this value will be recalculated. This may significantly slow down Excel when you are making constant changes.
One way of handling this is to manually turn off Automatic calculations (Formulas->Calculation Options->Manual). Make your changes and run the calculations manually by hitting Formulas->Calculate Now for recalculating the whole workbook or Formulas->Calculate Sheet for a recalc of only the worksheet.
Another way is to move the formulas to a VBA procedure. This way you can execute the calculation manually while all the other calculations in the workbook are carried out automatically.
EDIT1:
To make an VBA procedure from an Excel formula create a procedure like this:
Sub CalculateFormula
Range("A1").Value = Evaluate("YOUR EXCEL FORMULA WITHOUT '='")
'Simple example below
Range("A1").Value = Evaluate("IF(A1=1,1,2)")
End Sub
EDIT2:
With looping:
Sub CalculateFormula
for i = 1 to 10
Range("A" & i).Value = Evaluate("IF(B" & i & "=""Hello"",2,1)")
Next i
End Sub
I'm trying to process some data using Microsoft Excel 2010 and have come to something which confuses me. I have one cell which is doing the randbetween() function and is only referencing one other cell.
When I change the value for a completely enrelated cell to either of those cells then it changes the value for those cells which use the randbetween() function.
Why's it doing this and is there a way to stop it doing this?
Volatile functions will recalculate automatically whenever an action takes place in Excel-e.g., entering data somewhere else, or forcing a recalculation of the worksheet by pressing F9.
Some of the volatile functions are
Rand()
RandBetween()
Now()
Today()
To stop volatile calculations from calculating, you will have to change the calculation mode to Manual.