Naming an array using a variable - arrays

Is it possible to name an array variable using a different variable? For example, if I define variable "i" as an integer with a value equal to the number of columns I've used it a sheet:
Sub varNameTest
Dim i, j, As Integer
i = ActiveSheet.UsedRange.Columns.Count
...
Is it possible to then establish "i" number of arrays named something like myArray1 through i? Possibly something like:
For j = 1 to i
Dim (myArray & j())
Next i
Though this example immediately above is incorrect syntax, I'm just trying illustrate what I'm trying to do.
edit: so to be more clear, using the above example, say I have 4 sheets in a workbook. The variable i would then be 4, and I would have some code that generates myArray1(), myArray2(), myArray3() and myArray4().

You can create an array of arrays (though your question is a little unclear..)
Sub MyArrays()
Dim arrays()
Dim arr
Dim i, j
i = 5 'e.g.
ReDim arrays(1 To i)
For j = 1 To i
arr = Array()
ReDim arr(1 To j)
arrays(j) = arr
Next j
'reference an array by its position in "arrays"
Debug.Print UBound(arrays(3))
End Sub

Yes.
Dim i(5) As Integer
In VBA you can then access elements from i(0) to i(5).
Based on your edited question, the answer is no. You must explicitly define each variable in your code.
The other option would be to write code that writes your code - a form of code generation. Effectively that lets you write very long and complex code by repeating code "templates". But I don't think this would help in your case.

Related

accessing individual array elements in VBA function

VBA newbie here. I am trying to pass an array (it is static, but please answer for dynamic range as well) to a function. Then assign individual array elements to unique variables and use these variables in a custom formula. I just browsed around and wrote the code but keep getting #VALUE! error. The gist of the code is below:
Public Function mytest(ByRef arr1 As Range)
Dim A As Double
Dim B As Double
A = arr1(0)
B = arr1(1)
mytest = A + B 'The actual formula is a bit more complicated than simple addition
End Function
I am not sure what am i doing wrong at all. If anyone has a solution, can you please explain why it works as well. I appreciate any and all help I can get.
Many thanks !
As Coleman pointed out a range is not an array, consider:
Public Function mytest(ByRef arr1 As Range)
Dim A As Double
Dim B As Double
A = arr1(1, 1)
B = arr1(2, 1)
mytest = A + B 'The actual formula is a bit more complicated than simple addition
End Function
NOTE:
we treat the Range similar to an array
it is two dimensional
it is 1 based
if you are only dealing with the Range's value, you could create an internal array within your function that directly maps to the passed Range.
if the Range is truly dynamic, (like a Spill range) then all you need to pass is the anchor cell.
You seem to be trying to use a worksheet range as a 0-based array. That doesn't really make sense although using the Cells property of a range (which you are actually trying to do implicitly) you can come close:
Public Function mytest(arr1 As Range)
Dim A As Double
Dim B As Double
A = arr1.Cells(1)
B = arr1.Cells(2)
mytest = A + B 'The actual formula is a bit more complicated than simple addition
End Function
In the above code, you can drop Cells() since it will function as the default property here, but most experienced VBA programmers like to make explicit what property they are using.
This will more or less work for 1-dimensional ranges but might not work as expected with 2-dimensional ranges. Cells takes up to 2 indices and in general I think that the code is clearer when you are explicit about the full indices (e.g. A = arr1.Cells(1,1) and B = arr1.Cells(2,1)).
The question isn't in the code you posted but in the procedure that calls it. Here the calling procedure first assigns values to the cells in the worksheet (for testing purposes), then passes the range to the function which extracts the values into an array and then uses that array to calculate a return value.
Private Sub TestmyTest()
Dim Rng1 As Range
Cells(1, "A").Value = 3.14
Cells(2, "A").Value = 3
Set Rng1 = Range("A1:A2")
Debug.Print myTest(Rng1)
End Sub
Function myTest(Rng1 As Range) As Double
' procedures are 'Public' unless declared as 'Private'
' Therefore only declare "Private" or nothing
' Arguments are passed ByRef unless they are declared as 'ByVal'
' Therefore I recommend to omit "ByRef"
Dim Arr As Variant
Dim A As Double
Dim B As Double
' this creates a 1-based 3-D array of 2 row and 1 column
Arr = Rng1.Value
A = Arr(1, 1)
B = Arr(2, 1)
myTest = A + B 'The actual formula is a bit more complicated than simple addition
End Function

Can I Use a Variable to ReDim an Array?

I am not entirely sure why I am getting the error message of
Expecting a dynamic array var
with this code:
Option Explicit
Sub ArrayTest()
Dim i As Integer, BankList(0) As Variant, x As Integer
For i = 0 To UBound(ScreenArray)
If ScreenArray(i) Like "TR=SUB*" Then
Debug.Print ScreenArray(i)
ReDim Preserve BankList(x) '<<< ERROR LINE
BankList(x) = ScreenArray(i)
x = x + 1 'Raise the value for the next occurrence, if needed.
End If
Next
End Sub
Basically I am attempting to move specific strings from one array to a new array, if certain criteria are met. It's difficult to determine how many strings will be in the new array until running this For...Next statement.
If you can't tell from the code, the original array is ScreenArray and the new array is BankList.
To create a dynamic array, do not specify the size in the original declaration.
So use BankList() As Variant instead of BankList(0) As Variant.

