I have a function that I have implemented as a VBA module which takes one cell as a parameter and queries a web services to return a result. As the source of the data is remote, this function can take a few seconds to return.
The problem is that some actions, such as deleting any column, seem to cause every formula to recalculate, even if no change is needed. When my sheet has several hundred rows, this can take several minutes during which time Excel is unresponsive.
I would like to find some way to detect that no change is needed and skip this step. Some things I have tried:
- Determine the current value of the cell to be changed, from which I could determine if an update is needed. But ActiveCell.Value is blank, and attempts to pass the cell itself as a second parameter are met with a circular reference warning.
- Created a second column to hold the old input value, which is then passed into the function and compared with the new value. However, functions are not able to update this old value on success, and attempts to update with only formulas are always met with circular reference warnings. Furthermore, it doesn’t seem that a function can return a “no change”, so I would need to store and use the old result.
Is there any way to prevent some actions from updating every formula on the sheet?
Other requirements:
- There may be a way to disable all formula automatic calculation, but I definitely want each row to update as soon as the parameter cell is entered. I also don’t want to force the user to push a button to update the function.
- I tried doing a custom spreadsheet in Visual Studio, but found the deployment too difficult to maintain for my user base. Solution must be entirely contained in a macro-enabled workbook.
- Excel versions to use the sheet will be 2007 and 2010.
I would
systematically block recalculation by setting File / Options / Formulas / Workbook Calculation to “Manual” and switch off “Recalculation on Save” as well
create a
Private Sub Worksheet_Change(ByVal Target As Range)and determine, under which conditions a recalculation should take place (Target.Worksheet.Calculate) – for example determine the coord’s of the target (usingTarget.ColumnandTarget.Row), and call the query from inside the Worksheet_Change trigger.Eventually I would put the recalculation instruction in a Sub of its own and make a button into the sheet so the user can – on his/her wish – manually trigger recalculation (just in case the F9 key isn’t known to the users)
It is also thinkable to use a global Boolean variable
need_Querywhich is set by the Worksheet_Change triggerIf Target.Row = X And Target.Column = Y(= the parameter) and have the query function examine (and reset) that Boolean, and go in the query onlyIf need_Query Then, otherwise exit without action. Make sure that need_Query is set FALSE at worksheet load time, too.Finally, you could convert the query function into a
Suband formulate some more complex conditions in the Worksheet_Change trigger to fire it (e.g. if a certain column changes, etc.).