Reputation: 107
I'm trying to combine the values in a range of cells. I created a range as follows:
Dim rng As Range
Set rng = Application.Union(Range("A1:A3"), Range("C1:E2"))
For Each Address In rng
Debug.Print Address.Address
Next
I want to read the cells in horizontal order: A1,C1,D1,E1,A2,C2... etc. But instead they're being read A1,A2,A3,C1,C2,.. etc
How can I read them horizontally? Thanks
Upvotes: 2
Views: 1044
Reputation: 859
Just thought this might be an interesting addition to Chris' solution? (I changed the range slightly to highlight some of the advantages)
Dim Rng As Range, Col As Variant, Rw As Variant
Set Rng = Application.Union(Range("A3:A5"), Range("C2:E4"))
For Each Rw In ActiveSheet.UsedRange.Rows
For Each Col In Rw.Columns
If Not Intersect(Col, Rng) Is Nothing Then Debug.Print Intersect(Col, Rng).Address
Next Col
Next Rw
Upvotes: 0
Reputation:
You have to deal with the Range.Areas within the Range object created with the Union method.
Sub laterally()
Dim r As Long, c As Long, a As Long
Dim mnRW As Long, mxRW As Long, mnCL As Long, mxCL As Long
Dim rng As Range
With Worksheets("Sheet1") '<~~ ALWAYS set the worksheet!
Set rng = Union(.Range("A1:A3"), .Range("C1:E2"))
Debug.Print rng.Address(0, 0)
mnRW = Rows.Count: mxRW = 0
mnCL = Columns.Count: mxCL = 0
With rng
For a = 1 To .Areas.Count
With .Areas(a)
mnRW = Application.Min(mnRW, .Rows(1).Row)
mxRW = Application.Max(mxRW, .Rows(.Rows.Count).Row)
mnCL = Application.Min(mnCL, .Columns(1).Column)
mxCL = Application.Max(mxCL, .Columns(.Columns.Count).Column)
End With
Next a
For r = mnRW To mxRW
For c = mnCL To mxCL
If Not Intersect(.Cells, .Parent.Cells(r, c)) Is Nothing Then _
Debug.Print .Parent.Cells(r, c).Address(0, 0)
Next c
Next r
End With
End With
End Sub
After collecting the extents of the unioned range, each possible cell is looped through and the Intersect method is used to determine whether it belongs in the union or not.
Upvotes: 5
Reputation: 1518
A union of ranges doesn't care in which order the cells are added - whether it's by row or by column. So your original loop to unify the ranges is fine.
If you're concerned about the order in which you read the data, simply read by row or by column accordingly, with an inner and an outer loop. So for example, after you build the range, do as follows:
Dim Col as Variant, Rw as Variant
For Each Col in rng.Columns
For each Rw in Col.Rows
Debug.Print Rw.Address
Next Rw
Next Col
Upvotes: 3