Integer and String comparison conflict in VBScript - vbscript

The below VBScript code while trying to run in HP-UFT confused me because the first statement prints True instead of False (which does not seem logical), while the second one prints False (which seems logical)
Code:
print 40 = "40"
a = 40
b = "40"
print a = b
Output:
True
False

It's perfectly logical (cough), there is only one data type in VBScript and that is Variant. However VBScript can handle many different sub types of the Variant data type.
When you compare
40 = "40"
VBScript is implicitly converting the String sub type to an Integer sub type and comparing the result which is the same as performing the following explicit conversion;
40 = CInt("40")
If you already have your variants defined however VBScript only attempts to implicitly convert them if the execution context fits (when it fits is a bit hazy and in some cases a straight up bug - See Ref).
To avoid this use explicit conversions when necessary.
a = CInt(b)
Useful Links
A: VBScript implicit conversion in IF statement different from variable to literals?
MSDN Blog - Typing Hard Can Trip You Up (Eric Lippert)

Related

How to call Lua table value explicitly when using integer counter (i,j,k) in a for loop to make the table name/address?

I have to be honest that I don't quite understand Lua that well yet. I am trying to overwrite a local numeric value assigned to a set table address (is this the right term?).
The addresses are of the type:
project.models.stor1.inputs.T_in.default, project.models.stor2.inputs.T_in.default and so on with the stor number increasing.
I would like to do this in a for loop but cannot find the right expression to make the entire string be accepted by Lua as a table address (again, I hope this is the right term).
So far, I tried the following to concatenate the strings but without success in calling and then overwriting the value:
for k = 1,10,1 do
project.models.["stor"..k].inputs.T_in.default = 25
end
for k = 1,10,1 do
"project.models.stor"..j..".T_in.default" = 25
end
EDIT:
I think I found the solution as per https://www.lua.org/pil/2.5.html:
A common mistake for beginners is to confuse a.x with a[x]. The first form represents a["x"], that is, a table indexed by the string "x". The second form is a table indexed by the value of the variable x. See the difference:
for k = 1,10,1 do
project["models"]["stor"..k]["inputs"]["T_in"]["default"] = 25
end
You were almost close.
Lua supports this representation by providing a.name as syntactic sugar for a["name"].
Read more: https://www.lua.org/pil/2.5.html
You can use only one syntax in time.
Either tbl.key or tbl["key"].
The limitation of . is that you can only use constant strings in it (which are also valid variable names).
In square brackets [] you can evaluate runtime expressions.
Correct way to do it:
project.models["stor"..k].inputs.T_in.default = 25
The . in models.["stor"..k] is unnecessary and causes an error. The correct syntax is just models["stor"..k].

How can I see the actual binary content of a VB6 Double variable?

