How to do prime reading through a 2D array in asp pages - arrays

For my school project I am supposed to read values from HTML form which has 30 rows and 4 columns.
I've made a 2d array and made the reading like this (please ignore the validation parts):
Sub primeRead()
For i = 0 To 29
cDetails(i, 0) = Request.Form("UnitCode_" & rowID+1)
If cDetails(i,0) = " " Then
response.write("Hello")
Exit For
End If
cDetails(i, 1) = Request.Form("CP_" & rowID)
If cDetails(i, 1) = "15" Or "20" Then
'response.write("Credits points must be 15 or 20")
'Exit For
End If
cDetails(i, 2) = Request.Form("YS_" & rowID)
If cDetails(i, 2) = " " Then
response.write("Hello")
Exit For
End If
cDetails(i, 3) = Request.Form("UM_" & rowID)
If cDetails(i,3) = " " Then
response.write("Hello")
Exit For
End If
rowID = rowID + 1
i = i + 1
Next
End Sub
However, when I output the input taken from the form like this:
<%For x = 0 To 29%>
<tr>
<td> <%response.write(cDetails(x, 0))%><td/>
<td> <%response.write(cDetails(x, 1))%><td/>
<td> <%response.write(cDetails(x, 2))%><td/>
<td> <%response.write(cDetails(x, 3))%><td/>
<td> <%response.write(cDetails(x, 3))%><td/>
<tr/>
<%Next%>
it only shows up to 15 rows. Is there any limitations with 2D arrays VBScript or something else causing this undesirable output?

You're misunderstanding how For loops work. The loop variable is automatically. Incrementing the variable in the loop body on top of that like you do will cause the code to skip every second row. Remove the line i = i + 1 from the loop:
For i = 0 To 29
...
i = i + 1
Next
Also, the condition cDetails(i, 1) = "15" Or "20" will not work the way you seem to expect. It will check if the value cDetails(i, 1) equals "15" or if the string "20" is true. If you want to compare a variable with more than one value you must compare the variable with each value individually:
If cDetails(i, 1) = "15" Or cDetails(i, 1) = "20" Then
...
End If

Related

Cycle through variables incremented by a digit

I have an Access form where a bunch of sections are repeated, ex: Name, Age, Gender. The variable names for these text boxes are: Name1, Name2, ...; Age1, Age2, ...; etc.
I want to store all these values in an Array after a button is pressed. Instead of hardcoding all the variable names, I was wondering if there is a way to cycle through these in a for loop e.g.:
For i = 1 to 4
ArrayName(i) = ("Name" & i).value
ArrayAge(i) = ("Age" & i).value
ArrayGender(i) = ("Gender" & i).value
next i
I can get the string Name1 by ("Name" & i) but when I add .value after it, it doesn't seem to work.
I have also tried storing the variable name as a string into another array and then trying to use that array element to get the value, but that doesn't work either.
The error is because code is just building a string "Name1" and string does not have Value property. Consider:
Me.Controls("Name" & i).Value
or simplify with:
Me("Name" & i)
Value is default property so don't have to reference. However, the Me qualifier is important, otherwise the array will just populate with the control's name "Name1", not the control's value.
Arrays are 0-base by default which means the element index begins with 0 so iterating 1 to 4 to reference array elements will not provide correct results. Consider:
ArrayName(i - 1) = Me("Name" & i)
Otherwise, declare arrays as 1-base with Option Base 1 in module header.
Instead of 3 1-dimension arrays, a single 2-dimension array might serve.
Dim aryD(4, 3) As Variant, x As Integer, y As Integer
For x = 1 To 4
For y = 1 To 3
aryD(x - 1, y - 1) = Me(Choose(y, "Name", "Age", "Gender") & x)
Next
'verify array elements values
Debug.Print aryD(x - 1, 0) & " : " & aryD(x - 1, 1) & " : " & aryD(x - 1, 2)
Next

VBA - Only run if statement when array is not empty still runs even when array is empty,

