how I can run Formulas Calculate as last proces when WorkBook is opened ?
I mean when all data are already load, user gave permission to load external data from others WorkBook etc.
I already tryed with
Private Sub Workbook_Open()
Application.Calculate
End Sub
Private Sub Workbook_Open()
If Not Application.CalculationState = xlDone Then
Application.Calculate
End if
End Sub
When I run Excel file and click F9 (Calculate Formulas) then it's work.
How I can run Application.Calculate when all externals links(data from others workbook) are already loaded ? I think it could help
Thanks,
When you open the workbook use
Application.Calculation = xlCalculationManual
When you are about to close the workbook after completing all the work use
ThisWorkbook.Worksheets("wrkSheetName").Calculate
for each worksheet.
Related
I implemented some code into a few of my excel sheets that would cause the file to autosave periodically. The issue I am running into with the code, is that when it is executed, it reopens the files that have been closed that also contain the same code.
I am looking for a way to have VBA autosave documents every so often, but it would no longer run if the file isn't open.
This is the code I have implemented:
Contained in "ThisWorkbook":
Private Sub Workbook_Open()
Application.OnTime Now + TimeValue("03:00:00"), "Save1"
End Sub
Contained in "Module 3":
Sub Save1()
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Application.OnTime Now + TimeValue("03:00:00"), "Save1"
End Sub
A note: The code between all of the documents is 100% identical (except the TimeValue, which varies by a few hours among some of them).
Try the next approach, please:
Adapt the OnTime call to a better qualified Sub:
Private Sub Workbook_Open()
scheduleTime = Now + TimeValue("03:00:00")
Application.OnTime scheduleTime, "Module3.Save1"
End Sub
Make the Sub in discussion Private, and create a new Public variable on top of the module:
Public scheduleTime As Date
Private Sub Save1()
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
scheduleTime = Now + TimeValue("03:00:00")
Application.OnTime scheduleTime, "Module3.Save1"
End Sub
Clear the already set OnTime procedure:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.OnTime scheduleTime , "Module3.Save1", , False
End Sub
The first two items will solve the opening of other workbooks when the active workbook procedure is called. But, this should not happen and I am afraid that this is not the real opening mechanism, the workbooks are open by their own OnTime function call.
If my above supposition is True, the item 3 alone will solve the issue...
As you may notice, OnTime is an Application method, not a Workbook method.
This means that, even if you close the Workbook, so long as the Excel Application is still open that OnTime is still counting down. Once it hits zero, it will try to run the Subroutine - but the workbook is closed. Rather than throw an Error, Excel will reopen the Workbook, and then run the Subroutine.
In order to stop this, you will need to unscheduled the Subroutine before you close the Workbook, which will also mean Storing the time. So, you will need a Module that looks something like this:
Option Private Module
Option Explicit
Private AutoRunTime AS Date
Public Sub AutoSaveWorkbook()
ThisWorkbook.Save
AutoRunTime = Now()+TimeSerial(3,0,0) '3 hours
Application.OnTime AutoRunTime, "AutoSaveWorkbook", True
End Sub
Public Sub CancelAutoSave()
Application.OnTime AutoRunTime, "AutoSaveWorkbook", False
End Sub
Then, in the Workbook_Open even you call AutoSaveWorkbook to start things off, and in the Workbook_BeforeClose even you call CancelAutoSave to end them
I have file excel contained macro (.xlsm file). This Macro is objected to calculate the workbook and close the excel application.
Sub calc()
ActiveWorkbook.Calculate()
ActiveWorkbook.Saved = True
Application.Quit
End Sub
I want to trigger calc() macro every time i open the excel. So in ThisWorkbooks, i add
Private Sub Workbook_Open()
Call calc
End Sub
I stuck, when i open the .xlsm file, macro is calculate but the .xlsm won't close at all. Any suggestion?
It seems you have a syntax error in your code. You should also pay attention to the hint from #Tarik. The following code should do what you want
Private Sub Workbook_Open()
Call calc
End Sub
Sub calc()
Calculate
ThisWorkbook.Save
Application.Quit
End Sub
Are there some macros which can do it?
Any help would be appreciated - I am novice with VBA.
Please put this code in ThisWorkbook module. you can access this module by pressing double click on ThisWorkbook module inside VBA project.
Private Sub Workbook_Open()
Application.OnTime Now + TimeValue("00:01:00"), "Save1"
End Sub
then put this code in standard module. To insert standard module, right click on VBA project==>Insert==>Module. then paste code in newly created module.
Sub Save1()
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Application.OnTime Now + TimeValue("00:01:00"), "Save1"
End Sub
Now when you open your workbook, it will automatically save every minute. You need to reopen Workbook in order to trigger Workboook_Open event.
I'm trying to add a counter to a workbook to see how many times the workbook is used. However, the workbook is frequently updated by a script that will open said workbook, add new sheets to said workbook, and close/save the workbook. I would like to only count a use if the workbook is longer than 1/2 a second.
I have tried to add timers to the Workbook_Open function, this is what I currently have tried.
Private Sub Workbook_Open()
Dim AlertTime as Double
Application.OnTime AlertTime + TimeValue("00:00:02"), "AccessCounter"
End sub
Sub AccessCounter()
On Error Goto WorkbookAccessedbyMacro:
Counter = Counter + 1
WorkboookAccessedbyMacro:
End Sub
With the thought that having the On Error will just do nothing if the workbook is already shut. Thanks for any advice!
I figured it out, I simply had to move the Sub AccessCounter() to a module. Rookie mistake.
I am running a macro that opens a file referencing the one I am working in, pastes the relevant items as values into a separate sheet and makes a workbook out of that sheet.
The reason why I am doing this is because there are several thousand countifs, averageifs, and processor-intensive ilk.
The program runs from start to finish, just fine. The issue is that only a few of the items are calculated before the copy/paste operation and so I get a lot of #VALUE errors on the copy of the sheet with the formulas--even though the formulas are calculating correctly on further inspection.
I suspect the correct course of action is to delay the run until the sheet finishes calculating. Any and all help would be appreciated.
EDIT: I've tried all manner of application.calculations and nothing seems to be working. The links and items calculate normally if I open manually and let the processor do its thing. The only items that calculate are the ones that contain "COUNTA" somewhere in it. Is it possible that the application calculation methods don't work with Countifs and the like?
Shouldn't be that hard to do - the Worksheet object has a Calculate property that fires after it calculates. You can add a custom property to the worksheet that exposes a flag that you set after it is done calculating. In the worksheet code that has the time consuming calculation...
Option Explicit
Private can_copy As Boolean
Public Property Get CopyOK()
CopyOK = can_copy
End Property
Private Sub Worksheet_Calculate()
can_copy = True
End Sub
Private Sub Worksheet_Activate()
can_copy = False
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
can_copy = False
End Sub
'For volitile functions.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
can_copy = False
End Sub
...and in the calling code:
Dim book As Workbook
Set book = Application.Workbooks.Open("C:\foobar.xlsm")
Do While Not book.Worksheets("Sheet1").CopyOK
DoEvents
Loop
'Do your thing...
Note that I likely missed some events that would trigger a recalculation, but this should cover the scenario of just opening it.
So, I found a means for this to work:
Do Until Application.CalculationState = xlDone
Application.Calculate
While Application.CalculationState <> xlDone
MsgBox Application.CalculationState
DoEvents
Wend
Loop
It was a solution I sort of applied from Siddharth Rout : Wait until Application.Calculate has finished
Thank you everyone for your help!