|
Assuming that the program is running at the time, then my suggestion would be to have a timer that does a PerformClick on the button at the appropriate.
The timer would need to be checking every minute to see if the time has been reached. You would also need to disable it for the period that the process under the button is running so that it does not (potentially) cause any problems with firing again inside the time. Setting the interval to 65000 should stop that but better to disable the time during the execution of the target code.
|
|
|
|
|
It's a shame that the .NET Timer class doesn't let you schedule an event for a specified time. It seems like such an obvious thing and it's been in other platforms like Java for years, so you wonder why they've never added it to .NET. It can't be difficult to do from a technical viewpoint.
The previous post is a perfectly good solution but you could also have a look at Quartz.NET[^] for something more sophisticated or this article[^] if you prefer a "roll your own" solution.
If you are building an application that needs any sort of scheduling service beyond the basics, I would recommend something like this, but I suspect that might be overkill for your requirements.
|
|
|
|
|
Hi Bob,
Besides what the other two already told you, I strongly recommend you to not fire the button click event with the timer tick event.
Instead, it is much better practice, to move the code from the button's click event to its own Sub, and then call this sub both in the button's click event and in the timer's tick event.
So instead of this:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MsgBox("Jiihuu!!!")
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Button1.PerformClick()
End Sub
it's better to build your app like this:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MyMessageBox()
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
MyMessageBox()
End Sub
Private Sub MyMessageBox()
MsgBox("Jiihuu!!!")
End Sub
This will make future development a lot easier, for example if at some point you want the code to execute in different manners:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MyMessageBox(" Executed by Button1")
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
MyMessageBox(" Executed by Timer1 at " & Now.ToShortTimeString)
End Sub
Private Sub MyMessageBox(Byval ExtraMessage As String)
MsgBox("Jiihuu!!!" & ExtraMessage)
End Sub
My advice is free, and you may get what you paid for.
|
|
|
|
|
Hello Johan
Thanks for your help this looks good but whare would i put the spacifique time to fier my button ??
and my app will be running 24 7
Thanks
|
|
|
|
|
Hello Bob,
So take your case: you want the code to be executed once a day at a specific time (was it 5:34 pm ?).
Let's take my example code again:
Dim TheButtonWasClickedToday As Boolean = False
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MyMessageBox(" Executed by Button1")
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If TheButtonWasClickedToday = False Then
If Now.Hour = 17 Then
Select Case Now.Minute
Case 34
MyMessageBox(" Executed exactly on time by Timer1 at " & Now.ToShortTimeString)
TheButtonWasClickedToday = True
Case Is > 40 'a 6 minute safety catch'
TheButtonWasClickedToday = False
Case Is > 34
If TheButtonWasClickedToday = False Then
MyMessageBox(" Executed too late by Timer1 at " & Now.ToShortTimeString)
TheButtonWasClickedToday = True
End If
End Select
End If
End If
End Sub
Private Sub MyMessageBox(Byval ExtraMessage As String)
MsgBox("Jiihuu!!!" & ExtraMessage)
End Sub
For it to work you would have to set the timer's interval to 1 minute (60000 milliseconds).
The problem with the timer approach, is that you are dependent on the interval. If for any reason (for example the pc freezes) the tick event is a few seconds late, your code will not be run until the next day.
So I have added the TheButtonWasClickedToday boolean to check if the code was run. In this case I have given it 6 minutes time, but you can make that smaller or larger.
Also, I am not entirely sure if checking for the hour will work with 17, as you apparently use the am/pm system. You may have to investigate that.
As for Ashfield's answer to you, you say your app will be running 24/7, but is that just to make sure that the code will be executed on time, or because the rest of the app will be doing things the rest of the time?
My advice is free, and you may get what you paid for.
|
|
|
|
|
Thanks i will try that
and the app it doing thing 24 7 reson for this timer is i want to log some data into a excell file
so every hour it will record data to a set cell
|
|
|
|
|
Hello johan
Thanks for the help it is exacly what i wanted to do your the best
I got this to work but it only runs the first set 22:23 and it do notintg for 22:24
I have to have it run once ever hour somting difrent so i would need 24 lines of code
Thanks
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Timer1.Interval = 60000
TextBox1.Text = Format(Now, "M")
If Now.Hour = 22 Then
Select Case Now.Minute
Case 23
MyMessageBox(" Executed exactly on time by Timer1 at " & Now.ToShortTimeString)
End Select
End If
If Now.Hour = 22 Then
Select Case Now.Minute
Case 24
MyMessageBox(" Executed exactly on time by Timer1 at " & Now.ToShortTimeString)
End Select
End If
End Sub
I got this to work but it only runs the first set 22:23 and it do notintg for 22:24
Thanks agine
Bob
modified on Thursday, September 3, 2009 10:27 PM
|
|
|
|
|
Hi Bob,
You need to move Timer1.Interval = 60000 to where you start the timer.
So for example:
Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Timer1.Enabled = True
Timer1.Interval = 60000 'we should get a tick every 1 minute'
'if you get a tick more often, you need to increase this number'
'if you get a tick less often, you need to decrease this number'
Timer1.Start
End Sub
For your code to run 24 times (once an hour) you need to turn the If and Select Case statements around:
Select Case Now.Hour
Case 0
If Now.Minute = 23 Then MyMessageBox(" Executed exactly on time by Timer1 at " & Now.ToShortTimeString)
Case 1
If Now.Minute = 23 Then MyMessageBox(" Executed exactly on time by Timer1 at " & Now.ToShortTimeString)
Case 2
If Now.Minute = 23 Then MyMessageBox(" Executed exactly on time by Timer1 at " & Now.ToShortTimeString)
'Etc.'
End Select
Just write a case for each hour, and change the minutes that are checked, according to your needs. So yes, you will need to write 24 lines of code
Although I must agree with Ashfield, that what you are (apparently) trying do, really would work much more reliably with a console application.
If you have never written one, don't worry, it is pretty much the same as the application you have written now, and you wouldn't need to use a timer.
My advice is free, and you may get what you paid for.
|
|
|
|
|
Hay Thanks Thare
i will try this and see what hapens
2 thing why did you put the mins at 23 ??
and i have to put end if after each msg box right??
Thanks
Oh i just think i found somting a little easyer that might work but the msgbox comes up 9 times how can i have it just come up once ?? and have it come up once agine the next day ??
If TimeBox.Text = "10:44:01 AM" Then
MsgBox("Timer test", MsgBoxStyle.OkOnly + vbCritical, "Error")
End If
Thanks agine you are grate help
i wish every one was like you
modified on Friday, September 4, 2009 10:52 AM
|
|
|
|
|
Hi Bob,
Bob Beaubien wrote: why did you put the mins at 23 ?
I understood from your question that you need your application to run once an hour but at different minutes. So for example at 0:10, 1:23, 2:15, etc. Ofcourse I don't know what those minutes are, so I just put 23 as an example. That is why I said that you may have to change these minutes to fit your needs.
Perhaps I misunderstood what it is exactly that you are trying to achieve.
Bob Beaubien wrote: i have to put end if after each msg box right?
Actually no. The If statement allows for several different syntaxes:
If i = 1 Then MsgBox("Papa fume une pipe")
If i = 1 Then MsgBox("Papa fume une pipe") Else MsgBox("Mama fume le pipe de papa")
If i = 1 Then
MsgBox("Papa fume une pipe")
Else : MsgBox("Mama fume le pipe de papa")
End If
If i = 1 Then
MsgBox("Papa fume une pipe")
Else
MsgBox("Mama fume le pipe de papa")
End If
Just go ahead and give it a try.
Bob Beaubien wrote: If TimeBox.Text = "10:44:01 AM" Then
MsgBox("Timer test", MsgBoxStyle.OkOnly + vbCritical, "Error")
End If
No, no, no, bad, wrong, please don't !!! You are right, this might work, but it is much more likely to not work half the time. If you use your application on a computer that does not have the exact same regional settings, it won't work. If the tick event fires every millisecond or 100th or 10th of a second this code will do what you described: it will fire 999, 99, or 9 times in a row. If you set the interval to 1 second it will more than likely not fire at all, many times. Do yourself a big favor, and delete that code, and forget you ever came up with the idea.
Please stick to the idea I gave you. It will work on any machine, and it will do what it is supposed to do, not just maybe!
In other words, your idea may seem simple, but it is unsafe coding. It is bad, because if you teach yourself to code like that, it will come back and bite you in the ass, many, many, many times in the future.
My advice is free, and you may get what you paid for.
|
|
|
|
|
Johan is correct of course. I was giving you the quick answer!
The time, depending on whether it is always fixed or may change can either be in the tick event (if the value is never going to change), or as a user setting (if the user can change it), or as some other module level variable which is set on form load etc etc.
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim tmeFireAt as Date = "01:30"
If TimeValue(Now) = tmeFireAt Then
'Or whatever checking you feel you need to see if the time has been reached Hour() Minute() Second() etc etc
Timer1.Enabled = False
'
'do stuff
'
Timer1.Enabled = True
End If
End Sub
Private tmeFireAt as Date = "01:30"
'
'
'
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If TimeValue(Now) = m_tmeFireAt Then
'Or whatever checking you feel you need to see if the time has been reached Hour() Minute() Second() etc etc
Timer1.Enabled = False
'
'do stuff
'
Timer1.Enabled = True
End If
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If TimeValue(Now) = My.Settings.FiringTime Then
'Or whatever checking you feel you need to see if the time has been reached Hour() Minute() Second() etc etc
Timer1.Enabled = False
'
'do stuff
'
Timer1.Enabled = True
End If
End Sub
|
|
|
|
|
Hello Johan Hakkesteegt
I tryed to pm you but i can figuer how i can do that but anyways
i just wated to thanks you and everyone else that help me out
and having lost of patients i am not the best at vb but i am lerning
more and more every day
with your help i got what i wanted to do working perfect Thanks
I will have to get you a beer
Thanks
Bob
|
|
|
|
|
Firstly, are you sure your app will be running at that precise time? If not, why not just create a console app and schedule it with the windows scheduler - much more reliable I would have thought.
Bob
Ashfield Consultants Ltd
Proud to be a 2009 Code Project MVP
|
|
|
|
|
MY app will be running 24 7
|
|
|
|
|
In which case, just set the timer to the difference between the current time and the required time (remembering to use the date as well - I forgot once )
Bob
Ashfield Consultants Ltd
Proud to be a 2009 Code Project MVP
|
|
|
|
|
Hi all, how can i insert excel worksheet in vb.net form that can be applied excel formula in the worksheet.
Thanks in advance..
Regards
|
|
|
|
|
Hello Thare
I am new at this but i am also working with excel and found this site that was very usfull hope it is usfull for you too
http://vb.net-informations.com/excel-2007/vb.net_excel_2007_create_file.htm
look at the bottom of the page thare is all kinds of Related Contents
|
|
|
|
|
I am assuming what you are saying is that you want to disply an Excel worksheet in a form. You could link to Excel using Excel as a COM server (objExcel as Excel.Application) or you could get an excellent control like Spreadsheet Gear which makes what I am assuming you want to do very easy.
If you search the message boards here with 'using excel in vb' you will get 31 pages of results. You might find something useful there!
Alternatively you might find this useful: ExcelSpreadsheet.aspx
|
|
|
|
|
you could use OWC (office web control) to show the excel files and work with it on a form.
|
|
|
|
|
Hi,
I want to add new control at run time . I had written the code to add a new control to the Main Panel in the Data recieved event of the Serial port like this : -
Public Sub portname_DataRecieved()
Dim pnl as new Panel()
Dim pts As New System.Drawing.Point(pt.X, pt.Y)
pnl.Location = pts
pnl.BackColor = System.Drawing.Color.YellowGreen
MainPanel.Controls.Add(pnl)
End Sub
But I am getting the error at the line MainPanel.Controls.Add(pnl) that is cross-thread operation is not valid how can I remove it.
Thanks
|
|
|
|
|
Use current forms Invoke method to call MainPanel.Controls.Add method, hopefully it will resolve the issue.
|
|
|
|
|
I had tried the following code : -
If MainPanel.InvokeRequired Then
MainPanel.Invoke(AddControlToConatiner)
End if
Public Function AddControlToConatiner()
pnl.Location = pts
pnl.BackColor = System.Drawing.Color.YellowGreen
MainPanel.Controls.Add(pnl)
Return 0
End Function
but the problem still remains the same what is the error can u tell or an example
|
|
|
|
|
You're creating a control on a background thread. Don't. Have the AddControlToContainer method create the control. All controls should be created on the UI thread, not on a background thread.
|
|
|
|
|
Hi all
I'm trying to get a value of a column in DataGrid and insert it in Oracle Table. Below is my code.
Sub GridView1_RowDeleting(ByVal sender As Object, ByVal e As GridViewDeleteEventArgs) Handles GridView1.RowDeleting
Dim oradb As String = "Data Source=(DESCRIPTION=" _
+ "(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=Mahasilbkp.ltuisb.net)(PORT=1521)))" _
+ "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=db21a)));" _
+ "User Id=" + Label5.Text + ";Password=<pass>;pooling=false;enlist=false;"
Dim conn1 As New OracleConnection(oradb)
conn1.Open()
Dim cmd1 As New OracleCommand
cmd1.Connection = conn1
GridView1.DataBind()
Dim val As Label = DirectCast((GridView1.Rows(e.RowIndex).FindControl("NTN")), Label)
cmd1.CommandText = "insert into uu.record_backup(ntn, name, status, enf, aud, sector, delete_user) select ntn, name, status, enf, aud, sector" + ",'" + Label5.Text + "'" + " " + "from uu.total_cases where trim(ntn)='" + val.Text.ToString + "'"
Dim dr1 As OracleDataReader = cmd1.ExecuteReader()
dr1.Read()
dr1.Dispose()
dr1.Close()
cmd1.Dispose()
conn1.Dispose()
conn1.Close()
End Sub
When I click on Delete it gives the following error:
Object reference not set to an instance of an object.
Source Error:
Line 49: cmd1.CommandText = "insert into uu.record_backup(ntn, name, status, enf, aud, sector, delete_user) select ntn, name, status, enf, aud, sector" + ",'" + Label5.Text + "'" + " " + "from uu.total_cases where trim(ntn)='" + val.Text + "'"
If I remove the "val.Text" from the above code then it works, but obviously the results are not as I desire. Please help me with this.
Thanks.
|
|
|
|
|
val.Text.ToString ?? What is the object val ??
If it is a text box, try naming it to something else.
|
|
|
|
|