Creating an Array from a Variable Range in VBA - arrays

I'm looking for a way to create an array from a variable range in VBA. I've seen a similar posting but I can not find the way to adjust it to a variable range.
What I have is a Sheet with variable columns and I want store these into an array. So far I have the following code, but it is giving an error when trying to assign the dynamic range (HCRng)
Sub TestColumnNames()
Dim ArrayColumns As Variant
Dim HCRng As Range
HCRng = Sheets("HC").Range("A1", Selection.End(xlToRight))
ArrayColumns = HCRng.Value
End Sub
Any ideas?

Related

Type mismatch error when creating a vba array

I'm trying to drop a range of cells straight into an array to run some calculations. The range will always be A8:E?, but I never know how many total rows there will be. One of the columns contains string values that I need for determining conditions. I set a variable to find the last row (and no, this data never has any blanks so the method to set it works just fine). This is what I have"
Sub use_arr()
Dim rw As Integer
rw = Worksheets("Sheet1").Range("A8").End(xlDown).Row
Dim myArr()
myArr = Worksheets("Sheet1").Range("A8:E" & rw)
End Sub
But it keeps throwing a "Run_time error '13'" at me.
Arrays are still new to me, someone suggested using them instead of looping through cells for faster execution. So I'm still figuring this out.
Either declare myArr just as a Variant, not an array, or specify the Value property of the range:
myArr = Worksheets("Sheet1").Range("A8:E" & rw).Value

Assigning values of a range to an array

I have write bellow code, that prints 210 in immediate window.
Sub RangeToArr()
Dim data() As Variant
data = Range("Salary[EmpNum]").Value
Debug.Print UBound(data)
End Sub
When I using bellow, the Subscript out of range Run-time error message will displayed.
Sub RangeToArr()
Dim data() As Variant
data = Range("Salary[EmpNum]").Value
Debug.Print data(210)
End Sub
If data is an array, what is the problem, else, how can access a range values that assigned to an array, as above?
A range converted to an array will create a 2 dimensional array, if you try to return data(210) you are referencing it as if it's a single dimensional array. You can get the value from the 210th cell in the range by returning
data(210, 1)
I can only assume as to the reason why it forces a 2 dimensional array. My guess is because if your range included additional columns it would be 2 dimensional array. The act of creating a 2 dimensional array regardless even if you only have one column means the method for dealing with the data remains the same. There is an exception to this - If your range is a single cell, VBA will populate just the value as a single dimension.
To make sure your sample works, make sure you have 210 rows in your table sample.
In general, try something like this to get the idea of the arrays and ranges:
Crate a simple named range MyNamedRange with more than one column and more than one row
Put some values in it
Run this and see what you are getting in the immediate window:
Sub RangeToArr()
Dim arrVar As Variant
arrVar = Range("MyNamedRange")
Debug.Print arrVar(1, 2)
End Sub
Change the (1,2) values a bit to get the idea.

Storing rows, columns and sheets in dynamic arrays

