Forum Discussion
Excel VBA Rows(#).Calculate not working for cells with circular references
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.
- drKBerryJun 14, 2024Copper 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.