VBA Access 2010 extracting array elements as individual dynamically named variables

I am working through an Access 2010 VBA script. I am pulling information from a temporary table that may have 1 to 10 records in it. I am using GetRows to build a two-dimensional array that looks like this, for example:
**0** **1**
8677229 1
10289183 2
11981680 3
13043481 4
I have tested the array function by debug print, and the array does contain values. I want to split out the array values dynamically into variables for later use. In this example, I would like the 0 column to produce 4 variables named Anum(0) through Anum(3), and the 1 column to produce 4 variables named Pay(0) through Pay(3). However, I keep getting a "Error 9, subscript out of range" where indicated below:
Dim db As Database
Dim rs As Recordset
Dim PayAcct As Variant
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT Anum, Pay FROM PayPerAcct")
Dim highval As Integer
Dim i As Integer
i = 0
While Not rs.EOF
PayAcct = rs.GetRows(10)
Wend
highval = UBound(PayAcct, 2)
Dim Anum() As Variant
Dim Pay() As Variant
For i = 0 To highval
'error occurs on the below line
Anum(i) = CStr(PayAcct(0, i))
Pay(i) = CStr(PayAcct(1, i))
Next i
When I manually define Anum and Pay variables and use the Cstr(PayAcct(1,0)) operation, it passes the expected value from the array to the variable, so I don't think that is the problem.
I suspect I am assigning Anum() and Pay() the wrong dimension, because I have seen similar example code in Excel VBA where defining those variables as Range works. I have tried defining Anum() and Pay() as Range (which doesn't work, because this is Access VBA), Variant, and Object.
Any thoughts or tips?
Edit -
The below ended up working, thanks for your help:
Dim Anum() As String
ReDim Anum(0 To highval)
Dim Pay() As String
ReDim Pay(0 To highval)
Dim Anum() As Variant
declares a dynamic array that hasn't any elements yet, so you can't assign values to it. It needs a ReDim to use it.
But since you already know how many elements you need, what you want is:
Dim Anum(0 To highval) As Variant
or if you know that you will only store strings in it,
Dim Anum(0 To highval) As String

Array in excel vba

I want to have an array list in vba, hence I have a variant declared in excel vba like:
Dim Students(10) as variant
Now I want to store numbers in Students list. the numbers are not continuous. Sometime like:
Students(2,7,14,54,33,45,55,59,62,66,69)
How can I do this in vba? also how can I access the list items?
Students must be declared as a dynamic array. That is, an array whose bounds can be changed. Dim Students(10) gives an array whose bounds cannot be changed and cannot be loaded from an array.
Dim Students() As Variant
To load Students:
Students = Array(2,7,14,54,33,45,55,59,62,66,69)
To access the elements:
Dim Inx As Long
For Inx = LBound(Students) to UBound(Students)
Debug.Print Students(Inx)
Next
LBound (Lower bound) and UBound mean that the for loop adjusts to the actual number of elements in Students.
This is too complex for you right now, and you'll probably never run into a situation where you'll need this, but:
I use the following method for forming more memory-efficient arrays (because Variant uses the most memory of any variable type) while still having the convenience of declaring the array contents in one line. To follow your example:
Dim Students() As Long
Dim Array2() As String
Array2() = Split("2,7,14,54,33,45,55,59,62,66,69", ",")
ReDim Array1(0) As Long
For Loop1 = LBound(Array2()) To UBound(Array2())
ReDim Preserve Array1(0 To (UBound(Array1) + 1)) As String
Array1(Loop1) = Array2(Loop1)
Next Loop1
ReDim Preserve Array1(0 To (UBound(Array1) - 1)) As Long
Erase Array2
An example of accessing it would be something like:
For Loop1 = LBound(Students) to UBound(Students)
Msgbox Students(Loop1)
Next Loop1
I learned this from here: http://www.vbforums.com/showthread.php?669265-RESOLVED-VBA-Excel-Assigning-values-to-array-in-a-single-line&p=4116778&viewfull=1#post4116778
You can add values to an Array like this...
For i = 1 to 10
Students(i) = i
Next i
Or like this
Students = Array(2,7,14,54,33,45,55,59,62,66,69)
Then you can access the values in the same manor. Note if you use the second option you'll need to declare it as follows:
Dim Students() As Variant
Well,
That depends on how you would supply the values for the array, would you get the values from Worksheet.Range or from TextBox or ListBox , But basically the code would be something like that :
Dim students(10) as Integer
Dim Carrier as Integer
For i = LBound(students) To UBound(Students)
'some code to get the values you want to from whatever is your source
'then assign the value to Carrier
students(i)=Carrier
Next i
It is not good practice to dim an array as Variant when you certainly know that you are going to use integers only, as it will eat alot of memory that is not needed in the first place.
You also should be aware of the bounds of the numbers that are going to be assigned, if it exceeds the Integer limit then you should use Double or Float.
This is my first participation in the site,Cheers.

How do I declare an array variable in VBA?

I need to add the var in array
Public Sub Testprog()
Dim test As Variant
Dim iCounter As Integer
If test = Empty Then
iCounter = 0
test(iCounter) = "test"
Else
iCounter = UBound(test)
End If
End Sub
Getting error at test(iCounter) = "test"
Please suggest some solution
Generally, you should declare variables of a specific type, rather than Variant. In this example, the test variable should be of type String.
And, because it's an array, you need to indicate that specifically when you declare the variable. There are two ways of declaring array variables:
If you know the size of the array (the number of elements that it should contain) when you write the program, you can specify that number in parentheses in the declaration:
Dim test(1) As String 'declares an array with 2 elements that holds strings
This type of array is referred to as a static array, as its size is fixed, or static.
If you do not know the size of the array when you write the application, you can use a dynamic array. A dynamic array is one whose size is not specified in the declaration (Dim statement), but rather is determined later during the execution of the program using the ReDim statement. For example:
Dim test() As String
Dim arraySize As Integer
' Code to do other things, like calculate the size required for the array
' ...
arraySize = 5
ReDim test(arraySize) 'size the array to the value of the arraySize variable
Further to Cody Gray's answer, there's a third way (everything there applies her as well):
You can also use a dynamic array that's resized on the fly:
Dim test() as String
Dim arraySize as Integer
Do While someCondition
'...whatever
arraySize = arraySize + 1
ReDim Preserve test(arraySize)
test(arraySize) = newStringValue
Loop
Note the Preserve keyword. Without it, redimensioning an array also initializes all the elements.
Further to RolandTumble's answer to Cody Gray's answer, both fine answers, here is another very simple and flexible way, when you know all of the array contents at coding time - e.g. you just want to build an array that contains 1, 10, 20 and 50. This also uses variant declaration, but doesn't use ReDim. Like in Roland's answer, the enumerated count of the number of array elements need not be specifically known, but is obtainable by using uBound.
sub Demo_array()
Dim MyArray as Variant, MyArray2 as Variant, i as Long
MyArray = Array(1, 10, 20, 50) 'The key - the powerful Array() statement
MyArray2 = Array("Apple", "Pear", "Orange") 'strings work too
For i = 0 to UBound(MyArray)
Debug.Print i, MyArray(i)
Next i
For i = 0 to UBound(MyArray2)
Debug.Print i, MyArray2(i)
Next i
End Sub
I love this more than any of the other ways to create arrays. What's great is that you can add or subtract members of the array right there in the Array statement, and nothing else need be done to code. To add Egg to your 3 element food array, you just type
, "Egg"
in the appropriate place, and you're done. Your food array now has the 4 elements, and nothing had to be modified in the Dim, and ReDim is omitted entirely.
If a 0-based array is not desired - i.e., using MyArray(0) - one solution is just to jam a 0 or "" for that first element.
Note, this might be regarded badly by some coding purists; one fair objection would be that "hard data" should be in Const statements, not code statements in routines. Another beef might be that, if you stick 36 elements into an array, you should set a const to 36, rather than code in ignorance of that. The latter objection is debatable, because it imposes a requirement to maintain the Const with 36 rather than relying on uBound. If you add a 37th element but leave the Const at 36, trouble is possible.
As pointed out by others, your problem is that you have not declared an array
Below I've tried to recreate your program so that it works as you intended.
I tried to leave as much as possible as it was (such as leaving your array as a variant)
Public Sub Testprog()
'"test()" is an array, "test" is not
Dim test() As Variant
'I am assuming that iCounter is the array size
Dim iCounter As Integer
'"On Error Resume Next" just makes us skip over a section that throws the error
On Error Resume Next
'if test() has not been assigned a UBound or LBound yet, calling either will throw an error
' without an LBound and UBound an array won't hold anything (we will assign them later)
'Array size can be determined by (UBound(test) - LBound(test)) + 1
If (UBound(test) - LBound(test)) + 1 > 0 Then
iCounter = (UBound(test) - LBound(test)) + 1
'So that we don't run the code that deals with UBound(test) throwing an error
Exit Sub
End If
'All the code below here will run if UBound(test)/LBound(test) threw an error
iCounter = 0
'This makes LBound(test) = 0
' and UBound(test) = iCounter where iCounter is 0
' Which gives us one element at test(0)
ReDim Preserve test(0 To iCounter)
test(iCounter) = "test"
End Sub
You have to declare the array variable as an array:
Dim test(10) As Variant
David, Error comes Microsoft Office Excel has stopped working. Two options check online for a solution and close the programme and other option Close the program
I am sure error is in my array but I am reading everything and seem this is way to define arrays.
The Array index only accepts a long value.
You declared iCounter as an integer. You should declare it as a long.

Resources