Vbscript check hour difference within a loop - vbscript

I want to check the time difference of 1 hour within a loop. A Do-loop will be running and every single time it will see if the difference of current time and previous time period is 1 hour .
I wrote this , but i guess this is way complicated
Dim ti_me
Public Function storetime(arg1,arg2)
da_te = Time
If (DateDiff("h",da_te,arg1)=1 Or -1) Then
WScript.Echo DateDiff("h",da_te,arg1)&" hour"
End If
ti_me = arg2
End Function
Call storetime("1:18:22 PM",Time)
Do
a = Time
Call storetime(a,"")
WScript.Sleep 2000
Loop
Please Correct me .

Related

Trying to make my own vbscript

I have been working on this vb script for around an hour trying to get it to work there is many skype spammer scipts but i want to make one that includes a random number generator my script is this i call it at the moment "Skype_randizer_mk1"
If anyone would be able to take a look at it it would be greatly appreciated.
When i was posting this the website said i had to indent this so it may look a little strange
The Delay variable is the amount of time it will take to enter another number
I don't mind if this program makes only numerical values that is what i intend for it to do
set shell = createobject ("wscript.shell")
dim max
dim min
dim delay
max = 100
min = 1
delay = 0.00000001
for i = 1 to 5
randomize
intnumber = int((max - min + 1) * rnd + min )
wscript.echo intnumber
Next
for b=1 to delay
shell.sendkeys (intnumber)
wscript.sleep(delay)
if not isnumeric(delay) then
wscript.quit
end if
msgbox "You have 5 seconds to get to your inputbox."
wscript.sleep ( 5000 )
Next
You have lots of problems with your code:-
You should ALWAYS declare your variables using Dim: e.g. Dim shell
You are missing a Next for one of your For loops
Line 10 doesn't make much sense. It says: for b=1 to delay, but delay = 0.00000001, so your loop will never run. Also, why does this section even need to loop? I think you probably just want an If/Then/Else
Line 11 should probably say shell.SendKeys, not strshell.sendkeys as this is an uninitialised variable
Line 13 is checking for a numeric delay value. How will this ever be anything other than numeric when you are assigning a value of 0.00000001 on line 4 and it never changes. As a result, you will not exit the script until the for loop on line 5 has executed 5 times.

VB6 Timeout the function if no response

I have a function within a VB6 app that forces the program to be inaccessible. Sometimes when an error happens within the function the end-user wouldn't receive a result and might still think that something is happening in the background.
Due to that I was thinking of adding a timeout function. I know that function should return result within 1-2 seconds and if not there was an error so we have to break the function and return an error.
How can this "timeout" be achieved in VB6?
Maybe the sample below will help, it assumes a Timer control on your form named Timer1
Private Function TestFunction() As Boolean
On Error GoTo TestFunctionErrHandler
Me.Timer1.Interval = 1000 ' set time to fire one time per second
' code for (function should return result within 1-2 seconds) here
Exit Function
TestFunctionErrHandler:
' code for error condition here
End Function
Private Sub Timer1_Timer()
Static seconds As Integer
seconds = seconds + 1
If seconds >= 2 Then
' code for (forces the program to be inaccessible) here
End If
End Sub

VBA loop efficiency

I've used the answers found in the site a TON of times, but this is my first post.
Is it more efficient to perform a for loop inside a function or sub or to just send the incremented value of the loop into the function or sub as an argument?
I am importing some text data files into Excel, parsing out the various fields, and then splitting some of the fields into individual characters. One file I am using is a list of doctors. I have name, address, phone, DEA number, NPI, etc.
When checking the DEA number, I have a sub that receives the line number to be checked that splits the DEA into its individual digits, perform checking on these digits one at a time and then modify another field with the status of that DEA. This status cell will be colored red if it contains anything but the word "GOOD". Also, I am coloring the individual digit that is bad, if applicable.
This one sub is doing a lot and I could probably break it up a little, but there aren't any other places in the doctor file that I am performing this exact step, so I figured I should keep it like it is.
Anyways, the real question is whether I should send the line number into the sub or should I just call the sub and have the sub calculate the number of lines and do the checking. In the first case, I will call the sub a number of times equal to the number of lines in the doctor file. In the second, I will call the sub once and the sub contains the for loop for each line. Which is usually more efficient.
Apologies if I seem redundant. I train some complex software and that sort of thing leaks into other areas of life sometimes.
EDIT: I tried to add this into a comment but have insufficient experience posting here. Apologies if I violate some rule for this...
Here is the code I use currently to call the sub:
'Use the Doctor Last Name as the number of rows count
Dim numRows As Integer
numRows = Application.CountA(Sheets("DoctorDEA").Range("m:m"))
'lineCtr is the Line Counter used to iterate the FOR loops
Dim lineCtr As Integer
lineCtr = 1
'Call DEACHecking and DisplayIssues Subs
For lineCtr = 1 To numRows - 1
DEAChecking (lineCtr)
DisplayIssues (lineCtr)
Next lineCtr
My questions is this: Would it be better to just call DEAChecking with no arguments and just have DEAChecking calculate the line numbers and then use the FOR loop or to leave it as is?
This question is too broad right now to be answered effectively. So am just offering a small insight that might help you structure your program.
Typically the most efficient code is the one where all the variables are as local as possible. If inside a loop you are using globals, or calling other functions it is going to be much worse than performing all the calculation with local variables.
If you want to test each, and time them, you can use a timer. If you have a major gap, you will be able to catch it. If not, you will have your answer with no significant difference as far as processing time.
You can either use this and call your sub from TimerTest, or simply Call TimerStart at the beginning of your code and TimerStop at the end.
Run some code with the timer
Log the result
Repeat and compare
HH:MM:SS:00 format
Timer Code:
Public strStartTime As String
Public strEndTime As String
Public startTime As Date
Public endTime As Date
Sub timeTest()
Call TimerStart
'INSERT CALL TO YOUR SUB HERE
Call TimerStop
End Sub
Sub TimerStart()
startTime = Now
End Sub
Sub TimerStop()
endTime = Now
'Waited until the timer stopped to perform any additional code, such as formatting the time
Dim TotalTime As String
strStartTime = Format(startTime, "hh:mm:ss:" & Right(Format(Timer, "#0.00"), 2))
strEndTime = Format(endTime, "hh:mm:ss:" & Right(Format(Timer, "#0.00"), 2))
TotalTime = Format(endTime - startTime, "hh:mm:ss:" & Right(Format(Timer, "#0.00"), 2))
MsgBox (" Start: " & strStartTime & vbNewLine & _
" End: " & strEndTime & vbNewLine & _
"Total Time : " & TotalTime)
End Sub
Credit: #Nick Dandoulakis for timer formatting in his answer here: Providing this solution to show clock time with accuracy of less than a second.

