I'm trying to ensure that all calculations are performed in the workbook, I had situations were formulas were not calculated when opening the excel file due to slowness on computer. This is the code I have right now:
Public LOCAL_PARAMETERS_WORKBOOK As Workbook
Public LOCAL_PARAMETERS_WORKSHEET As Worksheet
application.ScreenUpdating = False
application.DisplayAlerts = False
application.EnableEvents = True
application.Calculation = xlCalculationAutomatic
Set LOCAL_PARAMETERS_WORKBOOK = Workbooks.Open(StrPathFile, True, True)
Set LOCAL_PARAMETERS_WORKSHEET = LOCAL_PARAMETERS_WORKBOOK.Sheets("Business Process Data Flow")
LOCAL_PARAMETERS_WORKBOOK.Worksheets("DynamicPath").Calculate
If application.CalculationState <> xlDone Then CalculateFormulas
LOCAL_PARAMETERS_WORKSHEET.Calculate
If application.CalculationState <> xlDone Then CalculateFormulas
This is one part of a function, it's required to calculate first Sheet "Dynamic Path" and only then we can calculate Sheet "Business Process Data Flow" since the second is dependent of the first.
From what I checked if I do application.Calculate
this will force calculations in all open workbooks to be done or retype application.Calculation = xlCalculationAutomatic
then application.CalculationState
will be xlDone
.
But if I do worksheets("").Calculate
the application.CalculationState
is going to stay always xlPending
, CalculateFormulas
is a simple function with a counter and checks if application.CalculationState = xlDone
and if not then it's going to perform application.Wait (Now TimeValue("00:00:01"))
.
Is there an explanation why if I just do Calculate at sheet level the application.CalculationState
doesn't change, and is there another solution that could be implemented here to help fix my code?
CodePudding user response:
There is a bug with the Application.CalculationState
when it shows xlPending
even after calculation is complete. It manifests particularly when you have volatile functions in the workbook.
You can go around by using a class I created a few years ago. You can find it here.
If you copy code then make sure you don't copy the attribute lines (1 to 9). Otherwise I suggest you download the repo ZIP and import the ExcelAppState.cls
file.
Once you have the class, you can use it like this:
Option Explicit
Sub Test()
Dim app As New ExcelAppState
'Do stuff
'...
app.WaitForCalculations maxMilliSecondsToWait:=10000 '10 sec - or whatever timoeout you need
End Sub