Split range containing multiple ranges into an array of ranges? - arrays

I'm trying to convert a multiple range selection into an array of ranges.
Right now this is what I'm trying:
Private Function SplitRange(ByRef r As Range) As Range()
Dim i As Long
Dim RangesArray() As Range
Dim AddressArray() As String
Dim Address As Variant
i = 0
AddressArray = Split(r.Address, ",")
ReDim RangesArray(UBound(AddressArray))
For Each Address In AddressArray
Set RangesArray(i) = Range(Address)
i = i + 1
Next Address
' It works till this point, executing RangesArray(0).Address returns a range address
SplitRange = RangesArray
' Here for some reason neither SplitRange(0).Address or RangesArray(0).Address work
End Function
How can I convert the "compound" range into an array of ranges?

Each object of Range type has property Areas that contains the collection of its subranges. You can operate on the items from this collection instead of creating array.
But if you really need an array you can easily convert it like that:
Public Function SplitRange(ByRef r As Range) As Range()
Dim i As Long
Dim ranges() As Range
Dim subrange As Range
'----------------------------------------------------------------
ReDim ranges(0 To r.Areas.Count - 1)
For Each subrange In r.Areas
Set ranges(i) = subrange
i = i + 1
Next subrange
SplitRange = ranges
End Function

Related

Creating an array from named range

I'm trying to create few arrays from named range in my workbook instead of defining that arrays manually.
Example:
This is the array I want to create
Array("bardzo lekka", "lekka", "średnia", "ciężka")
The same data is definied in named range $A$5:$A$8. I want to load that range into array like above.
I've tried to do this like that:
kategoria_a = ActiveWorkbook.Names("kategoria_agronomiczna_gleby").RefersToRange(1, 1)
It creates only one object array.
kategoria_a = ActiveWorkbook.Names("kategoria_agronomiczna_gleby")
That makes
kategoria_a = ='Dane wyjściowe'!$A$5:$A$8
Thanks in advance.
if your values are listed in along a column you could use:
kategoria_a = Application.Transpose(ActiveWorkbook.Names("kategoria_agronomiczna_gleby").RefersToRange.Value)
while if they are listed along a row then you could use
kategoria_a = Application.Transpose(Application.Transpose(ActiveWorkbook.Names("kategoria_agronomiczna_gleby").RefersToRange.Value))
to obtain a 1D array
Try this:
Dim a As Variant
Dim i As Long
Dim rng As Range, r As Range
a = Array("bardzo lekka", "lekka", "średnia", "ciężka")
For i = LBound(a) to UBound(a)
If i = LBound(a) Then
Set rng = Range(a(i))
Else
Set rng = Union(rng, a(i))
End If
Next i
a contains all named ranges. To access the values you could use this:
For Each r In rng
debug.print r.value
Next r
This will take all the named ranges, and put them in an array (myArr):
Sub get_named_ranges()
Dim rng As Range
Dim nm
Dim myArr() As Variant
ReDim myArr(1 To ThisWorkbook.Names.Count)
Dim i As Long
i = 1
For Each nm In ThisWorkbook.Names
myArr(i) = nm.Name
i = i + 1
Next nm
For i = LBound(myArr) To UBound(myArr)
Debug.Print (myArr(i))
Next i
End Sub
If you mean you want to set an array equal to the values in a named range,instead of entering them manually (like your example), then just set the array equal to the range. As long as "kategoria_agronomiczna_gleby" is your named range.
kategoria_a = ActiveWorkbook.Range("kategoria_agronomiczna_gleby")
You can use this loop to check the values in your array
For i = LBound(kategoria_a, 1) To UBound(kategoria_a, 1)
Debug.Print kategoria_a(i, 1)
Next

VBA Creating an excel chart using values in an array

