I've found something that I don't quite understand. Please help explain.
so I used this code to assign values within named ranges to an array. (see below).
Dim accountStructure As Variant
ReDim accountStructure(2)
accountStructure(0) = Range("namedrange1")
accountStructure(1) = Range("namedrange2")
accountStructure(2) = Range("namedrange3")
The code works. However, in order to call the first item in accountstructure(0) I need to type accountStructure(0)(1,1), second item accountStructure(0)(2,1) third item (0)(3,1) and so on.
I understand why there is (0) there but I don't understand why there is always a 1 after the item number. Please help me understand this.
If we have any range
Dim rng as Range
Set rng=Range("A1:A10")
We can assign
Dim arr As Variant
arr = rng
But we have to treat it as two dimensional array. Because Excel VBA does'nt "know" it is one dimensional.
So we can now
For i=1 To 10
arr(i,1) = i
Next
Related
I have become stuck trying to solve a piece of code I thought would be very simple.
I have defined a range (2 rows, 150 columns) and transferred it to an array. I then want to use the defined array in multiple ranges (same size of 2 rows and 150 columns). I have written the following code:
Dim LocalArray As Variant
LocalArray = .Range("FD6781:KW6782").Value2
.Range("FD6839:KW6840,FD6955:KW6956,FD7013:KW7014,FD7071:KW7072").Value2 = LocalArray
The issue is that every second range defined in .range("FD6839:KW6840,FD6955:KW6956...") shows up as N/A. Hence range FD6839:KW6840 is correct while range FD6955:KW6956 is wrong.
What have I done wrong in the above code?
Thank you!
You could loop. Otherwise, it does seem to be related to the number of columns causing the issue. Seems odd.
Option Explicit
Public Sub test()
Dim localArray(), rng As Range, ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet3")
localArray = ws.Range("FD6781:KW6782").Value2
For Each rng In ws.Range("FD6839, FD6955, FD7013, FD7071")
rng.Resize(UBound(localArray, 1), UBound(localArray, 2)) = localArray
Next
End Sub
I am trying to avoid the use of loops for populating arrays since they take a lot of time when managing a lot of data.
Apparently as well, that is possible and easy in VBA but often results in problems.
Here is the code:
sub populate()
'put the whole column in an array
Dim AppArray() As Variant
Dim AppRange As Range
'calculate the last row of the column 1 of sheets
Dim LstRow As Integer
LstRow = Sheets("whole").Cells(Sheets("whole").Rows.Count, "A").End(xlUp).row
'here I calculate the range that I want to pass to the array
Set AppRange = Sheets("whole").Range(Cells(1, 1), Cells(LstRow, 1))
MsgBox ("apprange " & AppRange.Address)
'i dont know if I need to redim or not
ReDim AppArray(1 To LstRow)
'here comes the point. populate the array with the values of the range
AppArray = AppRange.Value
End Sub
This does not work. I also tried application.tranpose(AppRange.Value).
I used:
For i = 1 To LstRow
Debug.Print AppArray(i)
Next
and an error appears, so somehow there is no AppArray(1).
I would be very happy if you can comment on that. More than just arranging the code suggest even other pages (links) to populate arrays with values of ranges when these ranges are not known in advance.
If the case is that looping is very time consuming and that arrays can be populated straight away, I don't understand why 99% of the pages referring to arrays use a loop (or nested loop) to populate an array.
I found the answer.
dim myRange as range
dim myArray() as variant
myRange = range(cells(2,3),cells(10,15))
redeem myArray(1 to 20,1 to 20)
myArray=myRange
It's always much faster to work with variables and arrays than with cells values.
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
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.
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.