Sub produces 'flashing' effect with ScreenUpdating turned off - vba

I'm using the following code (reduced to relevant parts for simplicity):
Sub deleteCategory()
Application.ScreenUpdating = False
Sheets("Recurring Expenses").Activate
'A bunch of stuff is checked and done on the now activated sheet
Sheets("Input").Activate 'This is the sheet the sub is called from via a button
Application.ScreenUpdating = True
End Sub
Although Application.ScreenUpdating is turned off, every time you click the button and the macro runs (otherwise bug-free) you can clearly see the Sheet "Recurring Expenses" briefly flash for a moment.
Any idea what causes this or how it could be fixed?

Try using With statement:
Sub deleteCategory()
With Excel.Application
.ScreenUpdating = False
.EnableEvents = False
End With
With Workbooks("your_workbook_name").Sheets("Recurring Expenses")
' do stuff like
' .copy
' .cells.select
End With
'A bunch of stuff is checked and done on the now activated sheet
With Workbooks("your_workbook_name").Sheets("Input") 'This is the sheet the sub is called from via a button
' Do stuff
End With
With Excel.Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Hope this help you.

Related

When I use a button to run a macro the excel can't complete it because of few memory

My macro set the values of a block of cells to 1 later it sets some of these cells to 0 based on the daily conditions (5232 cells total). I would like to put this macro behind a button, if I run it through the button I got the error message immediately.
Excel cannot complete this task with available resources.
Choose less data or close other applications.
Private Sub CommandButton1_Click()
Dim atado As String
Dim LastRow As Long
Dim i As Long
Dim j As Long
Dim elsoora As Long
Dim utolsoora As Long
Sheets("Maszk").Select
Range("C4", Range("HL4").End(xlDown)).Value = 1
(...)
End Sub
The code is trying to set values of 228 million cells (probably). This is quite a lot, see yourself. It is a good idea always to refer to the correct worksheet in VBA, otherwise you can get various errors.
Sub TesteMe()
With Worksheets("SomeName")
MsgBox .Range("C4", .Range("HL4").End(xlDown)).Cells.Count
End With
End Sub
However, you can upgrade it a bit, by turing the Application.ScreenUpdating off. Like this: Application.ScreenUpdating = False at the beginning of the code and Application.ScreenUpdating = True at the end of the code.
Are there any formulas pointing to that range? If yes, the re-calculation probably causes the memory issue. Set calculation to manual and stop screen updating.
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
'run your code here
With Worksheets("Maszk") 'fully qualify your range
.Range("C4", .Range("HL4").End(xlDown)).Value = 1
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Note that you always need to qualify your range to be in a specific worksheet, otherwise Excel might take the wrong worksheet. Therefor use a With statement and start your ranges with a dot. Or qualify each range like Worksheets("YourSheetName").Range(…)
There are several things you can "switch off" to speed up code processing - ScreenUpdating, EnableEvents, Calculation. I (re)use this particular routine:
Sub xlQuiet(Optional ByVal bQuiet As Boolean, Optional ByVal sStatusMessage As String)
On Error GoTo Terminate
With Application
.ScreenUpdating = Not bQuiet
.EnableEvents = Not bQuiet
.DisplayAlerts = Not bQuiet
.StatusBar = bQuiet
If bQuiet Then
.Calculation = xlCalculationManual
If Not sStatusMessage = "" Then .StatusBar = sStatusMessage
Else
.Calculate
.Calculation = xlCalculationAutomatic
DoEvents
End If
End With
Terminate:
If Err Then
Debug.Print "Error", Err.Number, Err.Description
Err.Clear
End if
End Sub
Then I call at the start / end of other routines, like this:
Sub foo()
xlQuiet True
With Sheets("Maszk")
.Range("C4", .Range("HL4").End(xlDown)).Value = 1
End With
xlQuiet False
End Sub
Edit: note the way that the range objects are qualified to the stated sheet - so the active / selected sheet becomes irrelevant.
You could write the 1s one row at a time:
Application.ScreenUpdating = False
For Each rw In Range("C4", Range("HL4").End(xlDown)).Rows
rw.Value = 1
Next
Application.ScreenUpdating = True

calculations are not disabled on the opening of the workbook, although calculations are set to manual

Dear community members,
We have disable the calculations in the workbook through below macro:
Private Sub Workbook_Open()
ActiveSheet.EnableCalculation = False
If Application.Calculation <> xlCalculationManual Then
Application.Calculation = xlManual
Else
End If
End Sub
But still when the workbook opens ,it calculates the formulas and takes some time to open. I ideally want to open the workbook without any initial calculations.
I tried the below code but it is not giving satisfactory results.
is there a ideal way to disable all the calculations??
Private Sub Workbook_Open()
ActiveSheet.EnableCalculation = False
Application.EnableEvents = False
Application.EnableEvents = True
If Application.Calculation <> xlCalculationManual Then
Application.Calculation = xlManual
Else
End If
End Sub
Would really appreciate you help on this.

changing sheet with macro causes sheet to freeze

