button flickering despite Application.screenupdating = false - excel

so I tried the solutions here Excel ScreenUpdating False and still flickering screen but nth worked , im wondering if I should put the screen update in the fucntion I call
Note that the function i call is gonna call another that'll parse data in the sheet once button 2 is clicked,Here's the code I did so far
Private Sub CommandButton2_Click()
Application.ScreenUpdating = False
ButtonOneClick = False
Call SheetName
If ButtonOneClick Then
Me.CommandButton2.Visible = True
Else
Me.CommandButton2.Visible = False
End If
Application.ScreenUpdating = True
End Sub

Related

Rerun a macro when a combobox value in a userform is changed

I have a userform with a combobox to select the training type for various employee classes.
When the user selects one of the options from the dropdown menu it runs the macro below.
Private Sub TrainingType_Selection_Change()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlCalculationManual
Dim TrainingType_Selection As String
TrainingType_Selection = Hiring_Validation_Form.TrainingType_Selection.Value
If TrainingType_Selection = "Sustain - 30" Or TrainingType_Selection = "Sustain - 60" Then
Hiring_Validation_Form.LinkingECPID_Selection.Visible = True
Hiring_Validation_Form.LinkingECP_Label.Visible = True
End If
If TrainingType_Selection <> "New Hire" Then
Hiring_Validation_Form.ReqReasonLv1_Selection.Visible = False
Hiring_Validation_Form.Label6.Visible = False
Hiring_Validation_Form.ReqReasonLv2_Selection.Visible = False
Hiring_Validation_Form.Label11.Visible = False
End If
End Sub
The problem I'm running into is that if someone makes a selection from the drop-down menu and then changes their mind and selects another value from the drop-down menu it isn't re-running the macro. For example they change it from the above "New Hire" to "Sustain - 30". I have a clear button on the userform, but that clears the entire form which would not be ideal in a situation where the user only wants to change one input, not completely start over.
How do I get the TrainingType_Selection_Change() macro to re-run again when the combobox selection is changed
This line:
Application.ScreenUpdating = False
disables screen updates even after the macro has finished running.
Add
Application.ScreenUpdating = True
as the last line before End Sub to re-enable them.
I was able to figure out a way to address this issue by using AfterUpdate()
I added the below macro and it now updates the entire form when selections are changed.
Private Sub TrainingType_Selection_AfterUpdate()
TrainingType_Selection = Hiring_Validation_Form.TrainingType_Selection.Value
Hiring_Validation_Form.LinkingECPID_Selection.Visible = False
Hiring_Validation_Form.LinkingECP_Label.Visible = False
Hiring_Validation_Form.ReqReasonLv1_Selection.Visible = True
Hiring_Validation_Form.Label6.Visible = True
Hiring_Validation_Form.ReqReasonLv2_Selection.Visible = True
Hiring_Validation_Form.Label11.Visible = True
Hiring_Validation_Form.Label21.Visible = True
Hiring_Validation_Form.NewHireSup_Selection.Visible = True
Call TrainingType_Selection_Change
End Sub

How can I make this code more efficient so that it runs quicker?

I am attempting to hide rows so that only a certain retailers data is shown, the data is not filterable due to the layout of the report. I start by just unhiding all rows as a reset and then manually hide rows that aren't relevant to a retailer until only the clicked retailers info remains.
However this is a slow way of doing this, and I need a quicker way I can understand. There is no criteria to filter the data. Just the retailer name on a click button.
My code shows the manual slow way of doing this.
Sub SummaryRetailer1Only()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
'Resets hidden rows by showing everything.
ActiveSheet.Rows("2:480").EntireRow.Hidden = False
'Hides all rows that don't show data for Retailer1.
ActiveSheet.Rows("18:21").EntireRow.Hidden = True
ActiveSheet.Rows("37:48").EntireRow.Hidden = True
ActiveSheet.Rows("54:57").EntireRow.Hidden = True
ActiveSheet.Rows("73:84").EntireRow.Hidden = True
ActiveSheet.Rows("88:129").EntireRow.Hidden = True
ActiveSheet.Rows("261:376").EntireRow.Hidden = True
ActiveSheet.Rows("390:393").EntireRow.Hidden = True
ActiveSheet.Rows("409:420").EntireRow.Hidden = True
ActiveSheet.Rows("424:427").EntireRow.Hidden = True
ActiveSheet.Rows("443:454").EntireRow.Hidden = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
The code works fine I just want a way that I assume uses some variables so that it runs quicker.
Another way:
Option Explicit
Sub SummaryRetailer1Only()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With ThisWorkbook.Worksheets("Sheet1") '<- It s better to create a with statement with the sheet you want to use insead of activesheet
'Resets hidden rows by showing everything.
.Rows("2:480").EntireRow.Hidden = False
'Hides all rows that don't show data for Retailer1.
Union(.Rows("18:21"), .Rows("37:48"), .Rows("54:57"), .Rows("73:84"), .Rows("88:129"), .Rows("261:376"), _
.Rows("390:393"), .Rows("409:420"), .Rows("424:427"), .Rows("443:454")).EntireRow.Hidden = True
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

