VBS won't allow programming - vbscript

I was doing some programming and I get an error message when I try and run it. my code:
MsgBox ("hi")
sleep (2)
MsgBox ("you ok" vbYesNo, "how are you?")
Select Case result
Case vbYes,
MsgBox ("that's good!")
Case vbNo, MsgBox ("sorry to hear that.")
End Select
Line: 3
Char: 18
Error: Expected ')' Source: Microsoft VBScript compilation error.

The problem is as the error says you have compilation issues but looking at the rest of the example code you also have other issues waiting to be corrected.
Missing argument syntax in MsgBox() Function:
Line: 3
Char: 18
Error: Expected ')' Source: Microsoft VBScript compilation error.
is because the Function MsgBox() expects arguments separated by a comma but the argument separator after "you ok" is missing causing the compiler to throw the exception.
Cannot use parentheses when calling a Sub:
When calling a procedure that doesn't return a value using brackets around multiple arguments passed to the procedure will cause;
Microsoft VBScript compilation error: Cannot use parentheses when calling a Sub
There is a caveat to this which is if it's just one argument it will not fail to compile, but this isn't because it accepts one argument but because it sees the brackets as part of the argument not part of the procedure (Eric Lippert discusses this at length in his blog);
MsgBox("Hi") 'Will work
This is equivalent to writing;
Call MsgBox(("Hi")) 'Note the extra brackets
This can be a little confusing so when it comes to multiple arguments you might think this is ok;
MsgBox("you ok", vbyesno, "how are you?") 'This will error
But as the brackets now denote the argument parentheses it becomes invalid and throws a compilation error. To avoid this there are three things you can do;
Remove the parentheses
MsgBox "you ok", vbyesno, "how are you?"
Return a value (if the procedure can return a value)
result = MsgBox("you ok", vbYesNo, "how are you?")
As you check the value of result on the next line this would be the correct option as it result will contain the outcome of clicking either vbYes or vbNo in the MsgBox() function.
Use the Call statement to prefix the procedure call
Call MsgBox("you ok", vbYesNo, "how are you?")
Syntax Error:
Microsoft VBScript compilation error: Syntax error
This comes down to trailing commas after the Case arguments, just remove the commas and the code will compile.
Select Case result
Case vbYes
Call MsgBox("that's good!")
Case vbNo
Call MsgBox("sorry to hear that.")
End Select
The Sleep duration:
The Sleep() function expects a value expressed in milliseconds not seconds, at the moment the example code is waiting for 0.002 seconds. To wait for 2 seconds (which I'm assuming was the intention) use;
Call Sleep(2000)
Useful links
Answer to Can't Use Parentheses When Calling a Sub - VBScript

Related

How to pass double quoted arguments into vbscript?

I am a new bee for vbScript. I have a script that I am calling with an arguments which contains double quote. Following is the call
.vbs "a" 2 where variable a is JO"N
My VbScript:
If WScript.Arguments.Count > 0 Then
MsgBox "NAME:" + WScript.Arguments.Item(0)
MsgBox "NAME:" + WScript.Arguments.Item(1)
Else
MsgBox "Please pass a parameter to this script"
End if
*Note this works when a = JON but does not work when a= JO"N. I tried putting escape characters" (Example: "WScript.Arguments.Item(0)") but it does not work.
You can't.
At least, as the WScript argument parser handles and removes all quotes from the values in Arguments collection, you can not use the default argument handling for this task.
note: And we are leaving out of the problem if the final command you are running when calling your script (you have not included how/from where you make the call) will or not have problems because the additional quote interferes argument quoting rules.
You need to use some workaround to get the double quote to reach the script. Some approachs could be:
Replace the quote and any other problematic character (use some kind of escape sequence) before calling the script and revert the process inside your script.
Save the value you want to pass into an environment variable (how to make it depends on how you are callign the script) and then retrieve the value from your script (ex. here).
Use WMI to retrieve the full command line used to start the script, including all the quotes (ex. here) and write your own argument parser routine.
From my point of view, I would use the second option.
This will work: Chr(34) & Wscript.Arguments.Item(0) & Chr(34). Here Chr(34) function returns a double quote using its ASCII code 34.

Why is it saying that there is a syntax error for the if/else statement I wrote?

I'm trying to write a program that calculates the sum of a geometric series on a TI-84.
Prompt A
Prompt R
Prompt N
If N=100 and abs(R)<1
Disp (A/1-R)
Else
Disp (A(1-R^N))/(1-r)
It says that there is a syntax error at the Else line.
Else can only be paired with an If .. Then construct, not a plain If. So:
Prompt A,R,N
If N=100 and abs(R)<1
Then
Disp A/(1-R
Else
Disp (A(1-R^N))/(1-R
In general the If.. Then .. Else .. End construct should be closed by End but in this case the program exits anyway so it makes no difference. There is some documentation of this in the official TI-BASIC manual and you can check out a more detailed version here.

VBScript Error 9 in AtEndOfStream Loop

I am using a script like this to loop through some data in a text file:
Do Until objFile.AtEndOfStream
'Check if it is not a blank line; otherwise skip it
If Len(Trim(objFile.ReadLine)) > 0 Then
'Some code
end if
Loop
I print out the values every time through and it gets all the way to end of the file (I can see that it prints every value) but when it reaches the end it always errors out. I used on error resume next and printed out Err.Number and I get error number 9 which is Subscript out of range.
The issue with the file I'm looping through is that the last line is blank. I know this because I've opened the file, removed the final blank line and then run the code and it works fine. This is an automated process though (the file is automatically sent to the FTP and the process runs by an automated task every day) so I can't go in and manually be getting rid of the last line every day. I included that If Len(Trim(objFile.ReadLine)) > 0 Then to take this blank line into account and it works fine on the lines with data but it still throws an error at the end of file.
I could have the loop end when it reaches a blank line but I would like to keep a condition in there in the case that a blank line shows up in the middle of the code for some reason down the line. I figure it'll be cleaner to figure out if it truly is the last line of the file and then end the loop.
Any ideas? Thanks for your help!
First of all, I'd like to ask you how you're actually processing that line you read in since you don't store it anywhere. You read it and pass it to Trim() for checking, but there's no way to get at that line afterwards.
If you have yet another ReadLine within the loop (thinking that's going to be the same line), that's going to be an issue since you might be reading the "blank" line within the if statement. It'll also mean you're throwing away every second line.
It seems to me you should be using something like:
Do Until objFile.AtEndOfStream
thisLine = objFile.ReadLine
If Len(Trim(thisLine)) > 0 Then
' Some code using thisLine, NOT another ReadLine.
End If
Loop
Another thing (once that issue is clarified), are you sure that the final line contains only spaces? I think that's all trim() gets rid of. It may be that there's other white space in there causing you problems, such as TAB, for example.
One way to find out would be to take a copy of an offending file and remove all but the last couple of lines. Then you can insert debug statements into your code to see what's happening:
Do Until objFile.AtEndOfStream
thisLine = objFile.ReadLine
trimLine = Trim(thisLine)
MsgBox ("[" & trimLine & "] " & CStr(Len(trimLine))
If Len(Trim(thisLine)) > 0 Then
MsgBox ("Processing it...")
' Some code using thisLine, NOT another ReadLine.
End If
Loop

Rescuing bash/system STDERR in Ruby

I'm shelling out of my Ruby script to call a system command as follows
puts "Reached point #1"
begin
system("sh my_shell_script.sh")
rescue StandardError => e
puts "There was an error"
end
puts "Reached point #2"
I purposely added an error in my shell script so it would fail (i.e. I spelled "echo" as "eho"). I would expect that my Ruby script would output that it reached marker #1, and then rescue the error to display "There was an error".
Instead, I'm getting:
"Reached point #1"
line 1: eho: command not found
"Reached point #2"
It certainly throws the correct error, but the shell error from system(...) isn't rescued. Any thoughts as to why?
From the documentation for Kernel#system:
system returns true if the command gives zero exit status, false for non zero exit status. Returns nil if command execution fails. An error status is available in $?.
This means that you have many ways to proceed (none of which involve rescuing a raised error), depending on exactly which failure information you want. If you just want to distinguish successfully executing the command with zero exit status from all forms of failure, this is the translation from your code:
puts "Reached point #1"
unless system("sh my_shell_script.sh")
puts "There was an error"
end
puts "Reached point #2"
You can of course distinguish between command execution failure and non-zero exit status by looking at the return value, and you can get the exit status code from $? if needed, as per the documentation.
Instead, I'm getting:
"Reached point #1"
line 1: eho: command not found
"Reached point #2"
So in other words, it got rescued, but not in the way that you're expecting.
What you actually want is probably more like this:
ret = system("sh my_shell_script.sh")
puts $? unless ret
http://www.ruby-doc.org/core-2.0/Kernel.html#method-i-system

Write apostrophe sign in writeln function - Pascal

How can I print the apostrophe sign in Pascal using the writeln function?
Example:
writeln('My brother's book');
wouldn't work because s book is out of "writing" function, so the compiler returns an error:
Fatal: Syntax error, ")" expected but "identifier S" found
Fatal: Compilation aborted
According to the Free Pascal Reference: The single quote character can be embedded in the string by typing it twice:
writeln('By brother''s book');
In Dev-Pascal 1.9.2 you will need three ''', for example:
writeln ('My brother'''s book');

Resources