Yes and no. In this case, it's not too difficult; however, it also won't have the helpful tooltips and descriptions that regular Excel functions have.
You should also be aware that UDF's are only available to the workbooks which contain their code. Exceptions would be the PERSONAL
file (auto-created during the first macro-recording, and always opened in the background) and add-ins. If you are the only person using this formula, either option would probably work, and would only need the code in one location. If you intend to use this formula in workbooks for other people, the simplest solution would probably be to put the custom UDF into each workbook which would use it. However, you could also add the UDF to a new workbook, save it as an add-in, and distribute it to everyone also using the workbooks. Either solution would, of course, have potential macro-security-permission issues, as the default in Excel tends to be either "run-with-permission" or "never-run".
In general, with VBA you can often add Application.
in front of worksheet function names to allow VBA to use them as you would normally. If you open up the code editor, you can add a Module (not a class module or a userform, just a plain regular module) and type Function FunctionName
. The VBA will automatically add the required End Function
. You would just need to add the required code in between those two lines.
A Few Notes
If you chose to rename the module you put the code in, do not match the module name with the function name. It confuses Excel.
When creating custom functions in VBA, newer programmers sometimes forget how to make a function return a value. You do that by assigning the value to be returned, to the function before the function's end (you'll be able to see how this is done in the attached code).
For your particular equation, both the MATCH and the INDEX functions work as expected when changed to Application.Match
and Application.Index
. Unfortunately, the OFFSET function does not. In your scenario, you are using the OFFSET function for it's resizing ability. Since the parameters you want to pass are all Ranges, you can use a range's .Resize
property to do the equivalent of the original OFFSET.
I took the liberty of renaming the variables in your equations to more descriptive (English) terms; feel free to rename them if desired (you will have to do a Find/Replace as the VBA editor doesn't automatically change references to a variable if the variable's name changes). When using the UDF, if you use Ctrl+Shift+A
after entering the UDF's name in the formula bar, the parameter names will get filled in (shortcut courtesy of JustinJDavies) If you would rather try to get tooltips for your UDF, this may help
Code
This may not be the best or most efficient way of writing this particular UDF; however, it should be functional (please note: you may need to change ,
for ;
, I'm not sure if the language specific aspects of Excel functions carry through to the VBA code editor). If you do want to try to find a better way to code this, or any other piece of functional code, you should try checking out the Code Review forum.
Function MYUDF(SearchArea As Range, RowMatch As Range, ColumnMatch As Range)
MYUDF = Application.Index(SearchArea, Application.Match(RowMatch, SearchArea.Resize(, 1), 0), Application.Match(ColumnMatch, SearchArea.Resize(1), 0))
End Function