I’m running a program that has a delay routine in it. The program needs to loop over the course of a week, but it stops working at midnight. I suspect it’s my delay code, but I don’t know what’s wrong with it: (code) Public Sub doDelay(ByRef amount!) 'argument: amount, amount of delay in seconds 'Description: to do a delay for application (not GPIB related) ’ Dim StartTime, endTime amount! = amount! * 1! StartTime = Timer 'check for 24-hours change If StartTime + amount! > 86400 Then StartTime = StartTime - 86400 endTime = StartTime + amount! Do While Timer < endTime DoEvents Loop End Sub (/code) I’m taking into account the fact that the timer loops back to zero at midnight. Why is my program stopping at midnight?

As a bear of perhaps little brain, c I am a bit puzzled as to how the original routine is expected to function. The routine’s process all relies on a call to the Timer function at the start of the routine. Timer automatically resets to zero at midnight, so unless there is some particular reason to spot the times at which this happens, there is little value in looking for values of Timer > 86,400. As the code stands, however, you are creating an action in the seconds when Timer is less than amount seconds before midnight. Is that what you need or want?

If you were to set up a public variable to record the value from timer on each visit to the routine, you easily identify the point at which you move to the new day, because your new value from Timer would be less than the stored value. This action would be done just once each day, immediately after midnight.

Just a thought …

It seems that you asked why your code doesn’t work and everyone is telling you a better way to do it. Let’s look at why it doesn’t work.

You have identified when the time duration crosses midnight, but you are reassigning StartTime = StartTime - 86400. That will make StartTime a negative value. Then, when you assign endTime: endTime = StartTime Amount! you have assigned endTime to be either a negative number or some very small value (probably less than 100). Now, your Do-Loop tests to see if the current Timer value is less than endTime. The very first time through the Do-Loop will give the Timer return value something large like 86,367 and endTime will be a negative value or something small like 100. Your do-loop will not execute even the first time!

If you call the doDelay subroutine for a duration that crosses midnight, there will be NO delay! It will immediately return to your calling code. If your code is hanging at midnight then I would check out your calling code to see why it is locking up when there is no delay.

Louis Vanderwilt

I agree with Rob. I guess we don’t have enough info to know if a timer is indeed needed. If all you want to do is run a process (sub) for a week then you could dim a global date variable that would contain the value of Now (current date time) plus 7 days when the form loads or right before calling the sub. Then on the sub you loop while Now is less than the value in the global date variable.

I haven’t studied the OP fully, but if it is a Do Loop running all the
time, I would be closely checking the CPU usage.
I once was burned by using continuous Do Loops, and I will never use
them again.
I too would be using the VB Timer, which can be surprisingly gentle with CPU
Rob

I’m not sure how accurate the actual times need to be but couldn’t you just use the regular vbTimer to check the current time?

Timer loops every minute or two etc.
If Hour(Now) = 0 and Minute(Now) < 02 Then 'do something…

Another method could be combined with Windows GetTickCount function as it is very accurate in miliseconds

Declare Function GetTickCount Lib “kernel32” () As Long

Dim End_Time as Long

End_Time = GetTickCount

Greg,

I’m not quite sure why you are using Single as your datatype for “amount”, rather than Integer (then again, I’m not quite sure what “Timer” is doing – it’s not a standard keyword in all versions of Visual Basic). Also, I’m not sure what effect generating a negative StartTime will have.

I would suggest rewriting your code as follows:

Public Sub doDelay(ByRef amount As Single)

'argument: amount, amount of delay in seconds
'Description: to do a delay for application (not GPIB related)

Dim StartTime As Single
Dim endTime As Single

amount = amount * 1.0
endTime = (StartTime amount) % 86400
Do While Timer < endTime
DoEvents
Loop
End Sub

(to ensure that plus signs make it through the forum, that’s):

Public Sub doDelay(ByRef amount As Single)

'argument: amount, amount of delay in seconds
'Description: to do a delay for application (not GPIB related)

Dim StartTime As Single
Dim endTime As Single

amount = amount * 1.0
endTime = (StartTime

OK all the plus signs where omitted from my previous post. I hope you can still follow =(

I guess I don’t think I am following your code clearly because I don’t see how it could work.
I will use hours so it is easier to follow so instead of 86400 I’ll use 24. Let’s say it is 11pm (23 hour):
Timer is 23
StartTime is 23
amount is 2 hours.
'check for 24-hours change
If StartTime amount! > 24Then StartTime = StartTime - 24
if 23 2 > 24 then startime is now 23-24 which is -1
endTime = StartTime amount!
endTime is now -1 2 which is 1
Do While Timer < endTime
it will not loop because 23 is less than 1
Maybe your loop needs to be
Do While StartTime < endTime which would be true since -1 is less 1

When you cross midnight, timer starts over at zero. Therefore, the response from timer never goes over 86400. What I do to protect a timer crossing midnight is:

dim StartTime as single
dim Duration as single

StartTime = timer
do
doevents
if timer < StartTime then StartTime = Timer 'Crossing midnight test
loop while timer - StartTime < Duration
:
:
Continue with program
:
:
When the program passes midnight, the value from timer drops to zero which is less than StartTime. When that happens, simply reassign StartTime. Keep in mind that if the length of the Duration is critical, the actual timer duration will be longer (only when crossing midnight).

I usually use this when I want to time out from a process that is taking too long and the actual duration isn’t critical.

Louis Vanderwilt

It is not immediately obvious what is happening, but I would consider putting the test clause in your if … statement in brackets () simply because this seems to be more stable and reliable.

It would also be useful to try to report the time each time your loop increments, but I can imagine that you would not want to be there watching and clicking once a second for a whole 24 hours (or longer). Have you considered writing the value to an output file on each increment? You could leave that running overnight an then come back and see what has happened. You could even report the system clock each time to see how the two cxompare.

failing that, you can start at a time near to 84600 and see what happens as you go past the 24 hour point.

Why don’t you use a datetime variable so you don’t have to be manipulating the value in EndTime?