Calculation in 1 line VBS - vbscript

How can I make this Calculator work if the user enters 1+1?
It only works if I enter 1 + 1 ;C
The calculation must be in 1 line.
x = inputbox("Calculation", "Calculator", "1+1")
y = Split(x)
if not isnumeric (y(0)) then
wscript.quit
end if
if not isnumeric (y(2)) then
wscript.quit
end if
if y(1) = "+" then
z = int(y(0)) + int(y(2))
msgbox(z)
end if
if y(1) = "-" then
z = int(y(0)) - int(y(2))
msgbox(z)
end if
if y(1) = "*" then
z = int(y(0)) * int(y(2))
msgbox(z)
end if
if y(1) = "/" then
z = int(y(0)) / int(y(2))
msgbox(z)
end if
if y(1) = "%" then
z = int(y(0)) MOD int(y(2))
msgbox(z)
end if
Thanks for any Answer!

Try next code snippet (commented for explanation):
Dim ii, sOperator, strExpr, y
strExpr = inputbox("Calculation", "Calculator", "1+1")
' insert spaces around all operators
For Each sOperator in Array("+","-","*","/","%")
strExpr = Trim( Replace( strExpr, sOperator, Space(1) & sOperator & Space(1)))
Next
' replace all multi spaces with a single space
Do While Instr( strExpr, Space(2))
strExpr = Trim( Replace( strExpr, Space(2), Space(1)))
Loop
y = Split(strExpr)
''' your script continues here
Another approach (allows more than pure arithmetic operations) using Eval Function (which evaluates an expression and returns the result) and basic error handling:
option explicit
On Error GoTo 0
Dim strResult: strResult = Wscript.ScriptName
Dim strExpr, strInExp, strLastY, yyy
strInExp = "1+1"
strLastY = ""
Do While True
strExpr = inputbox("Last calculation:" & vbCR & strLastY, "Calculator", strInExp)
If Len( strExpr) = 0 Then Exit Do
''' in my locale, decimal separator is a comma but VBScript arithmetics premises a dot
strExpr = Replace( strExpr, ",", ".") ''' locale specific
On Error Resume Next ' enable error handling
yyy = Eval( strExpr)
If Err.Number = 0 Then
strInExp = CStr( yyy)
strLastY = strExpr & vbTab & strInExp
strResult = strResult & vbNewLine & strLastY
Else
strLastY = strExpr & vbTab & "!!! 0x" & Hex(Err.Number) & " " & Err.Description
strInExp = strExpr
strResult = strResult & vbNewLine & strLastY
End If
On Error GoTo 0 ' disable error handling
Loop
Wscript.Echo strResult
Wscript.Quit
Sample output:
==> cscript //NOLOGO D:\VB_scripts\SO\39934370.vbs
39934370.vbs
1+1 2
2/4 0,5
0.5**8 !!! 0x3EA Syntax error
0.5*8 4
4=4 True
True+5 4
4=5 False
False+5 5
5 5
==>

I have found a much simpler way if having multiple files doesnt matter where you log it to a .txt file and use "set /a" in batch to simple calculate it.
In the vbs file:
calculation = inputbox("What do you want to calculate?(include =)", "Eclips-Terminal Calculator")
oFile.write "" & calculation & ""
oFile.close
wsh.run "calculator.bat"
wscript.sleep 3000
msgbox rfile.readall
oFile.close
In the batch file(calculator.bat):
#echo off
set /p math=<RAM.txt
set /a calculation=%math%
echo. >> RAM.txt
echo %calculation% >> RAM.txt
And then a text file called "RAM.txt".
Its my nice, clean and simple way wich isnt too hard to pull of.
EDIT: I know this is a 4 year old question i just couldnt find a simple fix so i added it here so others can find it.

Related

VBScript if typed response = Minute(now) Invalid procedure error

When you type the minute to be the same as the current minute (Ex. you type in 20 and its currently 1:20) I want it to end the script. Instead it gives me
Invalid procedure call or argument error.
Dim Ho, Mi, Se, RH, RM, RS
bOuterLoop = True
Do While bOuterLoop
reminder = InputBox(vbNewLine & "Enter a reminder for today," & " " &
WeekdayName(Weekday(Now())) & " " & MonthName (Month(Now)) & " " & (Day(Now)) & ", " & (Year(Now)) & "!", "Set a Reminder")
If IsEmpty(reminder) Then
WScript.Quit
End If
If reminder="" then
reminder="REMINDER FOR YOU"
end if
Ho = InputBox(vbNewLine & "At what hour would you like to be reminded?(24H)", "Time")
If IsEmpty(Ho) Then
WScript.Quit
End If
if Ho = "" then
WScript.Quit
End If
Mi = InputBox(vbNewLine & "At what minute in the hour do you want to be
reminded?", "Time")
If IsEmpty(Mi) Then
WScript.Quit
End If
if Mi = "" then
WScript.Quit
End If
RH = Hour(Now)
RM = Minute(Now)
RS = Second(Now)
if Mi = RM then
a=msgbox(reminder, 0, "")
wscript.quit
end if
Ho = Ho - RH
Se = RS
if RM > Mi then
Mi = Mi + 60
end if
Mi = Mi - RM
Do
WScript.Sleep (3600000 * Ho) + ((60000 * Mi) - (1000 * Se))
answer = MsgBox(reminder & " " & vbNewLine & vbNewLine & "Would you like to snooze the reminder? ", 4+64, "Reminder")
If answer = vbNo Then
WScript.Quit
bOuterLoop = False
Exit Do
End If
Loop
Loop
Please explain what I'm doing wrong.
I am not sure about the logic which you are using here but I think the 'If' condition comparing the values of variables 'Mi' and 'RM' is returning False.
Suppose the current time is 1:20.
In your code, the variable Mi stores the input taken from the user which is of type vbString. Suppose the user enters 20. So, your variable looks something like this:
Mi="20"
The variable RM stores Minute(now) which is of type vbInteger. So, it would look something like this:
RM=20
Now when you compare these two variables, they are not equal. Hence, the If condition returns False and your script does not end.
You can make the following change in your code:
If Cint(Mi) = RM then
a=msgbox(reminder, 0, "")
wscript.quit
End If

Remove duplicate values from a string in classic asp

I have below code in classic asp
str=Request.Form("txt_str")
"txt_str" is text box in a classic asp form page where I am entering below values:
000-00001
000-00001
000-00001
000-00002
response.write str
hence str will be 000-00001 000-00001 000-00001 000-00002
array = split(str,Chr(44))
if str <> "" then
x=empty
for i = 0 to ubound(array)
if array(i) <> "" then
array_2 = split(array(i),chr(13) & chr(10))
for j = 0 to ubound(array_2)
if array_2(j) <> "" then
if x=empty then
x= "'" & array_2(j) & "'"
else
x= x & ",'" & array_2(j) & "'"
end if
end if
next
end if
next
End if
response.write x
hence x will be returned as '000-00001','000-00001','000-00001','000-00002'
I want to remove duplicate values from x and display only it as:
x = '000-00001','000-00002'
How can i achieve this.Any help on this would be appreciated.
Thanks
To remove duplicates of string lists, the best option IMO is to use a Dictionary object. You can use this short function to do the task on a given string array:
Function getUniqueItems(arrItems)
Dim objDict, strItem
Set objDict = Server.CreateObject("Scripting.Dictionary")
For Each strItem in arrItems
objDict.Item(strItem) = 1
Next
getUniqueItems = objDict.Keys
End Function
A simple test:
' -- test output
Dim arrItems, strItem
arrItems = Array("a","b","b","c","c","c","d","e","e","e")
For Each strItem in getUniqueItems(arrItems)
Response.Write "<p>" & strItem & "</p>"
Next
This is a sample for your use case:
' -- sample for your use case
Dim strInput, x
strInput = Request.Form("txt_str")
x = "'" & join(getUniqueItems(split(str, Chr(44))), "','") & "'"
BTW, did you notice that Array and Str are VBScript Keywords, so you may run into issues with using such variable names. Therefore, I think it is common practice in VBScript to use prefixes for variable names.
If it's a ordered list, consider using a variable with last value:
lastval = ""
array = split(str,Chr(44))
if str <> "" then
x=empty
for i = 0 to ubound(array)
if array(i) <> "" then
array_2 = split(array(i),chr(13) & chr(10))
for j = 0 to ubound(array_2)
if array_2(j) <> "" then
if array_2(j) <> lastval then
lastval = array_2(j)
if x=empty then
x= "'" & array_2(j) & "'"
else
x= x & ",'" & array_2(j) & "'"
end if
end if
end if
next
end if
next
End if

Error Checking With VBScript Err Object

With the following block of code, which accesses an html span element, I am unable to check for errors. When I leave the input box empty and press "ok," the value of Err.Number doesn't change. I have user error checking enabled (On Error Resume Next) and I am checking to make sure that Err.Number is not equal to 0 (an error is ocurring). The error is being thrown, but the value of Err.Number is not changing, and this happens both when On Error Resume Next is on as well as when it is off). By the way, what is the default value of Err.Number? How does that value differ from the value of Err.Number after the Err object is cleared? If I am doing anything wrong or stating any wrong information, please inform me.
On Error Resume Next
Dim updateRate
updateRate = 0
RatePrompt()
Sub RatePrompt
updateRate = InputBox("Please enter an update rate (milliseconds)", "Update Rate")
If Err <> 0 Then
Err.Clear()
MsgBox "No Input Was Specified. Please Specify An Input."
RatePrompt()
Else If updateRate > 2000 then
rateDecision = MsgBox ("Consider entering a lower update rate" & vbCrLf & "Would you like to revise update rate?", _
vbYesNo, "Quiclock Alert")
If rateDecision = vbYes then
RatePrompt()
End If
Else If updateRate < 0 then
MsgBox "Update Rate Not Valid. The Default Value of 0 Milliseconds Will Be Used."
updateRate = 0
Else If updateRate = "" then
MsgBox "Update Rate Adjustment Cancelled. The Default Value of 0 Milliseconds Will Be Used."
updateRate = 0
Else
End If
End If
End If
End If
End Sub
TimerStart()
Sub TimerStart
timerID = window.setTimeout("TimeUpdate", updateRate, "VBScript")
End Sub
Sub TimeUpdate
clockOutput.innerHTML = Time()
window.clearTimeout(timerID)
TimerStart()
End Sub
I have spent a large amount of time researching this problem, but have not come to a conclusion. Thanks for the help.
Try next logic skelet for your script:
Dim updateRate, rateRevision
updateRate = InputBox("Please enter an update rate (milliseconds)", "Update Rate")
If IsEmpty( updateRate) Then
'`Cancel` (or equivalent `Esc` or red `×`) pressed/clicked
Else
If IsNumeric( updateRate) Then
updateRate = CLng( updateRate) 'convert string to a Variant of subtype Long
If updateRate > 2000 Then
' do not bother a user by an additional input: offer a value change right now
rateRevision = InputBox ("Consider entering a lower update rate" _
& vbCrLf & "Would you like to revise update rate?", _
"Quiclock Alert", updateRate)
If IsNumeric( rateRevision) Then
rateRevision = CLng( rateRevision)
If rateRevision > 0 Then updateRate = rateRevision
Else
' keep the value > 2000
End If
ElseIf updateRate < 0 Then
updateRate = 0
Else
''
End If
Else
'non-numeric input, use e.g. default value of zero
updateRate = 0
End If
TimerStart()
End If
An explanation and observation to the code:
There is a mistake in the InputBox Function reference. In fact: if the user clicks Cancel (or the red × or presses Esc), then the function returns an empty value, which looks like a zero-length string ("") due to automatic subtype conversion. See the 32213674.vbs script output below.
Comparison Operators (VBScript) reference shows how expressions are compared or what results from the comparison, depending on the underlying subtype; particularly: if one expression is numeric and the other is a string then the numeric expression is less than the string expression.
32213674.vbs script:
option explicit
On Error GoTo 0
Dim sValInput
Call doOutput( True, sValInput)
Do While True
sValInput = InputBox( _
"Please enter any value (and `OK`) to see its features:" & vbCR _
& "a date-like value, e.g. " & FormatDateTime( Now, vbShortDate) & vbCR _
& "a time-like value, e.g. " & FormatDateTime( Now, vbShortTime) & vbCR _
& "a number-like value, e.g. 123456" & vbCR _
& "a string of your choice" & vbCR _
& "an empty string (i.e. only click `OK`)" & vbCR _
& "or press `Esc` or click red `×` or `Cancel` button to exit the loop" _
, "InputBox test loop")
Call doOutput( False, sValInput)
If IsEmpty( sValInput) Then Exit Do
Loop
Sub doOutput( bHeader, sVal)
If Instr(1, Wscript.FullName, "cscript.exe", vbTextCompare) > 0 Then
If bHeader Then
Wscript.Echo sHead()
Else
Wscript.Echo sLine( sVal)
End If
Else
If bHeader Then
Else
MsgBox( sHead() & vbCR & sLine( sVal))
End If
End If
End Sub
Function sHead()
sHead = "Empty?" & vbTab & "Number?" & vbTab & _
"Date?" & vbTab & "VarType" & vbTab & "TypeName" & "[value]"
End Function
Function sLine( sValue)
sLine = IsEmpty( sValue) & vbTab & IsNumeric( sValue) & vbTab & _
IsDate( sValue) & vbTab & VarType( sValue) & vbTab & _
TypeName( sValue) & vbTab & "[" & sValue & "]"
End Function
Output:
==>cscript //NOLOGO D:\VB_scripts\SO\32213674.vbs
Empty? Number? Date? VarType TypeName[value]
False False True 8 String [2015-08-26]
False False True 8 String [22:01:05]
False True False 8 String [123456]
False False False 8 String [qwertz]
False False False 8 String []
True True False 0 Empty []

Trying to use Shell object and FileSystemObject in VBScript for file manipulation

I am trying to recursively loop through hundreds of directories, and thousands of JPG files to gather sort the files in new folders by date. So far, I am able to individually GetDetailsOf the files using the Shell NameSpace object, and I am also able to recursively loop through directories using the FileSystemObject. However, when I try to put them together in functions, etc, I am getting nothing back when I try to get the DateTaken attribute from the photo.
Here is my code so far:
sFolderPathspec = "C:\LocationOfFiles"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objDir = objFSO.GetFolder(sFolderPathspec)
Dim arrFiles()
getInfo(objDir)
Sub getInfo(pCurrentDir)
fileCount = 0
For Each strFileName In pCurrentDir.Files
fileCount = fileCount + 1
Next
ReDim arrFiles(fileCount,2)
i=0
For Each aItem In pCurrentDir.Files
wscript.Echo aItem.Name
arrFiles(i,0) = aItem.Name
strFileName = aItem.Name
strDir = pCurrentDir.Path
wscript.echo strDir
dateVar = GetDatePictureTaken(strFileName, strDir)
'dateVar = Temp2 & "_" & Temp3 & "_" & Temp1
arrFiles(i,1) = dateVar
WScript.echo i & "." & "M:" & monthVar & " Y:" & yearVar
WScript.echo i & "." & strFileName & " : " & arrFiles(i,1) & " : " & dateVar
i=i+1
Next
For Each aItem In pCurrentDir.SubFolders
'wscript.Echo aItem.Name & " passing recursively"
getInfo(aItem)
Next
End Sub
Function GetDatePictureTaken(strFileName, strDir)
Set objShell = CreateObject ("Shell.Application")
Set objCurrFolder = objShell.Namespace(strDir)
'wscript.Echo cstr(objCurrFolder.GetDetailsOf(strFileName, 12))
strFileNameDate = cstr(objCurrFolder.GetDetailsOf(strFileName, 12))
strFileNameDate = CleanNonDisplayableCharacters(strFileNameDate)
arrDate = split(strFileNameDate, "/")
'''FAILS HERE WITH A SUBSCRIPT OUT OF RANGE ERROR SINCE IT GETS NULL VALUES BACK FROM THE GET DETAILS OF FUNCTION'''
monthVar = arrDate(0)
yearVar = arrDate(1)
dayVar = arrDate(2)
GetDatePictureTaken = monthVar & "\" & dayVar & "\" & yearVar
End Function
Function CleanNonDisplayableCharacters(strInput)
strTemp = ""
For i = 1 to len(strInput)
strChar = Mid(strInput,i,1)
If Asc(strChar) < 126 and not Asc(strChar) = 63 Then
strTemp = strTemp & strChar
End If
Next
CleanNonDisplayableCharacters = strTemp
End Function
The "Subscript out of range" error when accessing arrDate(0) is caused by arrDate being empty (UBound(arrDate) == -1). As a Split on a non-empty string will return an array, even if the separator is not found, and an attempt to Split Null will raise an "Invalid use of Null" error, we can be sure that strFileNameDate is "".
Possible reason for that:
The index of "Date Picture Taken" is 25 (XP) and not 12 (Win 7) - or whatever came to Mr. Gates' mind for Win 8.
The DPT property is not filled in.
Your cleaning function messed it up.
You have to test for strFileNameDate containing a valid date and decide where to put the files without a valid DPT.
P.S. Instead of doing the recursive loopings, you should consider to use
dir /s/b path\*.jpg > pictures.txt
and to process that file.

VB Script Error - Worked before but now not confusingly

i am getting a error
The VB file reads col1 and finds the matching image name in the directory and the renames that file to col2 it produces a report to show what images haven't been renamed and placed the ones that have in a folder called rename
i have attached the code so you can see
strDocMap = "C:\img\DocMap.xlsx"
strInputFolder = "C:\img\"
strOutputFolder = "C:\img\renamed\"
strLogFile = "C:\img\RenamingLog.txt"
strPattern = "\d{5}"
Set regExpression = New RegExp
With regExpression
.Global = True
.IgnoreCase = True
.Pattern = strPattern
End With
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Const xlUp = -4162
Const xlFormulas = -4123
Const xlPart = 2
Const xlByRows = 1
Const xlNext = 1
Set objWB = objExcel.Workbooks.Open(strDocMap, False, True)
Set objSheet = objWB.Sheets(1)
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Right(strInputFolder, 1) <> "\" Then strInputFolder = strInputFolder & "\"
If Right(strOutputFolder, 1) <> "\" Then strOutputFolder = strOutputFolder & "\"
If objFSO.FolderExists(strOutputFolder) = False Then objFSO.CreateFolder strOutputFolder
Set objLog = objFSO.CreateTextFile(strLogFile, True)
objLog.WriteLine "Script started " & Now
objLog.WriteLine "Enumerating files in folder: " & strInputFolder
objLog.WriteLine "Renaming files to folder: " & strOutputFolder
objLog.WriteLine String(80, "=")
For Each objFile In objFSO.GetFolder(strInputFolder).Files
Set colMatches = regExpression.Execute(objFile.Name)
If colMatches.Count > 0 Then
If colMatches.Count = 1 Then
For Each objMatch In colMatches
strOldNum = objMatch.Value
Set objCell = objSheet.Cells.Find(strOldNum, objSheet.Range("A1"), xlFormulas, xlPart, xlByRows, xlNext, False, False)
If Not objCell Is Nothing Then
strNewNum = objCell.Offset(0, 1).Value
If strNewNum <> "" Then
strNewPath = strOutputFolder & strNewNum & "." & objFSO.GetExtensionName(objFile.Path)
' Check if a file already exists without the appended letter
blnValid = True
If objFSO.FileExists(strNewPath) = True Then
blnValid = False
' Start at "a"
intLetter = 97
strNewPath = strOutputFolder & strNewNum & Chr(intLetter) & "." & objFSO.GetExtensionName(objFile.Path)
Do While objFSO.FileExists(strNewPath) = True
intLetter = intLetter + 1
strNewPath = strOutputFolder & strNewNum & Chr(intLetter) & "." & objFSO.GetExtensionName(objFile.Path)
If intLetter > 122 Then Exit Do
Loop
If intLetter <= 122 Then blnValid = True
End If
If blnValid = True Then
objLog.WriteLine "Renaming " & objFile.Name & " to " & Mid(strNewPath, InStrRev(strNewPath, "\") + 1)
objFSO.MoveFile objFile.Path, strNewPath
Else
objLog.WriteLine "Unable to rename " & objFile.Name & ". Letters exhausted."
End If
End If
End If
Next
Else
objLog.WriteLine objFile.Name & " contains " & colMatches.Count & " matches. Manual adjustment required."
End If
End If
Next
objLog.WriteLine String(80, "=")
objLog.WriteLine "Script finished " & Now
objWB.Close False
objExcel.Quit
objLog.Close
MsgBox "Done"
Thanks
Jack
If line 68
objLog.WriteLine objFile.Name & " contains " & colMatches.Count & " matches. Manual adjustment required."
is really the culprit, I would argue:
The objects objLog, objFile, and colMatches were used before -
acquittal
The methods .WriteLine, .Name, and .Count look good - acquittal
Concatenation (&) should work on string literals and not
null/empty/nothing elements - acquittal
By elimination: objFile.Name contains a funny letter (not
convertable to 'ASCII'). Easy check: Replace "objFile.Name" with a
string literal.
Evidence
Dim s
For Each s In Array(Empty, Null, ChrW(1234))
On Error Resume Next
goFS.CreateTextFile("tmp.txt", True).WriteLine s
WScript.Echo Err.Description
On Error GoTo 0
Next
output:
====================================
Type mismatch
Invalid procedure call or argument
====================================

Resources