I have a code to set a timer of 5 minutes on my userform. It works when I press the command button.
How do I make it run automatically at the start ? I tried in ThisWorkbook but it didn't worked.
here's the code :
In a module:
Public Const AllowedTime As Double = 1
In the Userform:
Private Sub CommandButton1_Click()
Dim userClickedPause As Boolean ' Gets set to True by the Pause button
Dim stopTime As Date
userClickedPause = False
' If AllowedTime is the number of minutes with a decimal part:
stopTime = DateAdd("s", Int(AllowedTime * 600), Now) ' add seconds to current time
' If AllowedTime is the number of seconds:
'stopTime = DateAdd("s", AllowedTime, Now) ' add seconds to current time
Do
With UserForm1.TextBox1
.Value = Format(stopTime - Now, "Nn:Ss")
End With
DoEvents
If userClickedPause = True Then
Exit Do
End If
Loop Until Now >= stopTime
End Sub
Private Sub CommandButton2_Click()
userClickedPause = True
End Sub
I would recommend you to re-structure your code. Since you want to call your StartTimer sub from both a UserForm and the Workbook_Open event, put it into a module.
Then you simply call the sub from your Commandbutton1_Click event and the Workbook_Open event.
'Put this code inside ThisWorkbook
Private Sub Workbook_Open()
'This sub into ThisWorkbook
Application.Run "SetTimer"
End Sub
'This sub goes into a module
Private Sub SetTimer()
'Here goes your code that sets the timer
'(move it from your UserForm)
'.......................................
'.......................................
End Sub
'The code inside your UserForm
Private Sub CommandButton1_Click()
Application.Run "SetTimer"
End Sub
Related
It appears that if the OnTime event is registered by a programmatic MyBook.Close statement, then OnTime never runs.
This code works fine:
Sub TestOnTime()
Application.OnTime Now + TimeValue("00:00:05"), "MySub"
End Sub
Sub MySub()
Debug.Print "hello"
End Sub
Run TestOnTime. MySub will execute, as expected.
And this code runs fine:
ThisWorkbook:
Dim WithEvents oApp As Application
Private Sub Workbook_Open()
Set oApp = Application
End Sub
Private Sub oApp_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
Application.OnTime Now + TimeValue("00:00:05"), "MySub"
End Sub
Module 1:
Sub MySub()
Debug.Print "hello"
End Sub
Manually close another workbook to fire oApp_WorkbookBeforeClose.
MySub executes, as expected.
But this code fails. The OnTime event never runs.
Book 1
ThisWorkbook:
Dim WithEvents oApp As Application
Private Sub Workbook_Open()
Set oApp = Application
End Sub
Private Sub oApp_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
Application.OnTime Now + TimeValue("00:00:05"), "MySub"
End Sub
Module 1:
Sub MySub()
Debug.Print "hello"
End Sub
Book 2
Module 1:
Sub Test()
ThisWorkbook.Close
End Sub
Run Test to close Book 2.
Book 1 oApp_WorkbookBeforeClose
executes, as expected.
But the Book 1 MySub event never runs.
Why?
Why doesn't OnTime execute if registered by a Workbook_BeforeClose event? No code is running in the book that's closing. OnTime works no problem with other events (eg programmatically opening a workbook). Somehow, closing a workbook programmatically breaks OnTime. Why?
As Book 2 is being closed, You should include the Application.OnTime procedure in Book 2 and not in Book 1
Also, I think those books should be saved once and not new books.
Sub test()
Application.OnTime Now + TimeValue("00:00:05"), "Book 1.xlsm!MySub"
ThisWorkbook.Close
End Sub
EDIT Jul 6 -
You are closing the workbook and then you are trying to run a macro MySub in the same workbook after 5 seconds. Macro in the same workbook will not run once the book is closed. Application will reopen the file to run the macro. If you want to close Book2 after 5 seconds of closing Thisworkbook then --
in Thisworkbook
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.OnTime Now + TimeValue("00:00:05"), "Book2.xlsm!Test"
End Sub
So, after closing Thisworkbook, macro named "Test" in Book2 will run and will close that workbook.
There are a lot of tutorials in the Internet. However I was not able to find anything suitable. Is there any way to make animated dots on loading?
The idea is to make a loop of animated dots ..... on userform so they would appear one after another and then would start over after some amount of dots.
So I input a dot to Label1 and move it to left after certain time criteria?
My current code for UserForm:
Private Sub UserForm_Initialize()
HideTitleBar.HideTitleBar Me
Call loadingdots
End Sub
Code for Private Sub Workbook_Open():
Loading.Show (vbModeless)
Dim RngCom As Range
Dim RngTurb As Range
Dim RngGen As Range
Application.Wait (Now + TimeValue("00:00:06"))
ThisWorkbook.Worksheets("MAIN").ScrollArea = "$A$1:$BL$45"
Application.DisplayFormulaBar = False
ActiveWindow.DisplayHeadings = False
ActiveWindow.DisplayGridlines = False
etc...
Unload Loading
'Application.ScreenUpdating = True
End Sub
The most elegant solution would likely to be the OnTime method.
Place a label inside your UF and remove the caption. Next, in a regular module (so not that of the UF), place this subroutine:
'this function ensures the self-activating sub will stop if the UF has been closed
Public Function IsLoaded(form As String) As Boolean
Dim frm As Object
For Each frm In VBA.UserForms
If frm.Name = form Then
IsLoaded = True
Exit Function
End If
Next frm
IsLoaded = False
End Function
Public Sub loadingdots()
If IsLoaded("UserForm1") = True Then
If Len(UserForm1.Label1.Caption = 4) Then
UserForm1.Label1.Caption = "."
Else
UserForm1.Label1.Caption = UserForm1.Label1.Caption & "."
End If
Application.OnTime Now + TimeValue("00:00:01"), "loadingdots"
End If
End Sub
Next, call the self-activating sub when the UF gets initialised
Private Sub UserForm_Initialize()
Call loadingdots
End Sub
Do not forget to change the references to the UF to the right name.
I have built a small 5 minute Countdown in a UserForm.
The countdown should count down. But if the UserForm is closed, the macro should stop and the timer should be reset.
In the UserForm's Terminateevent I have stored the call of my own abort function. This terminates the UserForm, but the timer continues to run in the background and the corresponding macro is always brought to the foreground.
How can the code be modified to stop the timer when the UserForm is closed?
Module 1
Dim Count As Date
Sub callBreak()
Break.Show
End Sub
Sub Time()
Count = Now + TimeValue("00:00:01")
Application.OnTime Count, "minus"
End Sub
Sub minus()
Dim y As Date
y = Break.Label1.Caption
y = y - TimeSerial(0, 0, 1)
Break.Label1.Caption = y
If y <= 0 Then
Break.Label1.Caption = "Arbeit, Arbeit!"
Exit Sub
End If
Call Time
End Sub
Sub abord()
End
End Sub
Userform:
Sub UserForm_Initialize()
Call Coffeebreak.Time
End Sub
Sub UserForm_Terminate()
Call Coffeebreak.abord
End Sub
You can cancel a previously scheduled procedure by setting the optional Schedule argument of Application.OnTime to False. Try this as your Abord() function:
Sub Abord()
Application.OnTime EarliestTime:=Count, Procedure:="minus", Schedule:=False
End Sub
One solution:
in your module, define a global boolean variable, eg isCancelled. Set this variable to true in abort and check it in minus to prevent that the timer is called again.
Dim Count As Date
Dim isCancelled as Boolean
Sub Time()
isCancelled = False
Count = Now + TimeValue("00:00:01")
Application.OnTime Count, "minus"
End Sub
Sub minus()
if isCancelled Then Exit Sub
(...)
End Sub
Sub abort()
isCancelled = True
End Sub
Found some tips here and in google, but can't implement properly.
Say I have a loop that runs, and I need to show a box with a button "Cancel".
The code must run till I press the button.
In the following example I used For Loop and show iteration number in the Label1.Caption
' action of UserForm1 on Button Click
Private Sub CommandButton1_Click()
cancel = True
End Sub
Public cancel as boolean
Sub example ()
cancel = False
Dim i As Integer
For i = 1 To 1000
Application.Wait (Now + #12:00:01 AM#)
UserForm1.Label1.Caption = CStr(i)
UserForm1.Show vbModeless
If cancel = True Then
Exit For
End If
Next i
End Sub
This code runs, but it doesn't react on Button click.
If I do UserForm1.Show vbModal, then the code stops and waits till I click the button.
What am I doin wrong?
This is my code and it works perfectly when the userform is opened with frmTest.Show false
Dim cancelbool As Boolean
Function loopfunction()
Dim i As Integer
i = 0
Do Until cancelbool
DoEvents
Me.lblIteration.Caption = i
i = i + 1
Loop
End Function
Private Sub cmdCancel_Click()
cancelbool = True
End Sub
Private Sub UserForm_Activate()
loopfunction
End Sub
And by the way, the Application.Wait makes your app unresponsive
I want to show a message 20 seconds after opening the Excel workbook. Code is:
//ThisWorkbook
Private Sub Workbook_Open()
SetTimer
End Sub
//Module1
Public Sub SetTimer()
Application.OnTime Now + TimeValue("00:00:20"), "ShowMsg"
End Sub
Public Sub ShowMsg()
MsgBox ("my message")
End Sub
As you see, code is very simple and it works when user don't update sheet or when they leave updated/focused cell. However, if cursor remains at cell the message will never be shown. It seams that control doesn't return to VBA code while a cell has focus or is updating. Any idea for this issue? Thanks
Here's a workaround:
Sub main()
Dim start As Single
start = Timer
Do
DoEvents
Loop Until Timer > (start + 20) '20 seconds
MsgBox "hello"
End Sub
Edit. Code for further question:
In a module called Module1, enter the following code:
Public start As Single
Sub main2()
start = Timer
Do
DoEvents
Loop Until Timer > (start + 20) '20 seconds
MsgBox "hello"
End Sub
In your ThisWorkbook object (double click on ThisWorkbook from the list of objects in the Project Explorer) enter the following code:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Module1.start = Module1.start + 5
End Sub
Every time any cell in any worksheet in the workbook is changed, another five seconds is added to the timer.