Excel VBA: Array not empty but has no value? - excel

I have a global array named myArray.
In this array is stored information taken from another file.
The procedure handles the data stored in myArray, and it works fine.
However, when I launch the procudre a 2nd time, I have a condition where myArray is tested:
IsEmpty(myArray) returns false
So apparantly it's not empty. So when I type in the immediate window this:
UBound(myArray), I get an error message.
So it's not empty, but it doesn't have any values.
Also, IsNull(myArray) returns false.
This makes my code not work properly, because it's supposed to see if myArray is empty, and if it isn't then it accesses one by one the values of myArray. Obviously this causes an error the 2nd time around.
I tired 'Erase myArray' at the end of the procedure, that doesn't help.
Any clues?
Thanks,
Edit: Sample code:
Global myArray As Variant
Sub tryMe()
For i = 0 To 10
If IsEmpty(myArray) Then
ReDim myArray(0)
myArray(0) = i
Else
tempVal = UBound(myArray)
ReDim Preserve myArray(tempVal + 1)
myArray(tempVal + 1) = i
End If
Next i
MsgBox UBound(myArray)
End Sub

Related

Why am I getting a 'Subscript out of Range' error on an my Array? [duplicate]

I have declared an array as such Dim rArray() As Variantbut when i try and use the values that is stored in it (as shown below) I get a subscript out of range error. The UBound(rArray)and LBound(rArray) both returns values 14 and 1, but the error occurs at the Debug.Print line.
If I use the for statement as below
For Each rArr in rArray
then it works without issues, but for the purposes I am creating this array I need the flexibility to select each item stored in that order- meaning I need to refer to them using subscripts.
I have tried multiple ways to try and solve this with no luck and spend almost half my day on this one issue. Could anyone point out what I need to change to get this to work.
Set rng = Range("D4", Range("D4").End(xlDown))
rng.NumberFormat = "0"
rArray = rng.Value
For x = UBound(rArray) To LBound(rArray) Step -1
Debug.Print rArray(x)
Next x
Edit: another fact worth mentioning is that he array is declared and used within a Function but it is not passed from or to the function. Can't arrays be declared and used in Functions?
When you assign worksheet values to a variant array, you always end up with a 2-D array that is 1 based (e.g. 1 to something, 1 to something; never 0 to something, 0 to something). If you are getting values from a single column the second Rank is merely 1 to 1.
This can be proven with the following.
Dim x As Long, rArray As Variant, rng As Range
Set rng = Range("D4", Range("D4").End(xlDown))
rng.NumberFormat = "0" 'don't really understand why this is here
rArray = rng.Value
Debug.Print LBound(rArray, 1) & ":" & UBound(rArray, 1)
Debug.Print LBound(rArray, 2) & ":" & UBound(rArray, 2)
For x = UBound(rArray, 1) To LBound(rArray, 1) Step -1
Debug.Print rArray(x, 1)
Next x
So you need to ask for the element in the first rank of the array; it is insufficient to just ask for the element.

Iterating on a list object's rows, how can I access the entire row?

I come to you because VBA literature online does not show many results for when dealing with Tables and list objects.
With the following code, I add the list object items to a list box in a user form. I iterate through the list object's rows. But I need to validate wether the row is hidden as sometimes there will be filters on the table in the spreadsheet:
With Main
.Clear
Dim i As Long
For i = 1 To tblDataMaster.ListRows.Count
If tblDataMaster.Row(i).Hidden = False Then
.AddItem
Dim j As Integer
For j = 0 To 9
.List(.ListCount - 1, j) = tblDataMaster.DataBodyRange(i, (j + 5))
Next j
End If
Next i
End With
As written of course, the code won't work since .Row is not a property of the list object. But just to illustrate, the If statement needs to validate if that row is hidden or not. If it is not, then it will populate the list box with it.
Something like .DataBodyRange(i,1) is not working either.
Any help, greatly appreciated.
The key is to use ListRow.Range.
Dim tblRow As ListRow
For Each tblRow In tblDataMaster.ListRows
If Not tblRow.Range.EntireRow.Hidden Then
...
End If
Next
Or if iterating by index:
For i = 1 To tblDataMaster.ListRows.Count
If Not tblDataMaster.ListRows(i).Range.EntireRow.Hidden Then
...
End If
Next

Runtime error 9. Subscript is out of range