I have been told there is a way of storing data in dynamic arrays which can then be referred to in a function.
I come from my recent answered question:Showing hidden column in another sheet
I am trying to find out how to store in a dynamic array which row (first array), column (second array) and sheet (third array) my code has to make action on.
I still haven't done arrays in my class, I'm just guessing it is a dynamic one for what I have researched. Do you think this could be done in the same array using different dimensions?
(Edited ->) -- Being more specific: I am looking for a way to store a number of specific rows(or columns) of a specific sheet to then (in a loop I guess) run my function for each element.
I have read the basic documentation (https://msdn.microsoft.com/en-us/library/aa716275(v=vs.60).aspx) and looked for similar posts here but I can't find it. If someone can point out what I should do or read to achieve this I can try and do it myself if you believe it's better.
Edited:
I think I am doing some progress, but I still don't know how to refer to a the sheet within the range.
Would this do the job (if I didn't need sheet referring)?
Public Sub Test()
Dim Rng As Range
Dim Area As Range
Set Rng = Range("A1:A10,B1:B20,G1:G3")
For Each Area In Rng.Areas
Area.Hidden = True
Next Area
End Sub
You can manage that with a single array of Range because the range refer to:
The sheet
The row
The Column
Dim array() as Range
...
' Store with
set array(i) = worksheet.Range(a, b)
...
' Read with
set range = array(i)
The link to msdn in your question explain how to manage Dynamic Arrays
update
The problem in your code is you not refer the worksheet you want.
If no worksheet is indicate, in the best case an error is thrown, in the worst case it takes the "Activesheet" (yes, an error is a better case then work on you don't know what).
Consider you know the name of the sheet (or the position of it), you can pass it in parameters
Public Sub Test(byval sheetname as string)
' First solution: declare a worksheet variable referencing to your worksheet
dim ws as worksheet, rng as range, area as range
set ws = Worksheets(sheetname)
Set rng = ws.Range("A1:A10,B1:B20,G1:G3")
For Each area In rng.Areas
area.Hidden = True
Next Area
' You could replace the dim of ws by a With Worksheets(sheetname)
' and work with .Range() instead
End Sub

VBA: looping through a list of named ranges and pasting them to another sheet based on an address reference

I am making some VBA code to help me do the following:
Paste a list of all named ranges
Loop through the list and copy/select ranges based on the list
Each selection will be pasted on another sheet given an address reference with a certain offset from that address
I am pretty new to VBA so I have put together some code that I think will do the trick but I am getting run time errors. Could someone help me troubleshoot or provide suggestions?
My code is here:
Sub RangeLoop()
Sheets("RANGEMATCH").Select
Range("A1").ListNames
Dim columnrange As Range
Dim m As Long
Dim address As Range
Set columnrange = Sheets("RANGEMATCH").Range("A:A").SpecialCells(xlConstants)
With columnrange
For m = 1 To columnrange.Areas.Count
Set address = Sheets("RANGEMATCH").Range(.Areas(m).Cells(1, 7).Value)
Range(m).Copy Sheets("ETIE").Range(address.Offset(1, 10))
Next
End With
End Sub
Here is an example workbook of what I am working with:
https://docs.google.com/spreadsheet/ccc?key=0AodOP_8DnJnFdHJoQ0xBM3JUUGJxT3EyRXN0T2ltUmc&usp=sharing
Any suggestion are appreciated.
The Range() function expects a string variable. Either the name of a range or a cell reference like "A1"
Range(m).Copy Sheets("ETIE").Range(address.Offset(1, 10))
m is a number so that won't work. You'll need to reference the thing that you want to copy. I think that might just be your address object that you set in the line before:
address.Copy Sheets("ETIE").Range(address.Offset(1, 10))

Using an Array of Ranges in VBA - Excel

Does VBA support using an array of range variables?
dim rangeArray() as range
dim count as integer
dim i as integer
count = 3
redim rangeArray(1 to count)
for i = 1 to count
msgbox rangeArray(i).cells(1,1).value
next
I can't get it to work in this type of application. I want to store a series of ranges in a certain order as a "master copy". I can then add, delete, sort or do whatever to this array and then just print it out to a series of ranges in excel. It doesn't seem like excel supports this - it just forces you to store your data in the spreadsheet and you have to reread it in order to use it.
No, arrays can't hold objects. But oObjects can hold objects. I think what you may want is a Range object that consists of various specific other Range object. In this example, rMaster is my "array" that holds three cells.
Sub StoreRanges()
Dim rMaster As Range
Dim rCell As Range
Set rMaster = Sheet1.Range("A1")
Set rMaster = Union(rMaster, Sheet1.Range("A10"))
Set rMaster = Union(rMaster, Sheet1.Range("A20"))
For Each rCell In rMaster
MsgBox rCell.Address
Next rCell
End Sub
With my new found knowledge that arrays can hold ranges (thnx jtolle), here's an example of how you would store ranges in an array and sort them
Sub UseArray()
Dim aRng(1 To 3) As Range
Dim i As Long
Set aRng(1) = Range("a1")
Set aRng(2) = Range("a10")
Set aRng(3) = Range("a20")
BubbleSortRangeArray aRng
For i = LBound(aRng) To UBound(aRng)
Debug.Print aRng(i).Address, aRng(i).Value
Next i
End Sub
Sub BubbleSortRangeArray(ByRef vArr As Variant)
Dim i As Long, j As Long
Dim vTemp As Variant
For i = LBound(vArr) To UBound(vArr) - 1
For j = i To UBound(vArr)
If vArr(i).Value > vArr(j).Value Then
Set vTemp = vArr(i)
Set vArr(i) = vArr(j)
Set vArr(j) = vTemp
End If
Next j
Next i
End Sub
It's not entirely clear what you want to do, but...
If you want a collection, why not use a VBA Collection Object?
Dim myRanges as New Collection
A Collection.Item can be any object, including a Range.
A Range object doesn't hold data; it holds a reference to worksheet cells. If you want the Range contents in your collection, you'll have to copy them to and from the worksheet.
As with Java, your VBA variables are ephemeral, whether in an Array or Collection. If you want to close the file and have the data there when you open it again, you have to have it in worksheet cells. The worksheets are your persistence mechanism.
I'm going to take a big leap here so if I'm way off, ignore me. What I think you're looking for suggests setting up a separate worksheet as your "database", populated with List/Table objects holding your raw data. In front of that, is your "user sheet" where you do the interesting stuff, referring to the data in the database sheet. Name everything.
It's not completely clear for me what you're talking about.
If you're asking about an ability to create Ranges that map to nothing and exist on their own, then no, there's no way. A Range object is just something that refers to a certain area of a worksheet. It doesn't have any storage of its own or something. Several different instances of Range class can refer to the same worksheet area, too.
And if you just want to store some references in an array, then that's fine, go for it. The only problem with your code is that you don't initialize the array elements before using them: as the Range is a reference type, all elements get initialized with Nothings by default.

Resources