I have some data in a two dimensional array and I need to create a chart using excel charts. However, it seems that the charts setsourcedata accepts only range. This means that I have to store the array in a range on a spreadsheet somewhere and then pass the range to the chart as an input. So i created a temp sheet to store the data in a specific range and then plan to pass it to the create chart call. Here is a type that I created
Private Type CItem
CName As Variant
CWeek(13) As Variant
CDisabled(13) As Variant
CEmpty(13) As Variant
CEnabled(13) As Variant
End Type
Dim CItemArray(100) As CItem
cnt1 = 0
//.. do something
ActiveWorkbook.Sheets.Add(After:=Sheets("MainSheet")).Name = "WK_Report"
Worksheets("WK_Report").Range("C3:C15").value = CItemArray(cnt1).CWeek()
Worksheets("WK_Report").Range("D3:D15").value = CItemArray(cnt1).CDisabled()
Worksheets("WK_Report").Range("E3:E15").value = CItemArray(cnt1).CEnabled()
Worksheets("WK_Report").Range("F3:F15").value = CItemArray(cnt1).CEmpty()
My goal is to assign the entire array of CWeek for the first CItem to the range of C3:C15 respectively. However, the syntax I used above assigns the first element of Cweek, CDisabled, CEnabled, CEmpty to the entire range. I tried without the parentheses after CWeek and others, but the result is same.
How can I assign the array values to the range? I know that the values are in the array because I did a debug.print after assigning to verify.
You can use Application.Transpose: here's a simplified example
Option Explicit
Private Type CItem
CWeek(13) As Variant
End Type
Sub Tester()
Dim itm As CItem, x As Long
For x = 1 To 14
itm.CWeek(x - 1) = x
Next x
ActiveSheet.Range("C3:C15").Value = itm.CWeek '>> all "1"
ActiveSheet.Range("D3:D15").Value = Application.Transpose(itm.CWeek) '>> 1 to 13
End Sub
You've left out how you are populating the user defined type arrays but you should move to a 2-D variant array.
Private Type CItem
CName As Variant
CStuff(1 to 13, 1 to 4) As Variant
End Type
Dim CItemArray(100) As CItem, cnt1 as long
//.. populate 100 CItemArray.CStuff with 13 rows by 4 columns each
ActiveWorkbook.Sheets.Add(After:=Sheets("MainSheet")).Name = "WK_Report"
cnt1 = 1
with Worksheets("WK_Report").Range("C3")
.resize(ubound(CItemArray(cnt1).CStuff, 1), ubound(CItemArray(cnt1).CStuff, 2)) = CItemArray(cnt1).CStuff
end with
From my point of view, the user defined type is only getting in the way but once you get it working it may be a 'set and forget' type of thing. I used a 1-based array so you didn't have to add 1 to the ubounds.

Using VBA to assign range of cell values to array of variables

