Custom Eval function in excel - vba

I`m using =Eval() function to convert formula written as text (mostly created by CONCATENATE funtion, for example i have cell =A2+B2 as text) to be an excel function. The =Eval() is custom function that can be found on many excel blogs and training sites. VBA code I use is:
Function Eval(Ref As String)
Application.Volatile
Eval = Evaluate(Ref)
enter code here
End Function
The problem i`m having is that this only works for formulas that doesn't contains other formulas in it. For example after i created cell with text (by using CONCATENATE): =2^(0.5) it works correctly, =Eval() gives me correct answer (1,414), but when i it for =sqrt(2) it gives me error.

Related

Name error when trying to call a function

I'm still learning VBA so I might be doing a lot of very basic mistakes. At the moment I'm trying to make a macro which could count the rows of a table. This sub works perfectly (with a table named "Tab").
Sub AddRowTable()
ActiveSheet.ListObjects("Tab").ListRows.Add (2)
End Sub
However, when I try to convert this sub to a function so I can call it with the name of the table as variable, I get a name error when writing "=AddRowTableFunction(Tab)" in a cell.
Function AddRowTableFunction(TableName)
ActiveSheet.ListObjects(TableName).ListRows.Add (3)
End Function
I understand that it is just a problem of type, but I just cant find how to do it properly.
Thanks.
At the moment I'm trying to make a macro which could count the rows of a table.
First off, that is not what your code is doing. Your code is adding a row to the table. The number of rows would be accessed using ListRows.Count.
when I try to convert this sub to a function so I can call it with the name of the table as variable...
You don't need a Function in order to include a variable. The differance between a Sub and a Function is that a Function returns a variable, while a Sub does not (i.e. a Function gives back a variable to the code that used it). Both Subs and Functions can take variables.
A Function that returns the number of rows in a given table would be something like this:
Function AddRowTableFunction(TableName As String)
AddRowTableFunction = ActiveSheet.ListObjects(TableName).ListRows.Count
End Function
For adding a row, you would probably use a Sub, because the action of adding a row doesn't return any information:
Sub AddRowTable(TableName As String)
ActiveSheet.ListObjects(TableName).ListRows.Add
End Sub
Finally, when using the Function in a formula, as Apafey pointed out, you need to write "Tab" (in quotes), not just Tab. "Tab" tells Excel to pass the text of the word Tab, while Tab tells Excel to look for a range named Tab, which probably doesn't exist.
You should try:
=AddRowTableFunction("Tab")
You wrote:
=AddRowTableFunction(Tab)
that is not fine.
As FaneDuru said, an UDF function can't change other cells, which explains the error). Thnaks !

Prevent Excel from making links to external macro functions in formulas absolutely

There are two workbooks: The view foo.xlsm and the control bar.xlsm which gets loaded from the foo.xlsm with the Workbooks.Open()-Method and includes the VBA-Code necessary for the view. It does so because there are multiple possible paths to the bar.xlsm which have to be checked prior.
Set wC = Workbooks.Open("path\bar.xlsm", ReadOnly:=True, Editable:=False, AddToMru:=False)
In foo.xlsm there is a formula referencing to a macro function from bar.xlsm:
=bar.xlsm!functionName(parameter)
The problem is that on every startup excel modifies that link to the last path from which the bar.xlsm got loaded successfully, e.x.:
='C:/Users/X/Desktop/bar.xlsm'!functionName(parameter)
This behaviour is unwanted because the path of bar.xlsm can and will change. How to prevent excel from making this link absolutely?
In the meantime I have found an uncomplicated workaround. I call the desired method using a wrapper function in the view workbook:
Public Function functionWrapper() As Integer
functionWrapper = Application.Run("bar.xlsm!functionName(parameter)")
End Function
The wrapper function is called inside the desired cell formula as follows:
=functionWrapper(parameter)

Calling Excel's worksheet function from vba code

With worksheetfunction's methods I can call from vba code a lot of excel's function without reinvent the wheel.
Unfortunately not all function are available there but other simple function can be find under vba library.
Now I need to use two functions:
address()
indirect()
But none of two is available as method of vba or worksheetfunction
(here what is available: https://msdn.microsoft.com/en-us/library/office/ff822194(v=office.14).aspx)
Using the object browser on the editor I can't find those functions...
how can I do?
INDIRECT is a way of resolving a string, this can be done in VBA easily. ADDRESS can also be found as a member of a Range object. That's why they are not available.
Here is a tiny example:A1 contains the text B1B1 contains the text GoldC1 contains the formula:=INDIRECT(A1):
Running this macro:
Sub UsingEvaluate()
MsgBox Evaluate("INDIRECT(A1)")
End Sub
will produce:

When I try to use a VBA function that I've defined in an Excel spreadsheet, I get "That is not a valid function"

I defined a function in VBA as follows
Public Function Distance(X, Y) as Double
Then in a cell I try to use the function. I type "#Dis" and get the drop down menu, select the function and then enter the parameters ending up with #Distance(A1, A2) in the cell.
When I press Enter I get the Error "That function is not valid".
I enabled macros throughout the system, tried saving it as the old format and as the macro enabled workbook format to no avail.
What's wrong with my usage of this function?
Try using:
=Distance(A1, A2)
Instead of
#Distance(A1, A2)
I've never seen # as the correct character to call a function in Excel.
I tried the following in Excel, and it works like a charm:
In Module1:
Public Function Distance(X as Double, Y as Double) as Double
Distance = 10
End Function
In a cell:
=Distance(A1, A2)
Which produces the result:
10
as expected.
You'll also need to make sure that the VBA code for your function is in a Module and not in the code area of the Worksheet.
Do not use reserved words as the names of your functions. I tried one name Parse() and it kicked it back until I renamed it ParseString().

How can I return the results of a function to a cell in Excel?

Suppose I have a function attached to one of my Excel sheets:
Public Function foo(bar As Integer) as integer
foo = 42
End Function
How can I get the results of foo returned to a cell on my sheet? I've tried "=foo(10)", but all it gives me is "#NAME?"
I've also tried =[filename]!foo(10) and [sheetname]!foo(10) with no change.
Try following the directions here to make sure you're doing everything correctly, specifically about where to put it. ( Insert->Module )
I can confirm that opening up the VBA editor, using Insert->Module, and the following code:
Function TimesTwo(Value As Integer)
TimesTwo = Value * 2
End Function
and on a sheet putting "=TimesTwo(100)" into a cell gives me 200.
Put the function in a new, separate module (Insert->Module), then use =foo(10) within a cell formula to invoke it.
Where did you put the "foo" function? I don't know why, but whenever I've seen this, the solution is to record a dimple macro, and let Excel create a new module for that macro's code. Then, put your "foo" function in that module. Your code works when I follow this procedure, but if I put it in the code module attached to "ThisWorkbook," I get the #NAME result you report.
include the file name like this
=PERSONAL.XLS!foo(10)