I want to get the whole second column in range("A1:B15"). Of course , I can use 'Range("B1:B15")' but the range may change according to the situations like different WorkSheets. So I need to get the range of the second column dynamically.
The following code I made first pops up an error(Runtime error 13: Type mismatch).
Sub test1()
Dim r As Range
For Each r In Range("A1:B15").Columns(2)
Debug.Print r '// Runtime Error '13': Type mismatch.
Next r
End Sub
I thought that 'Columns(2)' is a kind of range, each cell of which can be accessed one by one. To my disappointment, here 'Range("A1:B15").Columns(2)' is not a normal series of range. Though, 'Range("A1:B15").Columns(2)' has an Address: '$B$1:$B:$15.' I couldn't understand this, at first.
To find out why the error occurs, I tried the following code.
Sub test2()
Dim r As Range, TargetColumn As Range
Set TargetColumn = Range("A1:B15").Columns(2)
Debug.Print TargetColumn.Count '//count is 1, not 15
For Each r In TargetColumn
Debug.Print r.Address '//$B$1:$B$15
Next r
End Sub
'TargetColumn.count' is not 15, but 1. 'r.address' is only "$B$1:$B$15.", not a series of "$B$1, $B$2, $B$3 ...." So 'Columns(2)' is not a normal series of range, but only a single range like a merged cells of range("$B$1:$B$15").
To bypass the type mismatch error, I changed the code like this:
Sub test3()
Dim r As Range, TargetColumn As Range
Set TargetColumn = Range("A1:B15").Columns(2)
' get the range using the address : Range("A1:B15")
For Each r In Range(TargetColumn.Address)
Debug.Print r.Address, r.Value ' works well
Next r
End Sub
'Columns(2)' is not a normal series of range but a collection of range areas. It does have an address, which can be used in 'Range(Address).'
For example, 'Columns(1).address' is '$A$1:$A$15.' and 'Columns(2).address' is '$B$1:$B$15.' So the 'Columns' object is a collection of each columns. It is just like 'Union(range("$A$1:$A$15"), range("$B$1:$B$15"))'. Therefore, we can not access directly each cell in 'Columns(2).'
Is there an easier and simpler way to get a column range so that I can access each cell in the column range? I believe there must be a better way than 'Range(Range("A1:B15").Columns(2).address)' or 'Range("A1:B15").Columns(2)' which fails to run. 'Range("A1:B15").Columns(2).EntireRow' returns the whole range of "B:B" which I don't like to use.