Application.OnTime reopens workbook when other workbook is open

I have a timer that closes my workbook after 5 minutes. The issue is when i have another workbook open the workbook with the timer will reopen when i try to close it.
Earlier i had the countdown to "tick" every second but that messed up the view of comments making them blink for every countdown tick. When i had that I didn't see any issues with reopening of the workbook.
I have this in both my module and thisworkbook
Public gCount as Date
These two codes are in my module. The timer is displayed in a cell
(Worksheets("kode").Range("H3")) and counts down every 10 seconds
Sub Timer()
gCount = Now + TimeValue("00:00:10")
Application.OnTime gCount, "ResetTime"
End Sub
Sub ResetTime()
Dim xRng As Range
If ThisWorkbook.Worksheets("kode").Range("H3") = "" Then GoTo Endsub
Set xRng = Application.ThisWorkbook.Worksheets("kode").Range("H3")
xRng.Value = xRng.Value - TimeSerial(0, 0, 10)
If xRng.Value <= 1.15740740740741E-05 Then
Call SavedAndClose
Exit Sub
End If
Call Timer
Endsub:
End Sub
This code is in ThisWorkbook
Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error Resume Next
gCount = Now + TimeValue("00:00:10")
Application.OnTime gCount, "ResetTime", Schedule:=False
ThisWorkbook.Worksheets("Interface").Select
'Hides all sheets but the interface sheet
Sheet2.Visible = False
Sheet3.Visible = False
Sheet6.Visible = False
Sheet7.Visible = False
Sheet8.Visible = False
End Sub
There too is a place where the cell Worksheets("kode").Range("H3") is set to 00:05:01 and a Workbook_SheetSelectionChange where it resets it to 00:05:01
The sheet closes when Worksheets("kode").Range("H3") is at 00:00:01
If i remove the "On Error Resume Next" the code makes a 1004 run-time error when i try to close the workbook.
Hope that someone can help me close my workbook
Best regards
If i remove the "On Error Resume Next" the code makes a 1004 run-time error when i try to close the workbook.
And that is why you should not put On Error Resume Next everywhere to silence errors instead of fixing them.
Application.OnTime can schedule the same procedure multiple times for different times of day. For this reason, it can only unschedule a previously scheduled entry when you provide the exact time for which it was scheduled - if you provide a time for which there is no scheduled entry, you will get a runtime error 1004.
Now + TimeValue("00:00:10") returns a different value each time you call it.
If you want to be able to cancel a previously set entry, store the time in a module-level variable and use that variable for both scheduling and unscheduling. Your module-level gCount variable would do, but:
You have two of them ("I have this in both my module and thisworkbook")
You overwrite the previously stored value with a useless new one right before calling Schedule:=False.
Make sure you only have one gCount, and only assign to it before scheduling a call, not before unscheduling it.
I found an answer to my own comment to GSergs answer:
I made a Msgbox with vbYesNoCancel options and canceled the OnTime event in the Yes and No answer and work around the generic "Save changes" prompt in excel. If Cancel is pressed the macro will cancel.
The "If xRng.Value <= 1.15740740740741E-05 Then" in the beginning insures that if the timer has run out it skips the MsgBox and just saves.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Set xRng = Application.ThisWorkbook.Worksheets("kode").Range("H3")
If xRng.Value <= 1.15740740740741E-05 Then
Application.ScreenUpdating = False
ThisWorkbook.Worksheets("Interface").Select
'Hides all sheets but the interface sheet
Sheet2.Visible = False
Sheet3.Visible = False
Sheet6.Visible = False
Sheet7.Visible = False
Sheet8.Visible = False
Application.OnTime gCount, "ResetTime", Schedule:=False
If ThisWorkbook.Saved = False Then
ThisWorkbook.Save
End If
Application.ScreenUpdating = True
GoTo Endsub
Else
End If
Dim intValue As Integer
intValue = MsgBox("Do you want to save changes?", 3, "Save changes?")
If intValue = 6 Then
Application.ScreenUpdating = False
ThisWorkbook.Worksheets("Interface").Select
'Hides all sheets but the interface sheet
Sheet2.Visible = False
Sheet3.Visible = False
Sheet6.Visible = False
Sheet7.Visible = False
Sheet8.Visible = False
Application.OnTime gCount, "ResetTime", Schedule:=False
If ThisWorkbook.Saved = False Then
ThisWorkbook.Save
End If
Application.ScreenUpdating = True
ElseIf intValue = 7 Then
Application.ScreenUpdating = False
ThisWorkbook.Worksheets("Interface").Select
'Hides all sheets but the interface sheet
Sheet2.Visible = False
Sheet3.Visible = False
Sheet6.Visible = False
Sheet7.Visible = False
Sheet8.Visible = False
Application.OnTime gCount, "ResetTime", Schedule:=False
ThisWorkbook.Saved = True
Application.ScreenUpdating = True
Else
Cancel = True
End If
End Sub
Hope it can help someone with the same issue.
Best regars
Søren

How Do I Disable a VBA Sub Using Another Sub

