Forum Discussion
Excel VBA Rows(#).Calculate not working for cells with circular references
I use Excel for complex iterative calculations that use circular references. These spreadsheets are run with the Options for Manual Calculation and Iterative Calculation on and set to 1 iteration.
To correctly calculate the iterative functionality (ie bypass Excels inheritance calculation order), I use a VBA function to calculate each row in the Worksheet from top to bottom. This used to work correctly with the following simple code:
For i = 3 to 30
Worksheets("Calculation").Rows(i).Calculate
Next i
But it appears that this was broken by an update with it working on simple calculations in the row, and cells with circular references are Not calculated.
I have tired using Range("5:5").Calculate, and even Range("B5").Calculate, but neither work.
A manual Calculation by pressing "F9" updates all cells, but as mentioned the execution order does not give the correct result.
2 Replies
- NikolinoDEPlatinum Contributor
Dealing with circular references in Excel, especially when you require specific iterative calculations, can be tricky. Excel's built-in calculation order does not always work as intended for complex iterative calculations. Given the issues with the Rows(#).Calculate method not working as expected for cells with circular references, we can explore a few alternative approaches to handle this problem.
Approach 1: Manual Iteration Control via VBA
You can explicitly control the iteration process by manually iterating over the cells and forcing recalculations. This involves calculating each cell individually within each row and then moving to the next row. This is more granular and ensures that each cell is calculated in the desired order.
Here is an example of how you can achieve this:
Vba Code is untested, backup your file first.
Sub CalculateWithCircularReferences() Dim ws As Worksheet Dim i As Long, j As Long Dim rng As Range Dim cell As Range Set ws = Worksheets("Calculation") ' Disable automatic calculation to avoid interference Application.Calculation = xlCalculationManual ' Loop through each row For i = 3 To 30 Set rng = ws.Rows(i).Cells ' Loop through each cell in the row For Each cell In rng ' Calculate each cell individually cell.Calculate Next cell Next i ' Re-enable automatic calculation Application.Calculation = xlCalculationAutomatic End SubApproach 2: Iterative Calculation Using VBA
Instead of relying on Excel's built-in iterative calculation, you can simulate the iterative process in VBA. This way, you have more control over the calculation order and can ensure that each cell is recalculated the desired number of times.
Here is an example:
Vba Code is untested, backup your file first.
Sub IterativeCalculation() Dim ws As Worksheet Dim i As Long, j As Long Dim iterations As Integer Dim maxIterations As Integer Set ws = Worksheets("Calculation") maxIterations = 10 ' Set the desired number of iterations ' Disable automatic calculation to avoid interference Application.Calculation = xlCalculationManual ' Perform iterative calculation For iterations = 1 To maxIterations For i = 3 To 30 Set rng = ws.Rows(i).Cells For Each cell In rng cell.Calculate Next cell Next i Next iterations ' Re-enable automatic calculation Application.Calculation = xlCalculationAutomatic End SubApproach 3: Using Excel's Iterative Calculation with Helper Macro
If you still want to rely on Excel's built-in iterative calculation, but want to ensure that calculations are done in a specific order, you can set up a helper macro to control the calculation process.
Vba Code is untested, backup your file first.
Sub CalculateIteratively() Dim ws As Worksheet Dim i As Long Set ws = Worksheets("Calculation") ' Ensure iterative calculations are enabled Application.Iteration = True Application.MaxIterations = 1 ' Set to 1 iteration at a time Application.MaxChange = 0.001 ' Adjust as necessary ' Disable automatic calculation to avoid interference Application.Calculation = xlCalculationManual ' Calculate each row iteratively For i = 3 To 30 ws.Rows(i).Calculate Next i ' Trigger a full recalculation to finalize ws.Calculate ' Re-enable automatic calculation Application.Calculation = xlCalculationAutomatic End SubConclusion
Given the complex nature of iterative calculations and circular references, you may need to combine these approaches based on your specific needs and the structure of your workbook. Ensuring that calculations are performed in the correct order is crucial, and using VBA to control the iteration process can provide the precision you need.
If you continue to face issues, consider simplifying the circular dependencies if possible, or breaking down the calculations into smaller, more manageable steps. The text, steps and codes were created with the help of AI.
My answers are voluntary and without guarantee!
Hope this will help you.
Was the answer useful? Mark as best response and Like it!
This will help all forum participants.
- drKBerryCopper ContributorHi All,
I have found that this issue is more complex, with it appearing to be a deeper Excel bug as a computer restart fixed the problem for a while, then it returned.
In relation to the suggested alternative code for the help of all forum participants, there are issues in the code provided that will cause incorrect calculation results. As NikolinoDE indicated, you need to test any code and spreadsheet calculations extensively. Simply reading/reviewing the Approach Code provided indicates:
All 3 approach code sets will cause abnormal results to be calculated after the code has run, because any user value change to the spreadsheet will trigger an Automatic Calculation (because Application.Calculation = xlCalculationAutomatic will cause the spreadsheet to partially recalculate after each value change or throw a circular reference error).
Approach 3 will provide incorrect results because it will calculate rows and then again the worksheet (ie 2 calculations). The worksheet calculation will use Excels inheritance calculation order, and hence the results will not be from the row calculation order.
I use this type of calculation for showing how complex control functionality operates. If the user changes a value, detecting that change triggers a series of actions, so to determine the change of value you compare the new value against the old value. (eg if (newvalue<>oldvalue) then .... endif; oldvalue = newvalue;) In this case, excel inheritance calculation will execute the oldvalue=newvalue cell formula before the if formula.
And if you are wondering why I don't program this in VBA as a function, many IT departments of my clients don't want to have VBA in Excel to be executed, and definitely wont go through a large amount of VBA code. I can normally convince them to internally allow a small function like above that does not take them long to understand. I do have extensive VBA libraries for systems that are just too complex to handle in the worksheet only.