I have code that creates an array and enters "supplier names" or "null" (actual string null) into an array if certain conditions are met. If certain conditions are not met, the array will not be filled with any data and is thus empty (or so I believe).
The next thing I want to do is print out only the supplier names listed in that array. Hence I have to create an If statement that will only be entered when the item in the array does not have the value "null" and when the array is not empty.
I'm experiencing the following problem in the code below. The string array supplierCategoryP(r) did not meet the conditions and thus was never filled with any information. So I assume this is an empty array. Yet when I debug, the code shows that this first If is still entered:
If supplierCategoryP(r) <> "null" And Not IsEmpty(supplierCategoryP(r)) Then
...while it shouldn't, since the array is empty.
k = 1
If countNoNull > 0 Then
moveDownBy = countNoNull
For r = 1 To nP
If supplierCategoryP(r) <> "null" And Not IsEmpty(supplierCategoryP(r)) Then
Cells(9 + k + moveDownBy, 5) = supplierCategoryP(r)
k = k + 1
countNoNull = countNoNull + 1
End If
Next r
Else
For r = 1 To nP
If supplierCategoryP(r) <> "null" And Not IsEmpty(supplierCategoryP(r)) Then
Cells(9 + k, 5) = supplierCategoryP(r)
k = k + 1
countNoNull = countNoNull + 1
End If
Next r
End If
Code that creates the array:
Worksheets("PEMCO").Activate
comNO = CLng(Range("commoditiesAmount").Text)
nP = CLng(Range("supplierAmount").Text)
ReDim supplierCategoryP(1 To nP) As String
For c = 1 To comNO
commodityLoop = Cells(3, 1 + c)
If commodity = commodityLoop Then
For r = 1 To nP
cellX = Cells(3 + r, 1 + c)
If cellX = "x" Then
supplierCategoryP(r) = Cells(3 + r, 1)
Else
supplierCategoryP(r) = "null"
End If
Next r
End If
Next c
Note that the IsEmpty function doesn't work on a null string, it tests for empty numeric value. You can verify this in the Immediate pane:
?IsEmpty("")
False
since you've ReDim your array to a specific number of items, all of those items are initialized as an empty string by the ReDim statement. Later, you assign to (overwrite) some those items with either the value from the cell, or the "null" value. The other cases will still retain the vbNullString from initialization.
To check for an empty string, you'd need to test whether supplierCategoryP(r) = vbNullString (this is the built-in constant which expresses "").
Or, if you consider spaces or sequence of spaces " " to be empty, you'd use Trim:
Trim(supplierCategoryP(r)) = vbNullString
Note also, and this may seem pedantic, but it's important: an empty array is not the same as an array that's been initialized which contains "empty" values. Your array is never empty, even if it contains nothing but "empty" (vbNullString) values.

Array search/compare is slow, compare to Excel VBA