I have a workbook that is designed to essentially operate as a standalone application. All sheets are protected, the individual excel tabs are hidden, and the top excel ribbon is hidden as well for the entire workbook.
The following VBA code performs the above procedures and is applied to every sheet within the workbook.
Sub masque()
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.ExecuteExcel4Macro "SHOW.TOOLBAR(""Ribbon"",False)"
ActiveWindow.DisplayHeadings = False
ActiveWindow.DisplayGridlines = False
ActiveWindow.DisplayWorkbookTabs = False
Application.DisplayFullScreen = True
Application.DisplayStatusBar = Not Application.DisplayStatusBar
Application.WindowState = xlMaximized
ActiveWindow.WindowState = xlMaximized
Application.DisplayFormulaBar = False
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
I want to use the following code as a button to override the prior code in order for an individual to easily switch between an "editor" mode and "user mode"
Sub masteredit()
Application.ScreenUpdating = False
ActiveWindow.View = xlNormalView
ActiveWindow.DisplayHeadings = False
ActiveWindow.DisplayGridlines = False
ActiveWindow.DisplayWorkbookTabs = False
Application.DisplayStatusBar = False
ActiveWindow.DisplayHorizontalScrollBar = True
ActiveWindow.DisplayVerticalScrollBar = True
ActiveWindow.DisplayWorkbookTabs = True
Application.DisplayFullScreen = False
Application.DisplayFormulaBar = True
Application.ExecuteExcel4Macro "SHOW.TOOLBAR(""Ribbon"",True)"
Application.ScreenUpdating = True
What is a good way to accomplish this?
well, you could have a predermined type of user, for example, by default the app will be for user_mode. So you use a special sub called auto_open(), that will be run each time you open the workbook. So we have
sub auto_open()
call masque
end sub
And you can add buttons whenever you want to change between editor mode and user mode. You can put sub auto_open() in any module you want, because it is detected as special by Vba
Solved the issue.
I forgot I had the following code on every sheet in the workbook.
Sub Worksheet_Open()
Call masque
End Sub
Sub Worksheet_Activate()
Application.ScreenUpdating = False
Call masque
Application.ScreenUpdating = True
End Sub
Therefore, any time I tried to navigate to a different sheet, the masque would be applied.
To solve my issue, I removed the prior code from every page. I then added a checkbox on my "Home" page that used the following code.
Sub Worksheet_Open()
Call masque
End Sub
Sub Worksheet_Activate()
Application.ScreenUpdating = False
Call masque
Application.ScreenUpdating = True
End Sub
This way, when you open up the workbook the masque is automatically applied. However when you click the checkbox you enter editor mode and the masteredit sub is applied. And when it is unchecked, the masque is once again applied.

excel vba slowing excel down, causing 10 second egg timer delay when clicking anywhere on sheet

I am using the following vba codes which im using to hide a set of rows and unhide rows depending on if a cell contains text or not, and they are causing my excel spreadsheet to be slow and unresponsive and causing the egg timer to show for about 10 seconds.
If I take the code out It speeds things up so what can I do to my codes to get them to speed up and not take so long? perhaps there is a better way of structuring the code but im really new to vba so am not sure what I would need to do, would appreciate someone's help thanks.
the reason I am using worksheet change and worksheet selection change is so that whether a user clicks on a cell or not the page still updates
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("K22").Value <> "" Then
Application.ScreenUpdating = False
Rows("25:38").EntireRow.Hidden = False
Rows("40:48").EntireRow.Hidden = True
ElseIf Range("K22").Value = "" Then
Rows("25:38").EntireRow.Hidden = True
Rows("40:48").EntireRow.Hidden = False
End If
Application.ScreenUpdating = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Range("K22").Value <> "" Then
Application.ScreenUpdating = False
Rows("25:38").EntireRow.Hidden = False
Rows("40:48").EntireRow.Hidden = True
ElseIf Range("K22").Value = "" Then
Rows("25:38").EntireRow.Hidden = True
Rows("40:48").EntireRow.Hidden = False
End If
Application.ScreenUpdating = True
End Sub
The main issue is from the Worksheet_Change event, but it could be applied to any event.
The worksheet change is triggering each time you hide a column, so it's trying several times to hide the same columns, before (eventually) failing with an out of memory error:
Hide these columns... Oh, a worksheet change... Hide these columns... Oh, A worksheet change... Hide th...
To avoid this, you need to use
Application.EnableEvents = False
when you decide you are going to make changes, and
Application.EnableEvents = True
when done.
You may also want to put some error handling that turns the events on again, as if something else occurs that stops the code from running, the triggers will be turned off, and the spreadsheet will no longer update as you expect it to.
Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
Application.EnableEvents = False
If Range("K22").Value <> "" Then
Rows("25:38").Hidden = False
Rows("40:48").Hidden = True
Else
Rows("25:38").Hidden = True
Rows("40:48").Hidden = False
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
This works instantly for me:
Application.ScreenUpdating = False
Select Case Range("K22")
Case Is <> ""
Rows("25:38").Hidden = False
Rows("40:48").Hidden = True
Case Else
Rows("25:38").Hidden = True
Rows("40:48").Hidden = False
End Select
Application.ScreenUpdating = True

Resources