UseCalculate method, but don't recalculate data tables - vba

I know you can set the calculation settings for the workbook, but I want to calculate the workbook ---and not data tables--- while running a VBA sub.
Generally, you can just call "Calculate" in your code and it acts as if you hit "F9" manually. How can you call "Calculate" and not recalc all data tables?

Application.Calculation = xlCalculationManual
Application.Calculation = xlCalculationSemiautomatic
does what you want.

Related

Excel VBA: efficient way to load data in a workbook with a lot of formulas

I have an Excel VBA code that reads the master data, load the data of each case/loop into a workbook, and then tons of calculations take place via numerous formulas (with no VBA codes). The desired result is the outputs of the calculations. The code loops through all the cases in the master data.
So here is the problem. I used multiple 'copy and paste' actions in each loop to load the data into the workbook, but the run time is way longer than I expected, causing Excel to be 'Not Responding'. Note that I already turned off automatic calculations in Excel and added the workbook Calculate trigger in the VBA code, so as to avoid updating the workbook entirely every time there is a paste action.
Could someone advise if directly setting the cells in the wb = the cells in the master data would speed up or slow down the code? Or could someone suggest a more efficient way of loading data?
I appreciate your effort before you send in your responses.
As said in the comments, not using .Select improves the speed of your macro. Also, copy paste actions are indeed more slow whith VBA and you should do assignations FromWorksheet.Range("CopyRange").Value = ToWorksheet.Range("PasteRange").Value. Also, it always helps to add these lines in the beginning:
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
Application.DisplayAlerts = False
and reactivating them at the end:
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.DisplayStatusBar = True
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
There are many information on this, like this link

How to stop automatic recalculation in excel

