How to put a complex worksheet function in VBA?

JenniferMurphy

Well-known Member
Joined
Jul 23, 2011
Messages
2,534
Office Version
  1. 365
Platform
  1. Windows
In this thread,


AhoyNC provided two worksheet expressions for fitting data to a power equation. The expressions are fairly complex. I fear that I will never remember them and will make many typos trying to type them. So I want to put them in a UDF. But they make use of several worksheet functions. Is there a way to put this expression in VBA without putting "application.worksheetfunction" in front of each function and making the expression span half a dozen lines?

VBA Code:
=EXP(INDEX(LINEST(LN(D2:D13),LN(B2:B13),,),1,2))

Thanks
 

Excel Facts

Does the VLOOKUP table have to be sorted?
No! when you are using an exact match, the VLOOKUP table can be in any order. Best-selling items at the top is actually the best.
After a lot of fiddling around, I came up with this UDF, which seems to work. I still need to add error codes. A couple of questions:
  1. Why does the EXP function fail if I put Application. in front of it?
  2. Is there any way to simplify this?
VBA Code:
'================================================================================================
'                           Fit a Power Equation to Sample Data

' Excel has an unreqasonably complex expression that finds the power equation that is
' the best fit for a set of sample data. This function makes that available in a more
' easily accessible form.

' The expression for the coefficient of the power equation:
'   =EXP(INDEX(LINEST(LN(TblMrX[Conf]),LN(TblMrX['#Reviews]),,),1,2))
'   =EXP(INDEX(LINEST(x2,x1,,),1,2))
'   =EXP(INDEX(x3,1,2))
' The expression for the exponent of the power equation:
'       =INDEX(LINEST(LN(TblMrX[Conf]),LN(TblMrX['#Reviews]),,),1)
'       =INDEX(LINEST(x2,x1),1)
'       =INDEX(x3,1)

'   Parameters
'     pXAxis  The X Axis values
'     pYAxis  The Y Axis values
'     pParm   "COEF" = Retirn the coefficient
'             'EXP"  = Return the exponent

'   Change Log
' 05/10/23  Based on this MrExcel thread:
'  https://www.mrexcel.com/board/threads/is-there-any-way-to-access-the-trendline-parameters-in-cell-expressions.1236795/
'================================================================================================
Function FitPower(pXAxis, pYAxis, pParameter As String)

Dim x1, x2, x3, x4
x1 = Application.Ln(pXAxis)
x2 = Application.Ln(pYAxis)
x3 = Application.LinEst(x2, x1)

Select Case UCase(pParameter)
  Case "COEF"
    x4 = Application.index(x3, 1, 2)
    FitPower = Exp(x4)            'Why no Application.?
  Case "EXP"
    FitPower = Application.index(x3, 1)
  Case Else
      
End Select

End Function

Here's a minisheet using it:

Amazon Ratings.xlsx
CDEF
5Rtg#ReviewsRankConf
659,46710.0132
739,10120.0130
848,49930.0136
9574440.0445
10444450.0608
11342760.0625
1258870.1328
1345680.1673
1433990.2045
1549100.4081
1654110.6270
1732120.8727
18
19CoefficientExponent
201.242141-0.49808Long expression
211.242141-0.49808My UDF
MrExcel
Cell Formulas
RangeFormula
E6:E17E6=RANK.EQ([@['#Reviews]],['#Reviews])
D20D20=EXP(INDEX(LINEST(LN(TblMrX[Conf]),LN(TblMrX['#Reviews]),,),1,2))
E20E20=INDEX(LINEST(LN(TblMrX[Conf]),LN(TblMrX['#Reviews]),,),1)
D21D21=fitpower(TblMrX['#Reviews],TblMrX[Conf],"coef")
E21E21=fitpower(TblMrX['#Reviews],TblMrX[Conf],"exp")
 
Upvote 0
VBA has it's own Exp function.
(sigh) So what? That's no reason for application.exp to fail. The worksheet has one, too.

PS: This is not directed at you. Sorry. It's just that Excel in general and VBA in particular is just a torture chamber.
 
Upvote 0
What's the point of replicating the function if it already exists?

You can see the full list of worksheet functions available via WorksheetFunction if you open the Object Browser (F2) and search for WorksheetFunction.

The members of the WorksheetFunction class are the worksheet functions that are available.

Similarly if you search for Math you'll see all the functions available in that class, including Exp.

Note, there are some functions, notably Trim, which have 2 'versions', a VBA one and a WorksheetFunction one.

The reason for this, as far as I'm aware, is that the worksheet function TRIM acts differently from the Trim function in VBA - I think the main difference is
that the worksheet version replaces multiple spaces between words with a single space, which the VBA version doesn't do.
 
Upvote 0
You are probably way past this stage but:
Is there a way to put this expression in VBA without putting "application.worksheetfunction" in front of each function and making the expression span half a dozen lines?
Did you try:
VBA Code:
    With Application
        FitPower = Exp(.Index(.LinEst(.Ln(pYAxis), .Ln(pXAxis)), 1, 2))
    End With

I fear that I will never remember them and will make many typos trying to type them.
For you consideration:
1) Wyn Hopkins from Access Analystics is a big fan of using Autocorrect to insert formulas he uses regularly.
This is then independent of the workbook, and available to you in all workbooks.
So you go into autocorrect and set up 2 or 3 characters that you want to use for the formula, put the formula in the replace with box.
Instead of the 2 ranges you would put a word or phrase no spaces as place holders.
To use it use your enter the identifying characters it inserts the formula and you double click on each range place holder and select the range.
Includes a 5 min video > Ref: Master INDEX MATCH in 60 Seconds

2) Use a Lambda function
Save it as a template (.xltx) workbook for easy access when creating a new workbook.
 
Upvote 0
Solution
You are probably way past this stage but:

Did you try:
VBA Code:
    With Application
        FitPower = Exp(.Index(.LinEst(.Ln(pYAxis), .Ln(pXAxis)), 1, 2))
    End With

Doh! Of course. Thanks for jogging my addled brain.

VBA Code:
Function FitPower(pXAxis, pYAxis, pParameter As String)

Select Case UCase(pParameter)
  Case "COEF"
    With Application
'               =EXP(INDEX(LINEST(LN(TblMrX[Conf]),LN(TblMrX['#Reviews]),,),1,2))
      FitPower = Exp(.index(.LinEst(.Ln(pYAxis), .Ln(pXAxis)), 1, 2))
    End With
  Case "EXP"
    With Application
'                =INDEX(LINEST(LN(TblMrX[Conf]),LN(TblMrX['#Reviews]),,),1)
      FitPower = .index(.LinEst(.Ln(pYAxis), .Ln(pXAxis)), 1)
    End With
  Case Else
      
End Select

End Function

So much better! Thank you.


For you consideration:
1) Wyn Hopkins from Access Analystics is a big fan of using Autocorrect to insert formulas he uses regularly.
This is then independent of the workbook, and available to you in all workbooks.
So you go into autocorrect and set up 2 or 3 characters that you want to use for the formula, put the formula in the replace with box.
Instead of the 2 ranges you would put a word or phrase no spaces as place holders.
To use it use your enter the identifying characters it inserts the formula and you double click on each range place holder and select the range.
Includes a 5 min video > Ref: Master INDEX MATCH in 60 Seconds

2) Use a Lambda function
Save it as a template (.xltx) workbook for easy access when creating a new workbook.

Hmmm... I'll look into that, but I fear I would forget what is what. I am more comfortable with VBA. Thanks.
 
Upvote 0
No problem. I am more comfortable with VBA than Lambda as well but the autocorrect is an interesting concept.
 
Upvote 0

Forum statistics

Threads
1,215,133
Messages
6,123,231
Members
449,091
Latest member
jeremy_bp001

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top