Variable input for Application.ontime

chazrab

Well-known Member
Joined
Oct 21, 2006
Messages
912
Office Version
  1. 365
Platform
  1. Windows
This code is in a module and activates the timer
Code:
Sub runShowMsg()
'called from when workbook open from call runShowMsg line of code
Dim RunTimer As Date
RunTimer = Now() + TimeValue("00:00:10") 
Application.OnTime RunTimer, "ShowMsg"
End Sub

This code is in a button on the MSGINPUT userform
Code:
Private Sub CMDPOSTPONE_Click()
RunTimer = Now() + TimeValue("00:00:10")
Application.OnTime RunTimer, "ShowMsg"
Unload Me
End Sub

Code for ShowMsg
Code:
Sub ShowMsg()
Dim s As String
Dim da As Date
Dim t As String
da = Date
Dim rgFound As Range
On Error Resume Next
Set rgFound = Range("DATES").FIND(What:=da, LookIn:=xlValues)
If rgFound Then
  t = rgFound.Offset(0, 1).Value
  s = rgFound.Offset(0, 2).Value
  MSG.TextBox1.Value = s
  MSG.Show
Else
MSG.TextBox1.Value = "No opening messages today"
End If
End Sub
and just has ShowMsg appear after 10 seconds as formatted
in TimeValue("00:00:10"). Simple enough because 10 seconds is
hard coded by specifying that value in the code.

I want to be able to run ShowMsg after ANY time that I specify
using a variable for Timevalue.

There are 3 pieces of information on MSGINPUT userform within the application
that puts new data for the MsgBox in the first blank row of Sheets("DATA")
col A = 6/13/2019 or ANY date from a DTPicker
col B = a number which is the time later in the day I want ShowMsg to run
col C = any new msg I type into Textbox1 on MSGINPUT
The important thing here is the value in col B. Combobox1 has
a list of values that represent different times of the day to copy to col B.

The problem I'm having is, if I don't format these values correctly in code, they're ignored
in the Runtimer code. IT would have to be RunTimer = Now() + the correctly formatted value input from Combobox1
cell B of the first blank row on Sheets("DATA"), and not hardcoded in TimeValue("00:00:00") each time I want to change a time to run. I know this is long, but I could not make it shorter without sacrificing a clear understanding of what I'd like to accomplish.

Thanks very much for anyone's help on this.
cr
 
Re: Asking for help on a variable input for Application.ontime...

All above is 100% correct. Each time a preset msg appears, if I want, a Postpone button will send that same msg with any additions to the text to a future time of day, week or month when a future date and time is entered in d = DTPicker1.value(for the future date) and t = DTPicker1.value(for the time on the day of the future date date). The OK button closes that message as it becomes past history. A New Entry button accepts new values from DTPicker1, DTPicker2 and Textbox1 for another msg to display at a later time. The net result of all this is that multiple msgs, both new and postoponed can appear on the same or different days at different times. Hope this is yet a little clearer. Userform objecs = 1 Textbox1, 2 DTPickers(1 &2) and 3 buttons = OK, New Entry, Postpone. Thx, cr
 
Upvote 0

Excel Facts