I just switched from VBA (Excel) to VB (Visual Studio Express 2013).
Now I have copied parts of my code from VBA to VB.
And now I'm wondering why VB is so slow...
I'm creating an Array (IFS_BV_Assy) with 4 column and about 4000 rows.
There are some identical entrys in it, so I compare every entry with each other and override the duplicate with a empty string.
The Code looks like that:
For i = 1 To counter
For y = 1 To counter
If IFS_BV_Assy(1, y) = IFS_BV_Assy(1, i) And i <> y Then
If IFS_BV_Assy(2, i) < IFS_BV_Assy(2, y) Then
IFS_BV_Assy(1, i) = ""
Else
IFS_BV_Assy(1, y) = ""
End If
Exit For
End If
Next
Next
Counter is the lenght of the Array.
In VBA it takes about 1 Sec. In VB it takes about 30 Sec. to go thru the loop. Somebody knows why? (im creating some Timestamp between every Step to be sure whats slow. And that loop is the bad guy)
The Array looks like this:
(1,1) = 12.3.015 / (2,1) = 02
(1,2) = 12.3.016 / (2,2) = 01 <-- delete
(1,3) = 12.3.016 / (2,3) = 02 <-- keep, because 02 is newer then 01
(1,4) = 12.3.017 / (2,4) = 01
(1,5) = 12.3.018 / (2,5) = 01
Thanks in advance
Andy
Edit: I create the Array like that:
strStartPath_BV_Assy = "\\xxx\xx\xx\"
myFile = Dir(strStartPath_BV_Assy & "*.*")
counter = 1
ReDim IFS_BV_Assy(0 To 2, 0 To 0)
IFS_BV_Assy(0, 0) = "Pfad"
IFS_BV_Assy(1, 0) = "Zg."
IFS_BV_Assy(2, 0) = "Rev"
Do While myFile <> ""
If UCase(Right(myFile, 3)) = "DWG" Or UCase(Right(myFile, 3)) = "PDF" Then
ReDim Preserve IFS_BV_Assy(0 To 2, 0 To counter)
IFS_BV_Assy(0, counter) = strStartPath_BV_Assy + myFile
IFS_BV_Assy(1, counter) = Left(Mid(myFile, 12), InStr(1, Mid(myFile, 12), "-") - 1)
IFS_BV_Assy(2, counter) = Mid(myFile, Len(myFile) - 8, 2)
counter = counter + 1
End If
myFile = Dir()
Loop
Maybe data was best case (around 4000) when ran in VBA.
30 sec seems a reasonable time for 4000x4000=16.000.000 iterations. 1 sec is too low for this number of iterations.
Stokke suggested to create the array as String instead of Objekt Type.
Dim IFS_BV_Assy(,) as String
I create the Module with Option Explicit Off, because I never see any difference in VBA for that point. Now I declare any variable with Dim .. as ....
And now, it's as fast as VBA is =)
Learning = making mistakes.. =)

Functions and loops

I am trying to make the function _EncryptionProcess() take arrays 1 by 1 and process them. I realized you can't have functions inside For loops.
The location in which the arrays need to be taken is where $aArray is typed, the arrays are stored in this value. The other variable defines the key size and value.
;Cuts the input up into piece;
$VariableToBeCut = "12345678"
$aArray = StringRegExp($VariableToBeCut, ".{2}", 3)
MsgBox(0, "die", $aArray[0]) ; personal check to make sure array works
$DataToBeEncrypted=_EncryptionProcess($aArray, $keyvalue, $keysize, 1) ;$aArray needs to be where the different arrays are processed
MsgBox(0, "Encrypted data", $DataToBeEncrypted)
This is how you should process array elements.
;Cuts the input up into piece;
$VariableToBeCut = "12345678"
$aArray = StringRegExp($VariableToBeCut, ".{2}", 3)
ConsoleWrite("Array element 0: " & $aArray[0] & #LF) ; personal check to make sure array works
For $i = 0 To UBound($aArray)-1
$DataToBeEncrypted = _EncryptionProcess($aArray[$i], $keyvalue, $keysize, 1)
ConsoleWrite("Element " & $i & " : " & $aArray[$i] & " DataToBeEncrypted: " & $DataToBeEncrypted & #LF)
Next

How many dimensions in my array or get the last one

How can I find out the number of dimensions in an array in Classic ASP ( VBScript ) .
I am being passed an Array with multiple dimensions but I only want to look at the last. Seems easy in other languages.
Ubound(MySingleDimensionalArray, 2) ' Number of Array Elements
Ubound(MyMultiDimensionalArray, 1) ' Number of Columns
Ubound(MyMultiDimensionalArray, 2) ' Number of Rows
Similar approach to feihtthief's answer here as I assume this is what you want rather than the size of a specified dimension.
Function NumDimensions(arr)
Dim dimensions : dimensions = 0
On Error Resume Next
Do While Err.number = 0
dimensions = dimensions + 1
UBound arr, dimensions
Loop
On Error Goto 0
NumDimensions = dimensions - 1
End Function
Then calling it as so:
Dim test(9, 5, 4, 3, 9, 1, 3, 5)
NumDimensions(test)
will give you the value 8
It's a bit crappy but it'll do what you asked.
function ArrayDimensions( theArray )
dim Result,test
Result = 0
if isarray(theArray) then
on error resume next
do
test = -2
test = ubound(theArray,result+1)
if test > -2 then result = result + 1
loop until test=-2
on error goto 0
end if
ArrayDimensions = Result
end function

Resources