vbscript won't return multidimensional array - asp-classic

This is really getting annoying. The following is a method which is contained in a custom database class. I query data into a recordset then try to convert this data into an array w/o field names. It appears to be working within the function because I setup a response.write to check if there were any values. But once out of the function, things go haywire (the array is not the same).
Public Function To2Array()
dim A, x, columns
columns = Rs.Fields.Count
Rs.MoveFirst()
x = 0
do until Rs.EOF
Redim A(x+1,columns)
for y = 0 to columns - 1
A(x,y) = Rs.Fields.Item(y)
response.write A(x,y) 'returns correct value
Next
x = x + 1
Rs.MoveNext()
loop
To2Array = A
End Function
I assign the return array but there appears to be nothing.
arr = db.To2Array()
response.write(arr(1,0)) 'returns nothing
Can anyone figure out what I'm doing wrong?

You can only grow the last dimension of an VBScript array. So you
need an colsXrows array.
To keep the 'old' part of a dynamic array, you must ReDim Preserve.
To get a two dimensional array from a recordset, use .GetRows - and avoid all risks of 'rolling your own'.

You lose the values in A every time you redim it. Using redim preserve prevents this, but you can only redim the last array dimension when you use preserve.

Related

How to empty a multidimensional array?

I wrote an CSV import function. The CSV file gets seperated into columns and rows and is then saved into a multidimensional array.
At one point, I need to set the multidimensional array to Empty, because the following If-condition checks for IsEmpty().
I already tried this:
aMultidimArray = Empty
aMultidimArray = Nothing
ReDim aMultidimArray(0,0)
Erase aMultidimArray
a = Split(sData, sDelimiter)
For Each x In a
'*** Resize and write into multidimensional array
ReDim Preserve aMultidimArray(iFirstDim, iSecondDim)
aMultidimArray(i - 1,iSecondDim) = x
If (i = iFirstDim + 1) Then
i = 0
End If
i = i + 1
Next
'***Empty array here
???
'***
GetDataFromCSV = aMultidimArray
'**** other script
If IsEmpty(GetDataFromCSV) Then
Do stuff
End If
The IsEmpty(GetDataFromCSV) should return true, but I cannot handle it.
It is NOT about clearing the array. It's about getting it uninitialized again. If this is even possible.
As a workaround (or maybe just a better solution) I just called Exit function. As a result the return value is Emptyand the IsEmptycondition will return True.
When in doubt, read the documentation:
IsEmpty returns True if the variable is uninitialized, or is explicitly set to Empty; otherwise, it returns False. False is always returned if expression contains more than one variable.
Since your variable absolutely is initialized, even if you remove all values from the array, why would you expect IsEmpty to return anything but False?
Depending on what you actually want to achieve with your code you could check the dimensions of your array:
If UBound(GetDataFromCSV, 1) = -1 And UBound(GetDataFromCSV, 2) = -1 Then
'array is a 0x0 array
End If
If your array is not zero-sized you probably need to iterate over all fields and check if those are empty.
If you think you need to reset a variable that was defined as an array to Empty I suspect you made a design error somewhere, so I would strongly recommend to go back and fix the design. However, if you absolutely must reset an array variable to Empty for some reason you should be able to do so like this:
ReDim a(2, 5) 'define variable as array
...
Dim a 're-define variable as regular variable; does not clear the value
a = Empty 'clear variable

Julia string concatenation gives an array that elements are broken to individual characters

I hope I get someone who understand this. I have been trying to concatenate Julia string for quit a while now but I still have an issue. I have this loop where I am trying to concatenate the string and a number from the loop then add the new value to an array, everything is fine when I print the value in the loop but printing the arrays then all the elements of the array are split again to individual characters.
my code is as bellow
a = 1
for i in nums_loop
i_val = i[a]
append!(const_names, (string(x, string(a))))
println(string(x, string(a)))
a += 1
end
print(const_names)
the output is as bellow
X1
X2
Any['X', '1', 'X', '2']
This seems the easiest way: first initiliaze your array_names with an empty string, later removing it with popfirst! (bad practise to call the array constant if you are actually changing its content)
array_names=[" "]
num_loops=2
for i=1:num_loops
push!(array_names, "X$i")
end
popfirst!(array_names)
println(array_names)
This gives me the result:
julia> println(array_names)
["X1", "X2"]

