Search code examples
excelvbaparametersrange

Passing a range of columns as a constant parameter


I am trying to pass a range of columns as a parameter for a function.

For sr = 1 To srCount 
    If IsEmpty(Data(sr, 4)) Then
        
        dr = dr + 1
        Data(dr, 4) = Data(sr, 1) 'instead of just the first column, a range of columns
        
    End If
Next sr

I thought I could define a range ("A:C") and pass its reference as a parameter, but VBA doesn't seem to accept anything but (references to) long variables/constants as parameters for the Data() function. What is the correct syntax for such a thing?

Edited 01/26 for clarification: Data is an array. The goal is to copy a row of a range of columns based on the condition that another cell in that row is empty (If IsEmpty(Data(sr, 4))). E.g. if cell(7,4) is empty, then row 7 of columns A-C should be copied to another area of the worksheet (K2:M2). If (13,4) is empty, then row 13, columns A-C to K3-M3, and so on.

As per @Cameron's tip I used Collections to store the ranges instead.

Dim users As New Collection
Dim cell As Range

With Worksheets(2) 
    users.Add .Range("A:C"), "Users"    
    users.Add .Range("K:M"), "FinalList"

End With


For Each cell In users.Item("Users")
   For sr = 1 to srCount
    If IsEmpty(Data(sr, 4)) Then
        
        dr = dr + 1
        FinalList = Users

    End If
Next sr
   
Next

Despite the research I can't find how I can manipulate Collections for this objective. Once I have all the necessary values stored in FinalList, how can I copy them to the goal Range ("K:M")?


Solution

  • Using a Single Array to Extract Matching Data

    Option Explicit
    
    Sub Test()
        
        Const SRC_CRITERIA_COLUMN As Long = 4
        Const DST_WORKSHEET_ID As Variant = 2 ' using the tab name is preferable!
        Const DST_FIRST_CELL As String = "K2"
        ' The following could be calculated from the source variables.
        Const DST_COLUMNS_COUNT As Long = 3
        
        Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
        
        ' whatever...
        
        Dim Data() ' ?
        Dim srCount As Long ' ?
        
        ' whatever...
        
        Dim sr As Long, dr As Long, c As Long
        
        ' Write the matching values to the top of the array
        ' When using a single array, the result needs to be in the top-left
        ' of the array. The data of interest is already left-most
        ' so there is no column offset.
        For sr = 1 To srCount
            If IsEmpty(Data(sr, SRC_CRITERIA_COLUMN)) Then
                dr = dr + 1
                For c = 1 To DST_COLUMNS_COUNT
                    Data(dr, c) = Data(sr, c)
                Next c
            End If
        Next sr
    
        ' Reference the destination range.
        Dim dws As Worksheet: Set dws = wb.Worksheets(DST_WORKSHEET_ID)
        Dim dfCell As Range: Set dfCell = dws.Range(DST_FIRST_CELL)
        ' Note how you're using just the 'dr' number of rows
        ' and 'DST_COLUMNS_COUNT' number of columns.
        Dim drg As Range: Set drg = dfCell.Resize(dr, DST_COLUMNS_COUNT)
        
        ' Write the result from the top-left of the array to the destination range.
        drg.Value = Data
        ' Clear below.
        drg.Resize(dws.Rows.Count - drg.Row - dr + 1).Offset(dr).ClearContents
    
        MsgBox "Data copied.", vbInformation
    
    End Sub