How to choose a random time once per hour

Suppose I want to run a task once per hour, but at a variable time during the hour. It doesn't have to be truly random; I just don't want to do it at the top of the hour every hour, for example. And I want to do it once per hour only.
This eliminates several obvious approaches, such as sleeping a random amount of time between 30 and 90 minutes, then sleeping again. It would be possible (and pretty likely) for the task to run several times in a row with a sleep of little more than 30 minutes.
The approach I'm thinking about looks like this: every hour, hash the Unix timestamp of the hour, and mod the result by 3600. Add the result to the Unix timestamp of the hour, and that's the moment when the task should run. In pseudocode:
while now = clock.tick; do
// now = a unix timestamp
hour = now - now % 3600;
hash = md5sum(hour);
the_time = hour + hash % 3600;
if now == the_time; then
do_the_work();
end
end
I'm sure this will meet my requirements, but I thought it would be fun to throw this question out and see what ideas other people have!
For the next hour to do work in, just pick a random minute within that hour.
That is, pick a random time for the next interval to do work in; this might be the same interval (hour) as the current interval (hour) if work has carried over from the previous interval.
The "time to sleep" is simply the time until then. This could also be execute "immediately" on a carry-over situation if the random time was before now: this will ensure that a random time is picked each hour, unless work takes more than an hour.
Don't make it more complex than it has to be - there is no reason to hash or otherwise muck with random here. This is how "Enterprise" solutions like SharePoint Timers (with an Hourly Schedule) work.
Schedule your task (with cron or the like) to run at the top of every hour.
At the beginning of your task, sleep for a random amount of time, from 0 to (60 - (the estimated running time of your task + a fudge factor)) minutes.
If you don't want your task to run twice simultaneously, you can use a pid file. The task can check - after sleeping - for this file and wait for the currently running task to finish before starting again.
I've deployed my suggested solution and it is working very well. For example, once per minute I sample some information from a process I'm monitoring, but I do it at variable times during the minute. I created a method of a Timestamp type, called RandomlyWithin, as follows, in Go code:
func (t Timestamp) RandomlyWithin(dur Timestamp, entropy ...uint32) Timestamp {
intervalStart := t - t % dur
toHash := uint32(intervalStart)
if len(entropy) > 0 {
toHash += entropy[0]
}
md5hasher.Reset()
md5hasher.Write([]byte{
uint8(toHash >> 24 & 255),
uint8(toHash >> 16 & 255),
uint8(toHash >> 8 & 255),
uint8(toHash & 255)})
randomNum := binary.BigEndian.Uint32(md5hasher.Sum(nil)[0:4])
result := intervalStart + Timestamp(randomNum)%dur
return result
}

Now() Accuracy in VBScript

Now() in VBScript appears to return time in 10,000,000th of a second precision when called as CDbl(Now()). In attempting to use this to write a more accurate implementation of now which returns CIM_DATETIME format I found that in VBScript, despite being particularly precise, is not very accurate with the time only updating once per second. This can be demonstrated by watching the output from what follows:
i = 0
While i < 50
gnow = Cdbl(now)
result = (gnow - Int(gnow))
WScript.Echo CDate(gnow)
WScript.Echo "Iteration " & i & ": " & result
WScript.Sleep(100)
i = i + 1
Wend
The question I'm now trying to answer is, given a VBScript that runs for less than a second which calls Now(), what time will be returned by Now()? Is it the time that the script interpreter started, the time when Now() was called, or something else?
It looks like it will be the time the "Now()" method was called accurate to the second. It's still a normal method invocation.

Resources