Simple broken For Each Loop in VB6

I am writing a Contains method for vb6 collections that hold strings.
However I cannot get the syntax right on my foreach.
What should I change?
Public Function Contains(col as Collection, key as Variant) as Boolean
Dim thing as Object '// this is the key
For Each thing in col
If CStr(key) = CStr(thing) then
Contains = True
Exit Function
End If
Next
Contains = False
End Function

Stack overflow error when do a loop inside another loop

In a classic ASP function, when I do a loop inside another as shown in the code below I have a stack overflow error.
Function shift(x,y)
shift = x
For i = 1 to y
shift = shift*2
Next
End Function
Function translate_url(iVal)
sAlpha = "abcdefghijklmnopqrstuvwxyz-_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
doWrite = False
iBase = 63 'DO NOT CHANGE
For i = 4 to 0 step -1
iPos = (iVal and shift(iBase, i*6))/shift(1, i*6)
If iPos Then doWrite = True
If doWrite Then translate_url = translate_url & Mid(sAlpha, iPos + 1,1)
Next
End Function
arr = Split("1,2,3,4,5,6,7,8,9,0",",")
For Each i In arr
response.Write(translate_url(arr(i)))
next
The error does not occur when I remove the loop outside the function. Eg:
response.Write(translate_url(arr(1)))
return "c".
What I need to do to make the code flows down the array and return the corresponding values ​​according to the function?
VBScript has a dark side. Variables scope is one of them.
When you don't declare a variable, VBScript will do it for you, free of charge or error and give it global scope.
What does it mean? Take a look in the main loop:
For Each i In arr
response.Write(translate_url(arr(i)))
next
The i variable becomes global. When you have this later in the function:
For i = 4 to 0 step -1
'...
Next
It's changing the same i variable. This is causing endless loop of function calls.
To resolve this, declare i locally in each function:
Function shift(x,y)
Dim i
'...
End Function
Function translate_url(iVal)
Dim i
'...
End Function
And it will be different variable and no overflow.
As the EVIL global variable i is used in your top level loop and in the functions shift() and translate_url(), you got what you deserve.
Evidence: Just change your loop to
For Each NoliMeTangere In arr
response.Write translate_url(arr(NoliMeTangere))
next
Remedy: Use "Option Explicit" and Dim all local variables in your Subs/Functions/Methods.

ASP - Randomize function returning same value for two different seeds

So I'm generating a random number using Rnd and Randomize to set a seed that looks like this:
Randomize lSeed
Response.Write Rnd
I'm noticing that it's returning the same result for two values in a row for lSeed (e.g. 123, 124) but then on say 125 it will return a new value but 126 will be the same as the on for 125. Why would this be?
Edit:
I have tried something like this
Randomize
Randomize lSeed
Response.write Rnd
And I get the same results I described above.
That's the problem with random numbers...
http://web.archive.org/web/20011027002011/http://dilbert.com/comics/dilbert/archive/images/dilbert2001182781025.gif
You should reseed before getting a random value each time. I'd recommend seeding to a timer.
you can also seed off of the current time that seems to work pretty well
' For ASP, you can create a function like:
Public Function RandRange(ByVal low As Integer, ByVal high As Integer) As Integer
Randomize()
Return ((Rnd() * (high - low)) + low)
End Function
' For ASP.NET, you can create a function like:
Private _rnd As System.Random()
Public Function RandRange(ByVal low As Integer, ByVal high As Integer) As Integer
' Purpose: Returns Random Integer between low and high, inclusive
' Note: _rnd variable must be defined outside of RandRange function
If _rnd Is Nothing Then
_rnd = New System.Random()
End If
Return _rnd.Next(low, high)
End Function
The issue was that the value for the seed was too large in the other environment (an incrementing database value). I ended up doing value Mod 100 to get something semi-random and that was going to be low to always work.

Resources