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.
Related
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 .
I need some assistance. I am new to vbscript and I have a problem/question.
I am trying to give an end user the ability to start a program over.
I have done research on MSDN and googled various other sites that involve tutorials based on if then statements, subroutines, functions and do,while,until loops
all the loop tutorials or explanations have a program looping through numbers and string lengths. I have developed a common stock transaction program:
'Stock Transaction Program
Option Explicit
Dim stockPrice, commission, stocksBought, stockCommission, stockTotal, totalCost, tryAgain
Wscript.StdOut.Write "Stock price: "
stockPrice = CDbl(Wscript.StdIn.ReadLine)
Wscript.StdOut.Write "Number of stocks bought: "
stocksBought = CDbl(Wscript.StdIn.ReadLine)
Wscript.StdOut.Write "Stock Commission percentage in whole number (i.e 2 for 2%): "
commission = CDbl(Wscript.StdIn.ReadLine)
stockTotal = stockPrice * stocksBought
stockCommission = commission * stockTotal / 100
totalCost = stockCommission + stockTotal
Wscript.StdOut.WriteLine "You payed a total commission of $" & stockCommission & " on the stocks you bought."
Wscript.StdOut.WriteLine "Your total price for you purchasing " & stocksBought & " stocks is $" & totalCost & "."
After this program concludes, I would to give the end user an option to evaluate another stock price..etc.
Wscript.Stdout.Writeline "Would you evaluate another stock price? (i.e y or n): "
tryAgain = lcase(wscript.stdin.readline)
My logic assumes that you would now proceed with an if statement of some kind that basically says: that if tryAgain equals "y" then proceed back to the top, if "n" then exit program with a thank you conclusion, if invalid character then state that the end user entered an invalid response, allowing them the oppurtunity to try again.
I couldn't figure it out. functions and subroutines need arguments (i assume) and subroutines do not give data output. functions do but this code doesnt classify. I was hoping that their was a syntax that would allow the program to start over. I think a loop of some kind is probably the answer but i dont have the knowledge or the experience.
Is their anyone that can assist me???
Thanks
This could be one of the simplest solutions.
Option Explicit
Dim stockPrice, .... , tryAgain
Do
'....
' your stocks code
'....
Wscript.Stdout.Writeline "Would you evaluate another stock price? (i.e y or n): "
tryAgain = lcase(wscript.stdin.readline)
Loop While tryAgain="y"
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.
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.
I am really new to VBscript; like I litteraly just started about a half hour ago, but I just need it for a super simple program. It runs a Do Until loop, and I want it to stop when I press the spacebar. I have everything else done, I just need to know if/how to detect the keystroke. Thanks in advance!
You need to put your script into an hta file (basically a web page with a program's permissions) see http://msdn.microsoft.com/en-us/library/ms536473(VS.85).aspx. Then set up an event handler for space key. Instead of a do loop do a timer and do 1 thing a timer tick. Your space key event handler cancels the timer.
onkeydown Event
Fires when the user presses a key.
Syntax
Inline HTML <ELEMENT onkeydown = "handler" ... > All platforms
Event property object.onkeydown = handler JScript only
object.onkeydown = GetRef("handler") Visual Basic Scripting Edition (VBScript) 5.0 or later only
Named script <SCRIPT FOR = object EVENT = onkeydown> Internet Explorer only
Event Information
Bubbles Yes
Cancels Yes
To invoke Press any keyboard key.
Default action Returns a number specifying the keyCode of the key that was pressed.
setInterval Method
Evaluates an expression each time a specified number of milliseconds has elapsed.
Syntax
iTimerID = window.setInterval(vCode, iMilliSeconds [, sLanguage])
Parameters
vCode Required. Variant that specifies a function pointer or string that indicates the code to be executed when the specified interval has elapsed.
iMilliSeconds Required. Integer that specifies the number of milliseconds.
sLanguage Optional. String that specifies any one of the possible values for the LANGUAGE attribute.
Return Value
Integer. Returns an identifier that cancels the timer with the clearInterval method.
Remarks
The setInterval method continuously evaluates the specified expression until the timer is removed with the clearInterval method.
This is a operative, non advisable (you are advised), option. But it generates a line write to console (jump to next line) every time it checks for the key press.
Function GetParentProcessId()
Dim processesList, process
Set processesList = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set processesList = processesList.ExecQuery("SELECT * FROM Win32_Process WHERE (Name = 'cscript.exe') AND Commandline LIKE '%"+WScript.ScriptName+"%'" )
For Each process in processesList
GetParentProcessId = process.ParentProcessId
Next
End Function
Dim parentProcessId
parentProcessId = GetParentProcessId()
Dim shell
Set shell = WScript.CreateObject("WScript.Shell")
Dim input, i
i=0
Do While True
WScript.StdOut.Write "Press space to stop process. Step [" & i & "]" & vbCR
i = i + 1
If (i Mod 10) = 0 Then
shell.AppActivate parentProcessId
shell.SendKeys "~"
input = WScript.StdIn.ReadLine()
If input = " " Then
Exit Do
End If
End If
WScript.Sleep 50
Loop
WScript.StdOut.WriteLine vbCFLF & "Process ended"
WScript.Quit