In the excel sheet pictured below I would like the recalculation to stop for the top portion from Row 1-5. And what I mean with recalculation is that for example cell M2, H4, S4 have the today() formula and every time I open it it recalculates. I would like for it to calculate once and once I save as to not recalculate again once opened again. Any suggestions? I have tried
Private Sub Workbook_Open()
Application.Calculation = xlCalculationManual
End Sub
Well, setting Application.Calculation = xlCalculationManual at the time of Workbook_Open may not always assure you the desired result as there is a possibility that the Excel might be in xlCalculationAutomatic while opening your file.
So the workaround is, open Excel and set calculation to manual either in VBE or through menus and then open your file.
In VBE, type Application.Calculation = xlCalculationManual in immediate window then hit Enter and then open your file.
In Excel, for 2007 version, click on Formula Menu, go to Calculation Group, in Calculation Options select Automatic/Manual. For older versions, Tools > Options > Calculation.
I don't have the reputation to post a comment to ask a clarifying question, so I will post an answer instead (making an assumption about what your answer would be).
As long as you never want those cells to recalculate (and don't mind losing the formula), the easiest solution would be to convert them to values.
simple macro to achieve this for first 5 rows:
sub ConvertToValues()
Dim rngToValues as Range
set rngToValues = YourSheet.UsedRange.Rows("1:5").EntireRow
rngToValues.Value = rngToValues.Value
end sub
I would suggest evaluating the function in VBA on events you want.
If you want TODAY function to calculate on your request, I would create a button with a macro that reevaluates TODAY.
How I would implement this depends on if you want/need to have the cell as a formula.
If it is enough to have the calculated value, you can calculate in VBA and set the value to the cells you want.
If you want to have a formula and keep the last evaluated TODAY value, you can set the formula to the cell.
Range("M2").Formula = Date() & "other formula part"
The easiest solution is to set todays value in some cell, in VBA
Sub Macro1 ()
Range("A5").Value = Date()
End Sub
I would suggest to add the below subroutine under Workbook_Open in PERSONAL.XLSB (to be saved at %APPDATA%\Microsoft\Excel\XLSTART) so that it gets loaded whenever Excel application is launched.
Private Sub Workbook_Open()
Application.Calculation = xlCalculationManual
Application.CalculateBeforeSave = False
End Sub
While Application.Calculation = xlCalculationManual will set the calculation mode to Manual (3rd Option in the below screenshot), Application.CalculateBeforeSave = False will untick the checkbox to Recalculate workbook before saving

Closing a userform that is in workbook A from workbook B

I'm new to VBA so there might be a simple answer to this question but if there is I sure haven't found it. What I am doing is copying data from several workbooks into one master workbook. I have writen the code for this and it works fine. The only problem is the workbooks where I'm retriving the data have userforms that automatically initiate when the workbook is accesed. This means that when I run my code to copy the data it hangs at each userform and wont continue until I've physically closed each userform. So my question is: Is there a way to remotely close the userforms in the raw data workbooks from my master workbook VBA code? Thanks in advance.
to close all userforms, (if you want a specific one , change my code)
sub Close_Userforms()
Dim Form as VBA.Userform 'if not work change to Object
For each Form in VBA.Userform
'can add a condition, like : if Form.name ="Whatever" then
unload Form 'if you don't want to lose the data from the userforms, Form.Hide, and later re-loop and Form.Show
next Form
edit : can also if Typename (Form)="Whatever" then , for the condition
Assuming you mean that the forms pop up when you open the workbooks, disable events before doing so:
Application.Enableevents = False
Workbooks.Open ...
Application.Enableevents = True
for example.
I would suggest trying
Application.EnableEvents = False
Further reading.
Short description: All events (Workbook_Open, Workbook_BeforeSave etc), that usually fires upon opening or closing a workbook, will be ignored.
I have written the following functions to make all macros a bit simpler (and faster). Simply place these functions in a regular module.
Public Function CalcOff()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.EnableEvents = False
End Function
Public Function CalcOn()
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Function
Begin your macro with:
CalcOff
And then end your macro with:
CalcOn
Remember that you need to put "CalcOn" in all places that exits the running macro.
Disabling ScreenUpdating makes the code "run in background" (nothing will be displayed).
Setting Calculation to manual improves the speed of the code, since no calculations will be made when changing data. But it's very important to exit all macros with "CalcOn", otherwise your sheet won't calculate (and that's not funny), and it will look like Excel has frozen (since ScreenUpdating would still be turned off).
However, if you by any chance happen to break a running code without exiting it the proper way (running "CalcOn"), simply close the Excel application and reopen it. Or run a macro that ends with the "CalcOn" code. Or create a new macro with that simple line.

VBA Table Refreshing

I'm creating a worksheet in Excel that is connected to an online database. I made a function that checks if new information has been posted and updates the worksheet accordingly. If there is a new release, I update all the column headings to make room for it using a loop.
My problem is that the function takes forever to run since the table refreshes itself each time I change the column headings.
I'm wondering is there is a way to pause the refresh so the table only refreshes itself once at the end of the vba script.
Thanks. I appreciate your help.
To stop formulas from refreshing whilst the code executes, you can use Application.Calculation like so:
Public Sub SomeProcedure()
Application.Calculation = xlCalculationManual
'Code goes here
Application.Calculation = xlCalculationAutomatic
End Sub
This will stop the formulas refreshing until the code in the middle has executed.

Recursive call on the worksheet change in VBA

I have created the workbook with multiple sheet, i am trying to use WorkSheet_Change on Sheet1, i.e. something change on sheet1 is getting copied to sheet2. Similarly if anything change to Sheet2 i want to make similiar change on Sheet1 as well.
On doing so there is recursive call on both sheet please let me know how i can avoid this.
you should disable events when calling your macro:
Sub Donot_Fire_Events()
Application.EnableEvents = False
' Coding to skip these events
Application.EnableEvents = True
End Sub
Put a new global variable in a Module and call it bAutoUpdating As Boolean for example.
When the _Change code runs it should set this to true. Also any change routine should not fire if this is true. At the end of each _Change routine set back to bAutoUpdating = false