VBA does not let me apply to the particular element in the dynamical array.
Dim a() As Variant
a = Range("A2:A11").Value
Range("B2:B11").Value = a 'Just to make sure that the list is not empty and is working correctly.
MsgBox a(1) 'OR a(7)=0 OR IF a(4)=0 then MsgBox "!"
I expect to use the first element of the array a, but get an error message at the fourth line, trying to execute MsgBox a(1) or any expression, which involves arr_name(num_index)). I tried the identical code with the static array, which works without any problems:
Dim b(10) As Variant
b(1) = 1234
MsgBox b(1)
The debugger also says that "subscript is out of range". At the same time, The array is for sure not void since the 3rd line works correctly and the array from a is copied to the array of neighboring cells and displayed there just a moment before the macros stops and I'm getting the error message.
What is wrong with my code?
This Code:
Dim a() As Variant
a = Range("A2:A11").Value
Range("B2:B11").Value = a
Will give you a 2-D array. To get the Elements of a 2-D array you need to do
MsgBox a(1,1)
MsgBox a(2,1)
and so on.
Also, You can check the Locals Window for all the Objects.
You are using a 2D array
Dim a() As Variant
a = Range("A2:A11").Value
Range("B2:B11").Value = a 'Just to make sure that the list is not empty and is working correctly.
MsgBox a(1,1)
If you want to browse your 2D array You might do as follow, Hope this help :
For element= LBound(a, 1) To UBound(a, 1)
Debug.Print a(element, 1)
Next

Access VBA Pass a MultiDimensional Array in a function

Access 2013 32 bit: Win 7 64bit
Tried: Is it possible to pass a multidimensional array as a parameter in EXCEL VBA? to no avail
(If you can answer this you can probably answer that, but they're a little different)
Sub CreateArray()
Dim myArray(1 to 10, 1 to 5)
'Code that assigns values to (1 to 10, 1 to 4)
myArray() = CalculateLastColofArray(myArray())
'Do stuff with full array
End sub
Function CalculateLastColofArray(calcArray)
For i = LBound(calcArray()) to UBound(calcArray())
calcArray(i,5) = calcArray(i,1) + calcArray(i,3)
Next i
CalculateLastColofArray = calcArray()
End Function
My calculation is actually much more complex than the simple addition and my array is dynamically large (x, 5)
Doing it the way I have shown above fills myArray, but debugging has it shown as when I hover over it wrapped in the function call and it errors before entering the function
You can pass multidimensional array as a parameter.
You can also assign the result of the function to the array variable, however this variable must be declared as dynamic array (so its dimensions cannot be specified in declaring line).
Furthermore, you have some other errors in your code. Below is the correct version:
Sub CreateArray()
'Dim myArray(1 To 10, 1 To 5) As Variant
Dim myArray() As Variant
ReDim myArray(1 To 10, 1 To 5)
'Code that assigns values to (1 to 10, 1 to 4)
myArray = CalculateLastColofArray(myArray)
'Do stuff with full array
End Sub
Function CalculateLastColofArray(calcArray() As Variant) As Variant()
For i = LBound(calcArray) To UBound(calcArray)
calcArray(i, 5) = calcArray(i, 1) + calcArray(i, 3)
Next i
CalculateLastColofArray = calcArray
End Function
The key was the CalculateLastColofArray(myArray()) because I had included the parenthesis in the myArray() argument it was looking for a single value, not taking the array as a whole.
changing this line to CalculateLastColofArray(myArray) solved my problem
it's always something small...

Removing Dupes in a Single Cell, Nested VBA

I needed to pull multiple vlookup values into a single cell. To do so I used vba to create a public function called MULTIVLOOKUP and it works perfectly resulting in the following values in a single cell:
Vendor, Site, ARO, ARO, ARO, Site
The formula to get this is: =MULTIVLOOKUP($J9, $A$2:$A$5000, 4)
I then used code found here on stackoverflow to remove dupes. Here is that code which user KazJaw was great in providing:
Function UniqueFromCell(rngCell, splitString)
Dim myCol As New Collection
Dim itmCol
Dim i As Long
Dim arrTMP As Variant
arrTMP = Split(rngCell, splitString)
For i = 1 To UBound(arrTMP)
On Error Resume Next
myCol.Add arrTMP(i), CStr(arrTMP(i))
On Error GoTo 0
Next i
Dim result
For Each itmCol In myCol
result = result & itmCol & splitString
Next
UniqueFromCell = Left(result, Len(result) - Len(splitString))
End Function
My resulting formula become:
=UNIQUEFROMCELL(MULTIVLOOKUP($J9, $A$2:$A$5000, 4), ",").
It works almost perfect except my result is: Site, ARO
I lost Vendor!
Any suggestions? Thank you in advance.
The line:
For i = 1 To UBound(arrTMP)
Is the problem. Split is returning a zero-based array not a one-based array. It's safer to write something like LBound(arrTMP) instead, to handle both kinds of array properly.
For i = LBound(arrTMP) To UBound(arrTMP)
You can read up on how arrays work in VBA here.

Resources