Runtime error 9. Subscript is out of range - excel

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

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.

Excel VBA: Is there a dynamic Array that can be used for Dates?

I'm working on an Excel Macro and I want to create an array of dates and then loop through it, without knowing how many dates will be added. I thought this would be simple, but I can't get it to work.
I tried using a collection:
Dim DateArr As Collection
Dim d As Date
Set DateArr = New Collection
DateArr.Add (CDate("1/1/2019"))
DateArr.Add (CDate("2/2/2020"))
For Each d In DateArr
sh.Cells(y, 27).Value = d
Next d
But I get an error that says "For Each control variable must be Variant or Object" and highlights the d in my loop. Are dates not objects?
I also tried a Variant:
Dim DateArr As Variant
DateArr.Add CDate("2/2/2020")
DateArr(1) = CDate("1/1/2019")
But I can't find the right syntax for adding a Date. The .Add line gives me an "Object Required" error and the DateArr(1)= line gives me a "Type Mismatch" error.
The only thing that kind of works is a standard array:
Dim DateArr() As Date
Dim y As Integer
ReDim DateArr(1 To 2) As Date
DateArr(1) = CDate("1/1/2019")
DateArr(2) = CDate("2/2/2020")
For y = LBound(DateArr) To UBound(DateArr)
sh.Cells(y, 27).Value = DateArr(y)
Next y
But I have no idea how many dates will be in the array, so can't use anything static. Is there a way to use this same syntax without setting dimensions?
Thanks!
Dates are variants not objects
Add for collections is a method. In your code you have assumed it is a function and added unnecessary parentheses, e.g.
DateArr.add cdate("1/1/2019")
To use a For Each then the indexing (controlling) variable must be an object or a variant.
Thus your first example should work fine (other errors not withstanding) if you dim d as a variant.

How to reference a collection in a formula

All I want to do is reference a collection in a formula. Like
Assume I already know how to make collections and arrays and have done so in my macro, Collection is literally a collection with only 1 column, and Textstring is an array vector.
'For every value of i in Textstring, I want to count the occurrence of that value in all the values of 'Collection'
For i = 1 to Whatever
=COUNTIF(Collection, """ & TextString(i) & """)
Next i
What I want to know is how to make aforementioned code work.
It should work like a normal countif:
'ie: "=COUNTIF('Sheet1'!A1:A10, ""blah"")"
You can't with COUNTIF, if you have a look at the arguments to the function, it expects a Range object.
The only suggestion I have is to do something like the below, i.e. write it out to a worksheet and then use that range as a parameter to your function ...
Public Sub CollectionToRange()
Dim objCollection As New Collection, i As Long
For i = 1 To 10
objCollection.Add i
Next
' Convert the collection to a range.
For i = 1 To objCollection.Count
Sheet1.Cells(i, 1) = objCollection.Item(i)
Next
' Pass the range into the worksheet function.
Debug.Print "CountIf Result = " & WorksheetFunction.CountIf(Sheet1.Range("A1:A" & objCollection.Count), ">3")
' Perform a clean up if required.
End Sub
Not sure if that helps or not.

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.

Excel VBA: Array not empty but has no value?

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

Resources