Home > database >  Calling Function with Range as Parameters
Calling Function with Range as Parameters

Time:06-09

I am trying to call a function with parameters as follows.

Private Sub Load_Data(File_Path As String)
    Dim data() As String
    'data = data_range_str(Range("rng_tbl_cell_ref_ttl_rows"), Range("rng_tbl_cell_ref_st_row"), Range("rng_CV_Col_No_A1"), Range("rng_cell_ref_sheet"))
    data = data_range_str(67, 6, 3, "Cell_Ref")
End Sub

Function data_range_str(row_count As Integer, offset_row As Integer, col As Integer, w_sheet_name As String) As String()
    Dim i As Integer
    Dim data_range_string() As String
    ReDim data_range_string(row_count - 1) As String
    
    If row_count > 1 Then
        For i = 0 To row_count - 1
            data_range_string(i) = ThisWorkbook.Worksheets(w_sheet_name).Cells(offset_row   i, col)
        Next i
    ElseIf row_count = 1 Then
        data_range_string(0) = ThisWorkbook.Worksheets(w_sheet_name).Cells(offset_row, col)
    End If
    data_range_str = data_range_string
End Function

When I call the data_range_str function with excel range as commented in the codes, it shows [Error 1004:Method 'Range' of object '_Global' failed]. But when I call the function with hardcoded parameters as in above code, it is OK.

Please help me to be able to call with variables.

CodePudding user response:

Not all details are given, so I had to guess a bit. This is my guess:

data = data_range_str(Range("rng_tbl_cell_ref_ttl_rows").Rows.Count, Range("rng_tbl_cell_ref_st_row").Row, Range("rng_CV_Col_No_A1").Column, Range("rng_cell_ref_sheet").Text)

It might be wrong, but I think you get the picture. A range is not a value, but an object with a lot of properties, such as row, column and a lot more.

CodePudding user response:

This should work. When working with arrays defined from ranges, they need to be of Variant type, even though the contents are still of String type (or Double). Also the arrays need to be 1 based and have a rank of 2. These are just conventions that Microsoft has introduced. in their design of Excel/VBA

ALso no need to loop through the data, but rather just use the .Resize() function to reference multiple cells at once.

Private Sub Load_Data(File_Path As String)
    Dim data() As Variant, first as String
    data = DataRangeVals(67, 6, 3, "Cell_Ref")
    first = data(1,1)
End Sub

Public Function DataRangeVals(ByVal row_count as Long, byVal offset_row as Long, ByVal col as Long, ByVal w_sheet_name as String) as Variant()
    Dim data() as Variant
    If row_count>1 then
        data = Sheels(w_sheet_name).Cells(offset_row,col).Resize(row_count,1).Value
    ElseIf row_count=1 Then
       ReDim data(1 to 1, 1 to 1)
       data(1) = Sheels(w_sheet_name).Cells(offset_row,col).Value
    Else
       data = Array()  'Empty array
    End if
    DataRangeVals = data
End Function

There is a caveat in the op code, when it uses .Cells() as opposed to .Offset(), depending on the numbers passed to the function. With offset_row=6 and col=3 the corresponding cell address is

Cells(6,3) => "C6"
Offset(6,3) => "D7"

I just want to point out if the numbers are offsets from the first cell then you need to use the .Offset() function, or if the numbers are index values in the worksheets, then .Cells() is what is needed.

I want to offer a better alternative, that uses a source range, and the row count. So the referencing of the data is done outside the function where you have more control of how it is done.

Private Sub Load_Data(File_Path As String)
    Dim data() As Variant, first as String
    data = DataRangeVals(Worksheets("Cell_Ref").Cells(6,3), 67)
    first = data(1,1)
End Sub

Public Function DataRangeVals(ByVal r_src as Range, ByVal row_count as Long, Optional ByVal col_count As Long = 1) as Variant()
    Dim data() as Variant
    If row_count>1 Or col_count>1 then
        data = r_src.Resize(row_count,col_count).Value
    ElseIf row_count=1 And col_count=1 Then
       ReDim data(1 to 1, 1 to 1)
       data(1) = r_src.Value
    Else
       data = Array()  'Empty array
    End if
    DataRangeVals = data
End Function
  • Related