Home » excel » excel – Dynamically Select Cells For Use in a VBA Function

excel – Dynamically Select Cells For Use in a VBA Function

Posted by: admin May 14, 2020 Leave a comment

Questions:

I’ve written the function below that I would like to use dynamically in my excel sheet where the function would assess the value of the variable selected in the formula and based on that value, perform a simple calculation referencing values in cells in different columns but in the same row.

I know that the code below works, but how can I rewrite the ranges so that my function can be used dynamically for each row of the same column?

Function AddedValue(TabSize As Integer)

Select Case TabSize

    Case 2
        AddedValue = Range("K3") * (Range("N3") * (Range("H3") * 0.001))

    Case 4
        AddedValue = Range("K3") * (Range("O3") * (Range("H3") * 0.001))

    Case 6
        AddedValue = Range("K3") * (Range("P3") * (Range("H3") * 0.001))

    Case 8
        AddedValue = Range("K3") * (Range("Q3") * (Range("H3") * 0.001))

    Case 10
        AddedValue = Range("K3") * (Range("R3") * (Range("H3") * 0.001))

End Select
End Function
How to&Answers:

You can add an input for the row and then concatenate the row to your range strings. Like so:

Function AddedValue(TabSize As Integer, iRow as Long)

Select Case TabSize

    Case 2
        AddedValue = Range("K" & iRow) * (Range("N" & iRow) * (Range("H" & iRow) * 0.001))

    Case 4
        AddedValue = Range("K" & iRow) * (Range("O" & iRow) * (Range("H" & iRow) * 0.001))

    Case 6
        AddedValue = Range("K" & iRow) * (Range("P" & iRow) * (Range("H" & iRow) * 0.001))

    Case 8
        AddedValue = Range("K" & iRow) * (Range("Q" & iRow) * (Range("H" & iRow) * 0.001))

    Case 10
        AddedValue = Range("K" & iRow) * (Range("R" & iRow) * (Range("H" & iRow) * 0.001))

End Select
End Function

Answer:

You can use Application.Caller to detect the cell that is running the Function:

Public Function AddedValue(TabSize As Integer)
    Application.Volatile
    r = Application.Caller.Row
    With Application.Caller.Parent.Rows(r)
        firstcell = .Cells(1, 11) ' column K
        Select Case TabSize
            Case 2
                secondcell = .Cells(1, 14) ' column N
            Case 4
                secondcell = .Cells(1, 15) ' column O
            Case 6
                secondcell = .Cells(1, 16) ' column P
            Case 8
                secondcell = .Cells(1, 17) ' column Q
            Case 10
                secondcell = .Cells(1, 18) ' column R
            End Select
        thirdcell = .Cells(8) ' column H
        AddedValue = firstcell * (secondcell * (thirdcell * 0.001))
    End With
End Function

Alternatively, if TabSize is uniform in the way your question suggests – you could also ‘calculate’ which column from it:

Public Function AddedValue2(TabSize As Integer)
    Application.Volatile
    r = Application.Caller.Row
    With Application.Caller.Parent.Rows(r)
        firstcell = .Cells(1, 11) ' column K
        secondcell = .Cells(1, 13 + (TabSize / 2)) ' dynamic column from TabSize
        thirdcell = .Cells(8) ' column H
        AddedValue2 = firstcell * (secondcell * (thirdcell * 0.001))
    End With
End Function

Answer:

Well, the quick and easy way would be to pass the row as an argument to the function.

Function AddedValue(TabSize As Integer, row As Long)

Select Case TabSize
    Case 2
        AddedValue = Range("K" & row) * (Range("N" & row) * (Range("H" & row) * 0.001))
    Case 4
        AddedValue = Range("K" & row) * (Range("O" & row) * (Range("H" & row) * 0.001))
    Case 6
        AddedValue = Range("K" & row) * (Range("P" & row) * (Range("H" & row) * 0.001))
    Case 8
        AddedValue = Range("K" & row) * (Range("Q" & row) * (Range("H" & row) * 0.001))
    Case 10
        AddedValue = Range("K" & row) * (Range("R" & row) * (Range("H" & row) * 0.001))
End Select
End Function

Answer:

Does this have to be VBA? This formula only solution should work for you:

=$H3*0.001*$K3*INDEX($N3:$R3,,1)

The last 1 is the index of the column in that range (N:R) that you want. So 1 = “Use column N” and 2 = “Use Column O” etc. You can simply copy the formula and paste down rows and it will auto-adjust the row numbers while keeping the columns the same.

Additionally, if preferred, you can use a cell reference instead of hard-coding the “Selected Column/TabSize” number, like so (where the “Selected Column/TabSize” number in cell A1 in this example):

=$H3*0.001*$K3*INDEX($N3:$R3,,A1)

Answer:

Dynamic Cell Calculation

Option Explicit

Function AddedValue(TabSize As Long, row As Long) As Double

    Const cValue As String = "2,4,6,8,10"
    Const cStr1 As String = "K"
    Const cStr2 As String = "N,O,P,Q,R"
    Const cStr3 As String = "H"
    Const cDbl1 As Double = 0.001

    Dim vntV As Variant
    Dim vnt2 As Variant
    Dim i As Long

    vntV = Split(cValue, ",")
    vnt2 = Split(cStr2, ",")

    For i = 0 To UBound(vntV)
        If TabSize = CLng(Trim(vntV(i))) Then
            AddedValue = Range(cStr1 & row) * Range(Trim(vnt2(i)) & row) _
                    * Range(cStr3 & row) * cDbl1
            Exit For
        End If
    Next

End Function