I'm very new to VBA, to bear with me here.
I want to assign a set of variables the value of a set of ranges ie. run a brief code to simplify the following
Dim Sample 1 as string
Sample1 = activeworksheet.range("C17").value
Dim Sample 2 as string
Sample2 = activeworksheet.range("C18").value}
and so on
Following an excelfunctions.net tutorial, I know that I can shorten the declaration to
Dim Sample(1 to 20) as a string
But the tutorial drops it there(because it's a tutorial about names), suggesting I populate it as follows
sample(1)=activesheet.range("C7").value
sample(2)=activesheet.range("C7").value
and so on
I found the discussion below to be on the right track to answer my quest, but I am having trouble applying it to my situation. (Excel VBA Array Ranges for a loop)
As a follow up note, I am ultimately trying to assign values to these variables for use in the following procedures, rather than declaring and assigning them each time.
Thanks!
Try something like this:
Sub test()
Dim sampleArr(1 To 20) As String
Dim i As Integer
Dim rng As Range, cel As Range
i = 1
Set rng = Range("C1:C20")
For Each cel In rng
sampleArr(i) = cel.Value
i = i + 1
Next cel
For i = LBound(sampleArr) To UBound(sampleArr)
Debug.Print sampleArr(i)
Next i
Also, if you know the range you want to put into an array, you can simply set an array to that range:
Sub test()
Dim sampleArr() As Variant
Dim i As Integer
Dim rng As Range, cel As Range
i = 1
Set rng = Range("C1:C20") ' Note, this creates a 2 Dimensional array
sampleArr = rng ' Right here, this sets the values in the range to this array.
For i = LBound(sampleArr) To UBound(sampleArr)
Debug.Print sampleArr(i, 1) ' you need the ",1" since this is 2D.
Next i
End Sub
You should :
Define the range you want to retrieve data
For each cell of the range, retrieve your datas
dim tab() As string, cell as range, i as integer
i = 0
redim tab(0)
for each cell in ActiveWorksheet.Range("C1:C20")
tab(i) = cell
i = i + 1
redim preserve tab(i)
next
edit : I indent the code to display it correctly
Additional way to the above you can only use:
Arr = ActiveWorksheet.Range("C1:C20").Value
Then you can directly use:
Arr(i,1) where i is C1 to C20 range!

Assigning Range array from a returning function

I want to have an array of ranges to create charts from them.
Here's how I had it:
Dim infoR As Range
Dim aRng() As Range
Dim numLvls As Integer
Set infoR = Range("H1:H100");
numLvls = getLevels()
Set aRng() = getOnlyNumericCellToArrayRanges(infoR, numLvls)
The function is this:
Function getOnlyNumericCellsRangesArrays(ByVal actRange As Range, ByVal numLvls As Integer) As Range()
Dim aRng() As Range
Redim aRng(0 To numLvls - 1)
'Some code
Set getOnlyNumericCellToArrayRanges = aRng()
End Function
I've seen several arrays examples over the internet and they use variant as a data type for that means but it doesn't compile like that too.
I've found that works with some changes:
Dim aRng
'Some code
aRng = getOnlyNumericCellToArrayRanges(infoR)
I think passing the array by reference could work, however I want to know if there is a way to make the array declaration and assignment to Range data type explicitly from the beginning.
Or how can I cast the result array back into a Range array?
An array is not an object (even when it's an array of objects), so you don't need Set here...
Sub Tester()
Dim arrRng() As Range, x As Long
arrRng = GetRangeArray()
For x = LBound(arrRng) To UBound(arrRng)
Debug.Print arrRng(x).Address()
Next x
End Sub
Function GetRangeArray() As Range()
Dim arrRng() As Range
ReDim arrRng(1 To 3)
Set arrRng(1) = ActiveSheet.Range("A1")
Set arrRng(2) = ActiveSheet.Range("A3")
Set arrRng(3) = ActiveSheet.Range("A5")
GetRangeArray = arrRng
End Function

Moving an Array to a Range VARIABLE

I am trying to find this but I can't! Is it possible to move/copy and VBA Array to a Range Variable, I am not saying a Range cells, it's a Range that you declare (ex: DIM ran as Range)
I want something like this:
Public Function test()
Dim ran As Range
Dim myArray(4) As Integer
myArray(1) = 1
myArray(2) = 2
myArray(3) = 3
myArray(4) = 4
'If I do this, it works!
Range("A1:A4") = myArray
'But I want this and it does not work!
ran = myArray
End Function
Thanks!
Even though the Range is declared in code, it's still a Range, not an array. If myArray is actually a Range object (in which case you should re-think your naming conventions) you should be able to do what your example showed.
However if your variable myArray is some other type of object (like and array) you can't just set it like that, you would have to write a method that converts myArray to a range.
EDIT:
I'm guessing that the reason that Range("A1:A4") = myArray works is because the assignment operator has been overloaded to support it as short-hand for Range("A1:A4").Value = myArray.
A Range however is not just an array, it's a data structure specific to Ranges of a workbook
When you declare Dim ran As Range you haven't actually initialized your Range object yet. I'm guessing that if you did the following it would work:
Dim ran As Range("A1:A4")
Dim myArray(4) As Integer
myArray(1) = 1
myArray(2) = 2
myArray(3) = 3
myArray(4) = 4
ran = myArray
If you set a variant to a worksheet range you get a 2 dimensional array. Try this
Sub MoveArray()
Dim myArray
myArray = Range("A1:B3").Value
Range("A6:B8").Value = myArray
End Sub
Or this
Sub MoveArray2()
Dim myArray
Dim myArray2
Dim myRange
Dim i As Integer
Dim j As Integer
myArray = Range("A1:B3").Value
Set myRange = Range("A6:B8")
For i = 1 To myRange.Rows.Count
For j = 1 To myRange.Columns.Count
myRange.Cells(i, j) = myArray(i, j)
Next j
Next i
myArray2 = myRange
End Sub
In either case the variant becomes an array rather than a range object and the loops set the values of the range from the array.
Edit
As you can see from the comments in the questions/answers in this thread a range is not an array, it is a complex object that has many properties and methods. One of the properties (I think the default property) is value. This property is in fact a 2 dimensional array (or at least behaves like one) of the values of the cells in the range. As such if myArray is also a 2 dimsensional aray the code myRange = myArray will execute. What will happen is the value of the cells that the range refers to will be set to the values in the array. The range refers to these cells, but it is the values in the cells that change rather than the range object.
As such if if you transfer a range to a diferent set of cells the new set of cells retains it's values.
On a practical side if you want to change the values of the cells that a range referes to you can do it as shown below:
Sub Test1()
Dim myArray(1 To 4, 1 To 1)
Dim myRange As Range
myArray(1, 1) = 1
myArray(2, 1) = 2
myArray(3, 1) = 3
myArray(4, 1) = 4
Set myRange = Range("A1:A4")
myRange = myArray
End Sub

Resources