简体   繁体   中英

How to set a dynamic range of cells using VBA?

Let's say I have a loop written, but need to Set lots of ranges for it to work. How can I set one range to contain cells that are spread out across a worksheet. Let's say in each row, I want to selected cells from column J, column S, column T.... all the way to column GB (5 columns between each). The pseudo-script I have goes something like this:

Sub CountPubs()


    Dim i, j As Long
    Dim Quant As Range

    i = 2
    j = 5
    While i <= 400

    Set Quant=Cells("I" & i),("I+j" & i),("I+2j" & i)... 

So the Set line is terrible. The loop itself will increase i every time a condition is met, but I want the 36 cells spread out across row i, as defined by Quant, to increase too. How can I complete that Set Quant line in a way that will do this?

EDIT: In my testing, I can't even get a simpler version right. If I was just to make this go as far as T, I imagine the script would be:

Sub CountPubs()
    Dim Count As Range
    Dim i As Long
    Dim Publications As Range
    i = 2
    Set Count = Range("C" & i)
    Set Publications = Range("I" & i), ("O" & i), ("T" & i)

But this gives me a compile error, with the wrong number of arguments or invalid property assignment. Am I defining the last range incorrectly here?

You can use the Union method to create a range of cells which are not next to one another.

In your scenario, you could use the below:

Sub unionCells()
    Dim i, j As Long
    Dim Quant As Range

    i = 2
    j = 5
    While i <= 400
        Set Quant = Union(Cells(9, i), Cells(9 + j, i), Cells(9 + 2 & j, i))
    Wend
End Sub

You can also see this answer about using union.

You are going to want to use the Union method to build the Quant range.

Dim i As Long, rw As Long, Quant As Range

With ActiveSheet
    rw = 2  'this will work on row 2 from J to GB
    Set Quant = .Cells(rw, "J") 'seed the target range
    'Set Quant = .Cells(rw, "J").Resize(400, 1) 'optional 400 rows deep

    For i = .Columns("J").Column To .Columns("GB").Column Step 5
        Set Quant = Union(Quant, .Cells(rw, i))
        'Set Quant = Union(Quant, .Cells(rw, i).Resize(400, 1)) 'optional 400 rows deep
    Next i

    Debug.Print Quant.Address(0, 0)
End With

I've included option lines that are 400 rows deep.

An alternative method to the union function would be to create an Array of Ranges, and in your loop, add each new cell as the next item in your array.

There are some obvious drawbacks, such as the fact that you would be unable to refer to the Range as a whole, and also that you would need to first determine the size of the array before you begin to add items to it. However, it does have a benefit in that it would allow you to refer to each cell by reference to a single index number. This may be useful if you were tracking the cells in order and you would only want to refer to cells 1 at a time by reference to that order. This would work as follows [Some snippets stolen from @Jeeped above]:

Dim i As Long, rw As Long, Quant() As Range, QuantSize As Long

With ActiveSheet

    For i = .Columns("J").Column To .Columns("GB").Column Step 5
        QuantSize = QuantSize + 1 'builds in the size of the array
    Next i

    ReDim Quant(1 To QuantSize) 'Resizes the array to match the total length above

    rw = 2  'this will work on row 2 from J to GB

    For i = .Columns("J").Column To .Columns("GB").Column Step 5
        Set Quant(i) = .Cells(rw, i)
    Next i

End With

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM