+ Reply to Thread
Results 1 to 11 of 11

Function argument's cell adress

Hybrid View

  1. #1
    Registered User
    Join Date
    08-26-2009
    Location
    London
    MS-Off Ver
    Excel 2007
    Posts
    28

    Function argument's cell adress

    Hi all!

    I have an attached file and I am trying to build a VBA function to calculate total values. First row is "RollingTime" and for example if I am trying to calculate the "Total" value. For "RollingTime" = 2 it should be

    RollingTime(2)*Percentage(2)+RollingTime (1)*(1-Percentage(1))*Percentage(2)+RollingTime(0)*(1-Percentage(0)*(1-Percentage(1))*Percentage(2)

    Which is 109732508*0,3 + 1017508995*(1-0,2)*0,3+1587172158*(1-0,1)*(1-0,2)*0,3

    And here is the code I have tried to produce:

    Function Calls(Percentage As Double, Amount As Double, RollingTime As Integer) As Double
    
    Dim i As Integer, Previous As Double
    
    Previous = 0
    
    If RollingTime = 0 Then
        Calls = Percentage *Amount
        Exit Function
    End If
    
    
    For i = 1 To RollingTime
        
            
            Previous = Amount.Offset(0, -i).Value + Previous * (1 - CallProb.Offset(0,-i)) ^ i
           
            
            
    Next
    
    Calls = CallProb * CallAmount + Previous
    
        
        
    End Function

    The problem in the function is that I (of course) cannot use "Amount.Offset" or "CallProb.Offset". So how could I determine what are the cell adresses for those arguments? So if the RollingTime argument is "2", Amount.offset(0,-2).Value would be 1587172158.

    Hope I am not too confusing..

    -John
    Attached Files Attached Files

  2. #2
    Forum Guru DonkeyOte's Avatar
    Join Date
    10-22-2008
    Location
    Northumberland, UK
    MS-Off Ver
    O365
    Posts
    21,531

    Re: Function argument's cell adress

    What is CallProb meant to reflect ? You are not passing a Variable of that name - so presumably Percentage ?

    As a general rule of thumb when using UDFs - whenever the values being passed originate from cells pass the variables as Ranges and not as values/data types as this gives you far greater flexibility in the long-run, eg instead of:

    C1: =FEX(A1,B1)
    
    Function FEX(x As Double, y As Double) As Double
    FEX = x * y * x.Offset(,-1).Value
    End Function
    which would fail (Offset as per your own function) you would use

    Function FEX(x As Range, y As Range) As Double
    FEX = x.Value * y.Value * x.Offset(,-1).Value
    End Function
    ie Range objects give you far more flexibility ...

    Going back to your actual question... so this is a recursive calc ?

    ie Previous should really be a cumulative total, ie

    For i = 1 to RollingTime
        Previous = Previous + calc for i
    Next i
    Correct ?

  3. #3
    Forum Guru DonkeyOte's Avatar
    Join Date
    10-22-2008
    Location
    Northumberland, UK
    MS-Off Ver
    O365
    Posts
    21,531

    Re: Function argument's cell adress

    Based on your original post and:

    Quote Originally Posted by John99
    RollingTime(2)*Percentage(2)+RollingTime (1)*(1-Percentage(1))*Percentage(2)+RollingTime(0)*(1-Percentage(0)*(1-Percentage(1))*Percentage(2)

    Which is 109732508*0,3 + 1017508995*(1-0,2)*0,3+1587172158*(1-0,1)*(1-0,2)*0,3
    I wonder if the below will work for you ?

    Function TOTALCALLS(rngRT As Range, rngAmt As Range, rngPct As Range) As Variant
    Dim bRT As Byte, dblPct As Double
    If Application.Count(rngRT, rngAmt, rngPct) < 3 Then
        TOTALCALLS = "Input Error"
        Exit Function
    End If
    For bRT = 0 To rngRT Step 1
        dblPct = IIf(bRT, dblPct * (1 - rngPct.Offset(, -bRT).Value), rngPct.Value)
        TOTALCALLS = TOTALCALLS + (rngAmt.Offset(, -bRT).Value * dblPct)
    Next bRT
    End Function
    Called from cell as:

    B9: =TOTALCALLS(B6,B7,B8)
    copied across
    For Rolling Time of 2 (ie D9) the above would generate 619951097.3 which I believe ties out to your initial post.
    Last edited by DonkeyOte; 09-16-2009 at 03:19 AM. Reason: removed superfluous Select Case

  4. #4
    Registered User
    Join Date
    08-26-2009
    Location
    London
    MS-Off Ver
    Excel 2007
    Posts
    28

    Re: Function argument's cell adress

    DonkeyOte,

    Thank you for your answer! The CallProb was actually supposed to be Percentage. I have been changing names and I forgot to change that one.

    Range object is really the way to go here and the function works nicely.

    This might be a stupid question but if I am changing the Percentage for the RollingTime = 2, where can i define that it recalcutes the TOTALCALLS values for RollingTimes =3,4,5..? Now i have to copy across the cells every time I am changing the Percentage argument..¨

  5. #5
    Forum Guru DonkeyOte's Avatar
    Join Date
    10-22-2008
    Location
    Northumberland, UK
    MS-Off Ver
    O365
    Posts
    21,531

    Re: Function argument's cell adress

    Quote Originally Posted by John99
    This might be a stupid question but if I am changing the Percentage for the RollingTime = 2, where can i define that it recalcutes the TOTALCALLS values for RollingTimes =3,4,5..? Now i have to copy across the cells every time I am changing the Percentage argument.
    Not at all, this is a key point when using UDFs, you want to avoid the requirement of Application.Volatile given UDFs are generally slower than native Functions, making UDFs Volatile is generally bad news.

    The answer is to perhaps alter the approach such that you pass the "cumulative ranges" so to speak, eg:

    Function TOTALCALLS(rngRT As Range, rngAmt As Range, rngPct As Range) As Variant
    Dim lngRT As Long, dblPct As Double
    If Application.Count(rngRT, rngAmt, rngPct) <> Union(rngRT, rngAmt, rngPct).Cells.Count Then
        TOTALCALLS = "Input Error"
        Exit Function
    End If
    For lngRT = rngRT To 0 Step -1
        dblPct = IIf(lngRT <> rngRT.Value, dblPct * (1 - rngPct(1 + lngRT).Value), rngPct(1 + lngRT).Value)
        TOTALCALLS = TOTALCALLS + (rngAmt(1 + lngRT).Value * dblPct)
    Next lngRT
    End Function
    Using your original file:

    B9: =TOTALCALLS(B$6,$B$7:B$7,$B$8:B$8)
    copied across
    As you alter the % you should find your results adjust accordingly given you're now explicitly setting a dependency in the Function to those % cells, ie altering the % in say D8 would cause all functions from D onwards to recalculate given explicitly referencing D8 in the Function call.

  6. #6
    Registered User
    Join Date
    08-26-2009
    Location
    London
    MS-Off Ver
    Excel 2007
    Posts
    28

    Re: Function argument's cell adress

    DonkeyOte,

    Thanks so much for your code. Cumulative ranges seems to be doing a good job!

    Br,
    John

  7. #7
    Registered User
    Join Date
    08-26-2009
    Location
    London
    MS-Off Ver
    Excel 2007
    Posts
    28

    Re: Function argument's cell adress

    Hi!

    My function is working nicely when I have argument ranges horizontally. But if I am trying to use vertical data I cannot get it work. So I have to modify the following part of my code.
    For lngRT = rngRT To 0 Step -1
        dblPct = IIf(lngRT <> rngRT.Value, dblPct * (1 - rngPct(1 + lngRT).Value), rngPct(1 + lngRT).Value)
        
        HTOTALCALLS = HTOTALCALLS + (rngAmt(1 + lngRT).Value * dblPct)
    Next lngRT
    Any ideas what I have to do? I struggled quite awhile now but cannot get it work..

    rngPct(1 + lngRT).Value and rngAmt(1 + lngRT).Value are the ones i should be modifying..

    Thanks for any help!

    -Jack


    Function VTOTALCALLS(rngRT As Range, rngAmt As Range, rngPct As Range) As Variant
    Dim lngRT As Long, dblPct As Double
    If Application.Count(rngRT, rngAmt, rngPct) <> Union(rngRT, rngAmt, rngPct).Cells.Count Then
        HTOTALCALLS = "Input Error"
        Exit Function
    End If
    
    For lngRT = rngRT To 0 Step -1
        dblPct = IIf(lngRT <> rngRT.Value, dblPct * (1 - rngPct(0, 1 + lngRT).Value), rngPct(0, 1 + lngRT).Value)
        
        HTOTALCALLS = HTOTALCALLS + (rngAmt(0, 1 + lngRT).Value * dblPct)
    Next lngRT
    
    
    End Function

  8. #8
    Registered User
    Join Date
    08-26-2009
    Location
    London
    MS-Off Ver
    Excel 2007
    Posts
    28

    Re: Function argument's cell adress

    Hi! here is the attachment with a VTOTALCALLS example.. just missing the values of the function..
    Attached Files Attached Files

  9. #9
    Forum Guru DonkeyOte's Avatar
    Join Date
    10-22-2008
    Location
    Northumberland, UK
    MS-Off Ver
    O365
    Posts
    21,531

    Re: Function argument's cell adress

    By my reckoning the existing function will work equally well in either direction, all that needs to alter are the range references when calling from the cell

    Horizontal:
    C7: =TOTALCALLS(C$4,$C$6:C$6,$C$5:C$5)
    copied across to P=7

    Vertical
    E12: =TOTALCALLS($B12,$D$12:$D12,$C$12:$C12)
    copied down to E25

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1