What is a shortest expression of a conditional statement in vbscript? - syntax

For example, if I have the following code:
dim a
if a = 0 then
b = 1
else
b = 2
end if
Can I shorten this code without sacrificing its validity? Thanks.

AFAIK , there is no way to shorten this code directly, but there you can do as :
dim a,b : a =0 : b=1 ''set a = 0 & b = 1 directly
'' Now as per your requirement 'a' value might change in script flow then you can set value as
If a > 0 then b= 2
Hope this help.........

You could use the single-line syntax for the If...Then...Else statement:
If a = 0 Then b = 1 Else b = 2

For this specific case, you could write a helper function to mimic the VBA IIf function:
Function IIf(expr, truepart, falsepart)
If expr Then
IIf = truepart
Else
IIf = falsepart
End If
End Function
b = IIf(a=0, 1, 2)

The basic If block is the simplest conditional statement in VBScript. VBScript does not have support for a Ternary Operator.

Related

How do you make a Randomizer do an action, out of a lot more actions using VBScript?

I am trying to make a randomizer that will pick an action out of 5. But here's the problem, when I run the script it doesn't pick an action out of the five. It just runs the action on line 3. Here's the script that I've done:
Randomize
a=Int((5 * Rnd()) + 1)
If a=5 then dim result
result = msgbox("Are you sure you want to install?", 4 , "Select yes or no")
If a=4 then c="Yes"
If a=3 then c="No"
If a=2 then c="Maybe"
If a=1 then c="Ask Me Later"
b=inputbox("What Is Your Question?")
c=msgbox("" & c)
Those lines of code is suppose to be an oracle of sorts, with a secret.
Edit:
God, this is embarassing:
Actually I tested you code just now, aaaaand: it works fine for me. Sooo maybe you should specify your problem again?!
Answer with Select Case
Randomize()
a=Int((5 * Rnd()) + 1)
Select Case a
Case 1
c= "Ask Me Later"
Case 2
c= "Maybe"
Case 3
c = "No"
Case 4
c = "Yes"
Case 5
dim result
result = msgbox("Are you sure you want to install?", 4 , "Select yes or no")
End Select
b = Inputbox("What Is Your Question?")
c = MsgBox("" & c)
Your code is using a single line If..Then statement, which you cannot have multiple actions assigned to. Try this:
Randomize
a=Int((5 * Rnd()) + 1)
If a=5 then
dim result
result = msgbox("Are you sure you want to install?", 4 , "Select yes or no")
End If
If a=4 then c="Yes"
If a=3 then c="No"
If a=2 then c="Maybe"
If a=1 then c="Ask Me Later"
b=inputbox("What Is Your Question?")
c=msgbox("" & c)
It's worth noting (as in other answers and comments) that where you have multiple If statements, it's often better to use a select case statement like this (I've also renamed the variables for easier readability):
Randomize
randomNum=Int((5 * Rnd()) + 1)
Select Case(randomNum)
Case 1 : randomResponse = "Ask Me Later"
Case 2 : randomResponse = "Maybe"
Case 3 : randomResponse = "No"
Case 4 : randomResponse = "Yes"
Case 5 : Dim result
result = MsgBox("Are you sure you want to install?", 4, "Select Yes or No") ' this option seems unwanted given your desired behaviour
End Select
userQuestion=InputBox("What Is Your Question?")
' should probably do something with userQuestion
' if it's empty you still return the random answer from above
' so only return the response where it's not
If Len(userQuestion)> 0 Then
MsgBox(randomResponse) ' don't need to append an empty string or set it to anything
End If

Variable values in For Each loop being retained

I'm new to VBScript and I am running into some trouble. The script is making an API call and pulling account information, placing the data into a CSV file. I'm pulling the data into an array, looping through each account and, if certain properties qualify, assigning them to a variable to be written to the CSV. The problem I am having is if one account qualifies for a property, it sets the variable and if the next account doesn't qualify, the variable is still retaining the value, giving false results in the CSV.
Set SFTPServer = WScript.CreateObject("SFTPCOMInterface.CIServer")
accounts = SFTPServer.AdminAccounts
For each admin in accounts
adminName = admin.Login
Dim count : count = admin.GetPermissionsCount()
For i = 0 To CInt(count )- 1
Set permission = admin.GetPermission(i)
' AdminPermissionsPolicy:
' ServerManagement = 0,
' SiteManagement = 1,
' STManagement = 2,
' UserCreation = 3,
' ChangePassword = 4,
' COMManagement = 5,
' ReportManagement = 6,
Select case permission.Permission
case 0:
serverAdmin = "Server Admin"
case 1:
site = permission.SiteName
case 2:
stMan = "2"
case 3:
userCreate = "3"
case 4:
chPassword = "4"
case 5:
comMan = "5"
case 6:
report = "6"
End Select
Next
WriteStuff.WriteLine""+adminName+"|"+site+"|"+stMan+"|"+userCreate+"|"+chPassword+"|"+comMan+"|"+report+"")
Next
Unfortunately variables in VBScript are either at global, or function scope.
So you'll need to reset each of the variables on each iteration of the for loop.
One way would be to write Dim dummy at the top of your script, and just before the Select Case, write serverAdmin = dummy, site = dummy etc.
It's good practice to Dim explicitly all your variables, and to use Option Explicit at the top of the module to enforce that.
Here's an alternate way to do what you need without having to empty each variable on each iteration. You've already documented what each value means in your code. Instead of using comments for that purpose, define them as constants at the top of your scope block:
' AdminPermissionsPolicy:
Const ServerManagement = 0
Const SiteManagement = 1
Const STManagement = 2
Const UserCreation = 3
Const ChangePassword = 4
Const COMManagement = 5
Const ReportManagement = 6
Then you can declare an array to hold the values:
Dim a(6)
And then in your loop you can empty the array on each iteration using the Erase function. You can use the constant names instead of 0/1/2/etc and, when it comes time to write the values, you can use Join() to combine your array values into a string instead of having to concatenate 7 variables.
For each admin in accounts
adminName = admin.Login
Erase a ' Empty the Permissions array for each new account
Dim count : count = admin.GetPermissionsCount()
For i = 0 To CInt(count )- 1
Set permission = admin.GetPermission(i)
Select case permission.Permission
case ServerManagement: ' Now you can use the constant instead of "0"
a(ServerManagement) = "Server Admin"
case SiteManagement:
a(SiteManagement) = permission.SiteName
...
End Select
Next
WriteStuff.WriteLine Join(a, "|") ' Use Join() to combine array values
Next
Let's start with the output. You want to print a list of items (some of them possibly Empty) separated by "|". That should be done like this:
WriteStuff.WriteLine Join(aOut, "|")
Advantages:
You don't need to know that VBScript's concatenation operator is &, not +, because you can't even use the wrong one with Join.
You don't need to repeat the separator.
No useless pre/ap-pending of the empty string "".
Works with any number of items.
aOut needs to be initalized in the loop. That is easy with ReDim - without Preserve.
Advantages:
You don't need to know that Empty is the literal for empty/uninitialzed in VBScript.
You don't need to repeat an assignment for each variable.
Works with any number of items.
Demo code:
Option Explicit
Const cnUB = 3
Dim nTest
For nTest = 0 To cnUB
ReDim aOut(cnUB)
Select Case nTest
Case 0
aOut(0) = "A"
Case 1
aOut(1) = "B"
Case 2
aOut(2) = "C"
Case 3
aOut(3) = "D"
End Select
WScript.Echo Join(aOut, "|")
Next
output:
cscript 31565794.vbs
A|||
|B||
||C|
|||D
Disadvantage:
Putting the data into the array anonymously (just known by number/index) may be more errorprone than using distinct variable( name)s. If you need the elements for further computations it may be a good idea to define constants
wtf
Const ciReport = 1
...
aOut(ciReport) = "B"