I have hunted about quite a bit but can't find a way to get at the Hexadecimal or Binary representation of the content of a Double variable in VB6. (Are Double variables held in IEEE754 format?)
The provided Hex(x) function is no good because it integerizes its input first.
So if I want to see the exact bit pattern produced by Atn(1), Hex(Atn(1)) does NOT produce it.
I'm trying to build a mathematical function containing If clauses. I want to be able to see that the values returned on either side of these boundaries are, as closely as possible, in line.
Any suggestions?
Yes, VB6 uses standard IEEE format for Double. One way to get what you want without resorting to memcpy() tricks is to use two UDTs. The first would contain one Double, the second a static array of 8 Byte. LSet the one containing the Double into the one containing the Byte array. Then you can examine each Byte from the Double one by one.
If you need to see code let us know.
[edit]
At the module level:
Private byte_result() As Byte
Private Type double_t
dbl As Double
End Type
Private Type bytes_t
byts(1 To 8) As Byte
End Type
Then:
Function DoubleToBytes (aDouble As Double) As Byte()
Dim d As double_t
Dim b As bytes_t
d.dbl = aDouble
LSet b = d
DoubleToBytes = b.byts
End Function
To use it:
Dim Indx As Long
byte_result = DoubleToBytes(12345.6789#)
For Indx = 1 To 8
Debug.Print Hex$(byte_result(Indx)),
Next
This is air code but it should give you the idea.

Invalid Control loop error with array

I have a fairly complex look of code where I am looking through multiple control variables.
I am getting an error 'Invalid 'for' loop control variable
the line in questions is
for w(1) = 32 to 127
I am more familiar with VBA where I would have zero problem with this statement.
I'm guessing it has something to do with the fact that i will be looping through w(1),w(2),w(3) etc. in the same tree. I initialize the variable as dim x(10) but have also tried dim w() , dim w() redim w(10)
Any thoughts? its a fairly critical aspect of the script; as such I am unwilling to swap out all my w 1,2... for individual variables
Thoughts?
EDIT:
As per comments I should clarify a Few things:
Essentially there is a alpha numeric association with an ID in a system that I am working with which I was not handed down the key too. So I have a multi-dimensional array of rates that are used for multiplying out costs.
What I am doing is working backwards through invoices and matching a material with very subtle differences that have different pricings.
For simplicity sake, say theres a 2 dimensional material where AA, AB, ... A9 are all priced through several multiplication factors in what would just be a 2x2 grid. So maintaining a pivot point based on the position in string is very important. For this code you could take tier to mean how many characters in the string (aka how complex the composition of the material):
dim x(), w()
for tier = 1 to 2
for w(1) = 32 to 127
x(1)= chr(w(1))
If tier = 2 then
for w(2)= 32 to 127
X(2)=chr(w(2))
next
end if
str = ""
for y = 1 to (tier)
str = trim(str & x(y))
next
'''msgbox str 'debug
next
end if
str = ""
for y = 1 to (tier)
str = trim(str & x(y))
next
'' msgbox str ' debug
next 'tier
This is just an excerpt i pulled to get a basic idea of the structure w/o any calculations. this is in essence what is not working
The error is quite clear, you cannot use an Array as the control variable. The definition in For...Next Statement is even clearer;
Numeric variable used as a loop counter. The variable cannot be an array element or an element of a user-defined type.
This is one of the key differences between VBA and VBScript.
You won't loop through x(1),x(2)...on what you write it's going like this 32(1),33(1)....what type it's your w(1) and how you define him?

vbscript Type mismatch error when calling function

I am running into the Type Mismatch error when I attempt to call a function I created.
Example:
Function DoThis(paramA, paramB, paramC)
If paramA = "Something" Then
DoThis = DoSomething
ElseIf paramA = "This" Then
DoThis = DoSomethingDifferent
Else
DoThis = DoThisOtherThing
End If
End Function
Dim result: result = DoThis(valueA, ValueB, ValueC)
Can anyone see what my mistake could be? Other functions are working correctly. I have double checked the spelling by actually copying and pasting the function name where I call it. I have verified that the function name is not used anywhere else, i.e., as a constant or something else.
Note that when debugging this the ValType for all arguments is vbString. Also I am never able to enter the function, so it is not like I am debugging the function, enter it and then get the type mismatch.
ty.
VBScript has only one data type called a Variant. A Variant is a special kind of data type that can contain different kinds of information, depending on how it is used. Because Variant is the only data type in VBScript, it is also the data type returned by all functions in VBScript.
There are some subtypes of data that a Variant can contain (e.g. Empty, Null, string, integer, object, array etc.) You can use some conversion functions to convert data from one subtype to another, if that conversion is not implicit in VBScript. Now, pay your attention to real, factual data subtype of True and vbTrue.
The True keyword (boolean literal) has a value (inner representation) equal to -1.
On the other hand, vbTrue is one of few built-in constants and, in despite of it's name, has a subtype of Integer! It's one of so-called Tristate Constants:
Constant Value Description
vbUseDefault -2 Use default from computer's regional settings.
vbTrue -1 True
vbFalse 0 False
I hope next code could make clear all above statements:
Wscript.Echo _
vbTrue, CStr( vbTrue), VarType( vbTrue), TypeName( vbTrue) , _
vbNewLine, True, CStr( True), VarType( True), TypeName( True)
However, used with If _condition_ Then ..., there are some particularities; in brief:
The Then part of the If ... statement conditionally executes groups of statements only when a single test If condition is not False, i.e. any non-zero number esteems to be true, not only -1. Therefore you are able to use whatever variable or expression (numeric or string) you choose as long as the result is numeric...
Summarizing: If _expr_ Then ... is the same as
If CBool(_expr_) Then ...
The reason why retval is retuning mismatch error because it has a numeric value and an alpha value and wsh does not like that.
A sure way to get a type mismatch error for the published code is to define DoSomething etc. as Subs (which seems probable, given the names).
I cannot explain why this was a problem, but today I reduced the function down to a simple boolean return value and I still got the type mismatch error.
So I then created a new function with the same parameters and such. When I changed the call to the new function the error goes away.
My original function with the simple boolean return:(MISMATCH ERROR)
Function IsInstalledCheck(valueToCheck, expectedValue, checkType)
IsInstalledCheck = vbFalse
End Function
My new function with the a simple return:(Works)
Function IsItemInstalled(valueToCheck, expectedValue, checkType)
IsItemInstalled = vbFalse
End Function
EDIT
Note that I had tried this with the standard True / False values as well. The solution was to simply recreated the same function with a new name and for whatever magical reason that worked. The function signature was the same, the order of variables, variable names, the test conditions, everything in the body of the new function is the same.

What side-effects arise from setting a Long variable equal to False?

I am working on a piece of legacy code at work and I ran into a variable assignment that raises some questions for me. The variable PortOpen was declared with its type set as Long, and later in the code it was set equal to False. Since the integer value of False is 0, I assume that this will just mean the PortOpen will be 0 until it is modified, but I am suspicious that this might introduce some subtle bugs. A Long is twice the size of a Boolean in this case, so is there any possibility for an error when later using PortOpen in a logic comparison? Or, just in general, are there any quirks or other effects of using this type of variable assignment?
This is of course a bad thing as it is confusing for a person reading the code, but as long as you use 0/False for the false values and -1/True for true values the program should work fine.
You need to watch out for using 1 for True, as that will give you ambigous results. 1 (or in fact any value other than 0) will give you True in logical comparisons, so this will display "True":
Dim myvar As Long
myvar = 2
If myvar Then
MsgBox "True"
Else
MsgBox "False"
End If
However, the problem arises when you apply a "Not" to this expression. Generally you would expect "Not True" to be "False", but the following code will display "True":
Dim myvar As Long
myvar = 2
If Not myvar Then
MsgBox "True"
Else
MsgBox "False"
End If
So, apart from being bad for readability of your code, using Integer or Long for booleans CAN lead to errors in your code.
As you say PortOpen will be 0 after the automatic conversion of True to a Long, there are no other side effects of this assignment.
Aside from being bad practice & confusing for others the only other potential problem would be any assumption that PortOpen = 1 = True which is not the case as Clng(True) is -1.
Personally I would replace the assignemtnet with 0 or a 0 CLOSED symbolic constant/enum.

Resources