My macro for changing sheets doesn't work anymore after I created a few UserForms. Thought the problem was the UserForms were not unloading properly but that doesn't seem to be the case.
When I click the button (which resides in a custom pop up menu) to go to another sheet it works but the sheet acts frozen, I can't scroll or highlight for example.
But if i change sheets by clicking on the tabs then everything is fine. So it would appear that my code to active another sheet is faulty.
My excel workbook has some UserForms, Worksheet_Change and Worksheet_SelectionChange events if that matters.
Is there a better way of doing this. Something that will obviously work and note freeze my sheet after it is activated?
Sheet goto Code:
Sub goto630()
Application.ScreenUpdating = False
Dim sht2 As Worksheet
Set sht2 = ThisWorkbook.Worksheets(2)
Dim sht3 As Worksheet
Set sht3 = ThisWorkbook.Worksheets(3)
sht3.Activate
sht3.Protect _
DrawingObjects:=False, _
Contents:=True, _
Scenarios:=False, _
UserInterFaceOnly:=True, _
AllowFormattingCells:=True
sht2.Visible = True
sht3.Visible = True
On Error GoTo 0
ActiveWindow.Zoom = 90
ActiveWindow.DisplayHeadings = True
ActiveWindow.DisplayHorizontalScrollBar = True
ActiveWindow.DisplayVerticalScrollBar = True
Application.DisplayFormulaBar = True
sht3.DisplayPageBreaks = False
ThisWorkbook.Worksheets(1).Visible = False
ThisWorkbook.Worksheets(4).Visible = False
ThisWorkbook.Worksheets(5).Visible = False
ThisWorkbook.Worksheets(6).Visible = False
ThisWorkbook.Worksheets(7).Visible = False
ThisWorkbook.Worksheets(8).Visible = False
Set sht2 = Nothing
Set sht3 = Nothing
Application.ScreenUpdating = True
End Sub
UserForm Code:
Private Sub UserForm_Click()
Application.OnTime Now + TimeValue("00:00:01"), "Finish"
Unload Me
Call Module2.ScreenRefresh
Exit Sub
End Sub
ScreenRefresh Module is just Application.ScreenUpdating = True read somewhere about this same problem that if the ScreenUpdating is in another module then when called it will fix the freeze issue.
Finish Module is activating the sheet again after the UserForm has been closed (also said to help the freeze issue).
It seems that Excel is waiting for me to click a cell before allowing me to scroll. How can I get around this?
Thanks for any help :)

How to copy and paste into another workbook using vba by timer without target workbook popping up each time?

I am copy and pasting data from workbookA to workbookB every 1 minute interval using the application.ontime method. However while I'm running this macro I am working on something different entirely on workbookC. Each time the macro runs, workbookB pops up which interferes with what I'm doing on workbookC. It can get frustrating... is there a way around this?
My code has the structure:
sub dataextract()
ThisWorkbook.Activate 'ThisWorkbook is workbookA
'copy the data
If workbookB Is Nothing Then
Set workbookB= Workbooks.Open("C:\Users\Ken\Desktop\Df.xlsx")
Else
Set workbookB= Workbooks("Df.xlsx")
End If
workbookB.Activate
'paste the data here
workbookB.Save
timer 'timer is the sub that contains the application.ontime loop
end sub
Any suggestions?
sub dataextract()
dim xl as application
dim workbookB as workbook
'ThisWorkbook.Activate 'ThisWorkbook is workbookA, unnecessary to activate workbook when you copy
'copy the data
If workbookB Is Nothing Then
set xl = new application 'create another excel application
xl.visible = false 'set the new excel application invisible
Set workbookB= xl.Workbooks.Open("C:\Users\Ken\Desktop\Df.xlsx")
Else
Set workbookB= xl.Workbooks("Df.xlsx")
End If
'workbookB.Activate 'unnecessary to activate workbook when you paste
'paste the data here
workbookB.Save
timer 'timer is the sub that contains the application.ontime loop
end sub
You have two options to stop the flashing, using the below function, turn off screen updating (the function includes a few other things too, but don't forget to turn it back on).
Sub SetEvents(ByVal State As Boolean)
With Excel.Application
.ScreenUpdating = State
.EnableEvents = State
If State = True Then .Calculation = xlCalculationAutomatic Else .Calculation = xlCalculationManual
End With
End Sub
Or stop using the activeworkbook/select range method. If you define your references properly, ie.
Workbooks("Mybook.xlsx").Sheets("Sheet1").Range("A1").copy
The flashing will stop as the workbooks aren't in fact changing.
If you want to include the first option, as per your comment, add the function outside the sub and call it, as below:
sub dataextract()
setEvents False
ThisWorkbook.Activate 'ThisWorkbook is workbookA
'copy the data
If workbookB Is Nothing Then
Set workbookB= Workbooks.Open("C:\Users\Ken\Desktop\Df.xlsx")
Else
Set workbookB= Workbooks("Df.xlsx")
End If
workbookB.Activate
'paste the data here
workbookB.Save
timer 'timer is the sub that contains the application.ontime loop
setEvents True
end sub
Sub SetEvents(ByVal State As Boolean)
With Excel.Application
.ScreenUpdating = State
.EnableEvents = State
If State = True Then .Calculation = xlCalculationAutomatic Else .Calculation = xlCalculationManual
End With
End Sub

Changing value of a cell to trigger a macro

As the title suggests, I want a specific macro (PopulateCalculatorWithWeekChosen) to run whenever a user changes the value in the 'Summary' worksheet, cell H10.
I found the below question and answer and tried it but it doesn't seem to trigger it. Did I understand correctly that I put the code below...
Trigger event when select from dropdown
Sub PopulateCalculatorWithWeekChosen()
If Target.Address = "$H$10" Then
With Application
.EnableEvents = False
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
[the rest of the code in the PopulateCalculatorWithWeekChosen macro]
With Application
.EnableEvents = True
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
End If
End Sub
...in the right place?
It doesn't seem to do anything. Thanks in advance for any help.
The problem is you've defined a macro and the question/answer you reference is using the Worksheet_Change event. In your VBA code, you should have Worksheet object which has a Change event. An event is just a function that is triggered when a specific thing happens.
In this case, the function Worksheet_Change triggers whenever the worksheet is modified. You should have something like this:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$H$10" Then
With Application
.EnableEvents = False
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
With Application
.EnableEvents = True
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
End If
End Sub
When you modify the worksheet, Excel will automatically call this function and tell you which cells were modified by providing that information in the Target parameter.