Using Function Arguments with nested formulas
If writing INDEX in Func. Arguments, type MATCH(. Use the mouse to click inside MATCH in the formula bar. Dialog switches to MATCH.
Re: Asking for help on a variable input for Application.ontime...

Ah .... that requires a re-think on my part - sorry I must have missed something earlier.

I was gong to dump all messages with same time to the same message box
- which will obviously not work if you want to be able to postpone individual messages
- that also explains why you were trying to drive everything from your message list

Objective reassessed
Every message pops up separately at its allotted time
When it pops up the user either
- accepts with OK
- OR postpones and enters a new date and time (and a new entry is added for that item whilst retaining the old item)
- the user can also create a new item

Something I am trying to figure out is what is best way to trigger the next message to pop up
- VBA can only do one thing at a time
- I will test a couple of ideas and return tomorrow

Yongle
 
Upvote 0
Re: Asking for help on a variable input for Application.ontime...

All reassessed objectives 100% accurate. RE "what is best way to trigger the next message to pop up" = not necessary to labor over. Whether a postponed or new entry userform message pops up, the OK button is always present on either form. You'd have to click OK on the Postponed userform msg, so it will vaporize, and then click the main calling button on the QAT to show a blank new userform for a new entry.

Once the new entry userform pops up, the OK button will also cause it to close and go away. The underlying data in the userforms, be they Postponed or New Entry, is still stored in rows and columns on the DATA sheet, or whatever the sheet is named. Net net - Postponed form pops up from postponed form source once up - OK closes it or POSTPONED button pushes it foorward. Blank New Entry form pops up from QAT button - the main calling source of the app. - i.e., MSGBOX.Show = a blank New Entry userform with only ONE OK button will appear.

When the date and time for that new form pops when it's scheduled to, TWO buttons now are now visible OK to close it and POSTPONE to move it to a future date and time with any new added text. The way this would work is of course on the New Entry form POSTPONE BUTTON.visible = False; New Entry Form now appears - POSTPONE BUTTON.visible = true. As said earlier, OK will always be on both, regardless. Perhaps more clearer. Many thx, once again for all your help. cr
 
Last edited:
Upvote 0
Re: Asking for help on a variable input for Application.ontime...

You have already developed this tool much further than I realised and I have been unnecssarily solving the "whole" picture rather than trying to provide you with the bits you need to fit into what you have already done. Apologies for that.
Let's try a different approach and look at the individual pieces that you need to dovetail into what you have already got working

Getting the correct values into Application.OnTime

The simplest way - convert combobox value to time value when it is written to a cell

When cell value is formatted as time then use that value directly
Code:
    Application.OnTime Range("B2"), "MyMacro"

If the cell value is TEXT then it must be converted
If it looks like 08:00 or 20:00 etc then use CDate function
Code:
     Application.OnTime [COLOR=#ff0000]CDate([/COLOR]Range("B4")[COLOR=#ff0000])[/COLOR], "MyMacro"

Any other style of text is likely to require you create your own code to do the converting
So if using values like 8am or 8pm ...
Code:
    Application.OnTime [COLOR=#ff0000]GetTime([/COLOR]Range("B6")[COLOR=#ff0000])[/COLOR], "MyMacro"
... which calls this function (requires modifying if minutes are also required)
Code:
Function GetTime(aTime As Variant) As Date
[COLOR=#006400][I]'remove am and pm[/I][/COLOR]
    If Right(aTime, 2) = "pm" Then
        aTime = Replace(aTime, "pm", "") + 12
    Else
        aTime = Replace(aTime, "am", "")
    End If
[I][COLOR=#006400]'build string[/COLOR][/I]
    aTime = aTime & ":00:00"
[I][COLOR=#006400]'convert to time[/COLOR][/I]
    GetTime = TimeValue(aTime)
End Function

Excel 2016 (Windows) 32 bit
[Table="width:, class:head"][tr=bgcolor:#E0E0F0][th] [/th][th]
A
[/th][th]
B
[/th][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
1
[/td][td][/td][td]Time[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
2
[/td][td]Number formatted as time[/td][td]
08:00​
[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
3
[/td][td]Number formatted as time[/td][td]
20:00​
[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
4
[/td][td]String[/td][td]08:00[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
5
[/td][td]String[/td][td]20:00[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
6
[/td][td]String[/td][td]8am[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
7
[/td][td]String[/td][td]8pm[/td][/tr]
[/table]
[Table="width:, class:grid"][tr][td]Sheet: Sheet1[/td][/tr][/table]
 
Last edited:
Upvote 0
Re: Asking for help on a variable input for Application.ontime...

Please read post#14 before reading this


Has every message been dealt with?


Application.OnTime
is reliant on the macro being active at the correct time but that will not always be the case

A method is required so that VBA can identify prior messages which have not been dealt with

Suggest extra column "D" to indicate message status
- in example below : "D" = dealt with , "X" = postponed
write "D" to worksheet when "OK" is clicked on userform
write "X" to worksheet when "Postpone" is clicked on userform

Excel 2016 (Windows) 32 bit
[Table="width:, class:head"][tr=bgcolor:#E0E0F0][th] [/th][th]
A
[/th][th]
B
[/th][th]
C
[/th][th]
D
[/th][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
1
[/td][td]Date[/td][td]Time[/td][td]Message[/td][td]Status[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
2
[/td][td]
11/06/2019​
[/td][td]
10:00​
[/td][td]Check that project X is on schedule[/td][td]D[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
3
[/td][td]
12/06/2019​
[/td][td]
14:00​
[/td][td]Staff weekly meeting[/td][td]D[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
4
[/td][td]
13/06/2019​
[/td][td]
16:00​
[/td][td]WebMeeting with boss[/td][td]D[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
5
[/td][td]
14/06/2019​
[/td][td]
10:00​
[/td][td]Pay Bill A[/td][td]D[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
6
[/td][td]
14/06/2019​
[/td][td]
10:00​
[/td][td]Ring the school[/td][td]D[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
7
[/td][td]
14/06/2019​
[/td][td]
14:00​
[/td][td]Book hotel for Wednesday[/td][td]D[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
8
[/td][td]
15/06/2019​
[/td][td]
14:00​
[/td][td]Chase delivery of materials for project X[/td][td]D[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
9
[/td][td]
15/06/2019​
[/td][td]
14:00​
[/td][td]Ring Peter re Team Meeting[/td][td]D[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
10
[/td][td]
16/06/2019​
[/td][td]
10:00​
[/td][td]Pay Joiners Inc[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
11
[/td][td]
16/06/2019​
[/td][td]
14:00​
[/td][td]Team meeting tomorrow[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
12
[/td][td]
18/06/2019​
[/td][td]
10:00​
[/td][td]Feed the cat[/td][td]D[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
13
[/td][td]
18/06/2019​
[/td][td]
14:00​
[/td][td]Phone bank re cheque[/td][td]X[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
14
[/td][td]
18/06/2019​
[/td][td]
14:00​
[/td][td]Phone bank re overdraft[/td][td]X[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
15
[/td][td]
18/06/2019​
[/td][td]
20:00​
[/td][td]Arrange transpost for delivery X[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
16
[/td][td]
18/06/2019​
[/td][td]
20:00​
[/td][td]Feed the fish[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
17
[/td][td]
18/06/2019​
[/td][td]
20:00​
[/td][td]Phone bank re oversight[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
18
[/td][td]
18/06/2019​
[/td][td]
20:00​
[/td][td]Phone home[/td][td][/td][/tr]
[/table]
[Table="width:, class:grid"][tr][td]Sheet: DATA[/td][/tr][/table]
 
Last edited:
Upvote 0
Re: Asking for help on a variable input for Application.ontime...

Please read post#14 onwards before reading this

Sorting messages

The UserForm adds items with various dates and times to sheet "DATA"
Those items are added in the order created
Below is a simple procedure that can be called to sort the data in the way it is likely to be required by VBA
Code:
Sub SortMessages()
    With Sheets("Data")
        .Sort.SortFields.Clear
        With .Range("A2", .Range("A" & Rows.Count).End(xlUp)).Resize(,[COLOR=#ff0000] 4[/COLOR])
            .Sort .Range("B2"), xlAscending
            .Sort .Range("A2"), xlAscending
        End With
        .Sort.SortFields.Clear
     End With
End Sub

Resize(, 4) allows for column D (as suggested in post#15)
 
Upvote 0
Re: Asking for help on a variable input for Application.ontime...

Please read post#14 onwards before reading this

Which message is next?

Here is the simplest way I can think of to return the correct "next" message each time

With column D = message status & messages soted by date and time (as explained in posts #15 & #16 )
.. the FIRST message with a blank cell in column D
.... is the correct "next" message
...... ( = earliest message which has not been dealt with)

The code below
- calls itself recursively
- column B = TimeValues(not text)
- column A = DateValues (not text)
- message returned to a message box (you need to return it to the textbox in your userform)

Code:
Sub NextMessageToDisplay()
    Dim cel As Range

[I][COLOR=#006400]'get first blank cell in column D[/COLOR][/I]
    Set cel = Sheets("DATA").Range("D1").End(xlDown).Offset(1, -3)
    
[I][COLOR=#006400]'if message date and time is before current date and time then ...[/COLOR][/I]
    If cel + cel.Offset(, 1) <= Now Then
[COLOR=#006400][I]'display message[/I][/COLOR]
        MsgBox cel.Offset(, 2)
       Call NextMessageToDisplay
    Else
[I][COLOR=#006400]'display next message at appropriate time[/COLOR][/I]
        Application.OnTime cel.Offset(, 1), "NextMessageToDisplay"
    End If
End Sub


With data sorted as below, the next message displayed is
[TABLE="width: 349"]
<tbody>[TR]
[TD="width: 349"] "Pay Joiners Inc"[/TD]
[/TR]
</tbody>[/TABLE]
Excel 2016 (Windows) 32 bit
[Table="width:, class:head"][tr=bgcolor:#E0E0F0][th] [/th][th]
A
[/th][th]
B
[/th][th]
C
[/th][th]
D
[/th][th]
E
[/th][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
1
[/td][td]Date[/td][td]Time[/td][td]Message[/td][td]Status[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
2
[/td][td]
11/06/2019​
[/td][td]
10:00​
[/td][td]Check that project X is on schedule[/td][td]D[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
3
[/td][td]
12/06/2019​
[/td][td]
14:00​
[/td][td]Staff weekly meeting[/td][td]D[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
4
[/td][td]
13/06/2019​
[/td][td]
16:00​
[/td][td]WebMeeting with boss[/td][td]D[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
5
[/td][td]
14/06/2019​
[/td][td]
10:00​
[/td][td]Pay Bill A[/td][td]D[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
6
[/td][td]
14/06/2019​
[/td][td]
10:00​
[/td][td]Ring the school[/td][td]D[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
7
[/td][td]
14/06/2019​
[/td][td]
14:00​
[/td][td]Book hotel for Wednesday[/td][td]D[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
8
[/td][td]
15/06/2019​
[/td][td]
14:00​
[/td][td]Chase delivery of materials for project X[/td][td]D[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
9
[/td][td]
15/06/2019​
[/td][td]
14:00​
[/td][td]Ring Peter re Team Meeting[/td][td]D[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
10
[/td][td]
16/06/2019​
[/td][td]
10:00​
[/td][td]Pay Joiners Inc[/td][td=bgcolor:#FFFF00][/td][td]<---Finds this empty cell[/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
11
[/td][td]
16/06/2019​
[/td][td]
14:00​
[/td][td]Team meeting tomorrow[/td][td][/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
12
[/td][td]
18/06/2019​
[/td][td]
10:00​
[/td][td]Feed the cat[/td][td]D[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
13
[/td][td]
18/06/2019​
[/td][td]
14:00​
[/td][td]Phone bank re cheque[/td][td]X[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
14
[/td][td]
18/06/2019​
[/td][td]
14:00​
[/td][td]Phone bank re overdraft[/td][td]X[/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
15
[/td][td]
18/06/2019​
[/td][td]
20:00​
[/td][td]Arrange transpost for delivery X[/td][td][/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
16
[/td][td]
18/06/2019​
[/td][td]
20:00​
[/td][td]Feed the fish[/td][td][/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
17
[/td][td]
18/06/2019​
[/td][td]
20:00​
[/td][td]Phone bank re oversight[/td][td][/td][td][/td][/tr]

[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]
18
[/td][td]
18/06/2019​
[/td][td]
20:00​
[/td][td]Phone home[/td][td][/td][td][/td][/tr]
[/table]
[Table="width:, class:grid"][tr][td]Sheet: DATA[/td][/tr][/table]
 
Last edited:
Upvote 0
Re: Asking for help on a variable input for Application.ontime...

please read this AFTER reading posts #14 to #17

Final contribution for today - some of this has now become "pseudo-code simply there as a bit of a guide :warning:

Calling the userform to postpone a message

1.Userform code requires access to "cel" variable

So delete this line in NextMessageToDisplay
Code:
  Dim cel As Range
and create a public variable at the top of the module ABOVE all procedures (makes the variable available to other modules including userform module)
Code:
  Public cel As Range

2. Replace this line in NextMessageToDisplay
Code:
        MsgBox cel.Offset(, 2)

.. with something like this (userform name needs amending)
Code:
        If MsgBox(cel.Offset(, 2) & vbCr & vbCr & "Postpone above message?", vbYesNo, "Postpone??") = vbYes Then
            Userform1.Show
            Exit Sub
        Else
[I][COLOR=#006400]'update message status to "Dealt with"[/COLOR][/I]
            cel.Offset(, 3) = "D"
        End If

3. Postpone procedure requires something similar to this
Code:
[I][COLOR=#006400]'message text etc[/COLOR][/I]
  TextBox1.Value = Cel.Offset( , 2) - likewise for other values being transferred into userform objects
[I][COLOR=#006400]
'prevent past date being seleced otherwise message visibility lost[/COLOR][/I]
  ?? perhaps date picker already does this, otherwise insert code to control input

[I][COLOR=#006400]'update message status ONLY if date or time has changed otherwise message visibility lost[/COLOR][/I]
   If cel.offset( ,1) <> TimeValue of ComboBox1 Or cel <> Date Value of UserformDateObject Then cel.Offset(, 3) = "P"

[I][COLOR=#006400]'trigger next message[/COLOR][/I]
   Call NextMessageToDisplay
 
Last edited:
Upvote 0
Re: Asking for help on a variable input for Application.ontime...

Hi Yongle - you really have put a lot of effort into this and I appreciate it very much - I need to study this - a recent development has taken my focus off this but affects it a great deal -apparently the developers of O365 have seen fit to force a user to have changes to worksheets and code automatically saved to OneDrive. This has created a problem when trying to run and test this code out - I keep getting
Code:
Cannot run the macro ..://d:docs.live.net/ac484c1474897305 ALL FOLDERS/Documents/2019.xlsm! CMDFINDVAL'. The macro may not be available in this workbook or all macros may be disabled
this error message when the code searces for a future date. I signed out of my account but the same thing happens. As soon as I can resolve this, I want to continue full force with finishing the development of this reminder app. My vb editor window also got all messed up and I can't figure out how to keep the Project Explorer and code windows to stay locked in the docked positions next to each other in the same position all the time as it was before. The windows don't stack anymore - they appear as separate windows on top of windows and I have to rearrange the editor window. I don't know if I accidently clicked a button on the toolbar or what I did but it's very annoying. Sorry for the venting - I just need to get on with this - thx again for all your help , time and input...cr
 
Last edited:
Upvote 0
Re: Asking for help on a variable input for Application.ontime...

Consider starting a new thread to help resolve OneDrive issue - others have probably suffered similarly :banghead::banghead::banghead::banghead:
Good luck
 
Last edited:
Upvote 0

Forum statistics

Threads
1,223,236
Messages
6,170,906
Members
452,366
Latest member
TePunaBloke

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top