How to I set a ruby variable based on an if-then decision tree

I want to write the following:
variable = if x
a
else
if y
b
else
c
end
end
Where if x is true, variable equals a. If x is false and y is true, variable equals b. If x and y are both false, variable equals c.
I thought this was valid ruby syntax but when I try it, the variable is always set to nil. Why is this and how do I set it correctly?
I am using ruby 1.9.3 btw
Edit: FALSE ALARM. In my example, c was set to nil which I thought was erroneous. My original syntax worked fine. I'm not sure of the StackOverflow etiquette on whether I should delete this question, advise is welcome.
Thanks for the quick responses.
Do not make it complicated! There is nothing wrong with writing
variable =
if x then a
elsif y then b
else c
end
No one will look at this code and not figure out what has happend.
There two main variants:
With a if-else-end tree:
variable =
if x
a
else
if y
b
else
c
end
end
and as a logical boolean algebra expression:
variable = x && a || ( y && b || c )
That is the same as:
variable = x && a || y && b || c
The first variant is usually preferred, then you are using complex code or calculation inside the if-else-end blocks. The second, when the simple read/logical constructions is used.
If you have an error or get an invalid result in your expression, just check your logical expression.

MSAccess Sorting column with text and numbers

I need to sort a column in my Access2010 Query correctly. It is a Textcolumn containing Strings with numbers like "CRMPPC1". The text length may vary within the column.
When I sort this it looks like
CRMPPC1
**CRMPPC10**
CRMPPC2
CRMPPC3
CRMPPC4
....
But what I need is
CRMPPC1
CRMPPC2
CRMPPC3
CRMPPC4
....
**CRMPPC10**
Can anybody help me out (preferably with SQL)? I tried various approaches like VAL, CAST etc. but nothing works so far.
If the number of characters in the text prefix is variable then I don't think there is a pure Access SQL solution, but the VBA function
Public Function ExtractNumber(textString As Variant) As Long
Dim s As String, i As Long
s = Nz(textString, "")
For i = 1 To Len(s)
Select Case Mid(s, i, 1)
Case "0" To "9"
Exit For
End Select
Next
If i > Len(s) Then
ExtractNumber = 0
Else
ExtractNumber = Val(Mid(s, i))
End If
End Function
would allow you to use a query like this
SELECT textTest.*
FROM textTest
ORDER BY ExtractNumber([textColumn]);
Try out using this 'hack' for natural order sorting. It only works for two characters, but you can modify it for more of course.
'''' ONLY WORKS WITH LAST TWO CHARACTER NUMBERS AT THE END. IF YOU HAVE THREE NUMBERS IT WILL BREAK'''''''
Function PadNumberForNatSort(strToMod) As String
If IsNumeric(Right(strToMod, 1)) = True Then
If IsNumeric(Mid(strToMod, Len(strToMod), 1)) = True And IsNumeric(Mid(strToMod, Len(strToMod) - 1, 1)) = True Then
PadNumberForNatSort = strToMod
Else
PadNumberForNatSort = Mid(strToMod, 1, Len(strToMod) - 1) & "0" & Mid(strToMod, Len(strToMod), 1)
End If
Else
PadNumberForNatSort = strToMod
End If
End Function
In your SQL: ORDER BY PadNumberForNatSort([column_name])

How to define more one condition in a While

I would like something like that :
While Not RdoRst.EOF And RdoRst(2) = "Foo"
cboComboBox.AddItem RdoRst(1)
cboComboBox.ItemData(cboComboBox.NewIndex) = RdoRst(0)
RdoRst.MoveNext
Wend
I want that the expression 1 (Not RdoRst.EOF) is evaluated first. Then if it returns true, the expression 2 is evaluated too (RdoRst(2) = "Foo"). If expression 1 return false, the expression 2 is not evaluated.
Regards,
Florian
AndAlso is not available in VB6. Try this
Do
If RdoRst.EOF Then Exit Do
If Not RdoRst(2) ="Foo" Then Exit Do
cboComboBox.AddItem RdoRst(1)
cboComboBox.ItemData(cboComboBox.NewIndex) = RdoRst(0)
RdoRst.MoveNext
Loop
The question relates to 'short circuit' evaluation of condition expressions. Well VB6 does not support this feature. I know this is stupid.
While Not RdoRst.EOF
If RdoRst(2) = "Foo" Then
cboComboBox.AddItem RdoRst(1)
cboComboBox.ItemData(cboComboBox.NewIndex) = RdoRst(0)
Else
Exit Wend
End If
RdoRst.MoveNext
Wend

Resources