Name error when trying to call a function - vba

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 !

Related

How can I run several macros where the Macro name begins with a specific string of characters?

I've created several custom functions which I would like to Register. Currently, I have a different procedure for which I specify the registration for each function (there's no issue with that piece). However, the only way I know of to registering all these functions is by calling each Macro by name in another procedure like this:
Sub spRegisterFunctions()
Call spRegisterCUSTOMAfunction
Call spRegisterCUSTOMBfunction
Call spRegisterCUSTOMCfunction
Call spRegisterCUSTOMDfunction
End Sub
I'm actually looking for something more dynamic so that every time I create a new function, and it's corresponding "spRegister..." procedure, I don't have to remember to add the "Call" code to the "Sub spRegisterFunction()" procedure for that specific function.
Here's an example of what attempting to do:
Sub spRegisterFunctions()
Dim mc as Macro
For Each mc in VBProject("NameOfProject").Module("NameOfModule")
If Left(mc.Name,10)="spRegister" then
Call mc
End If
Next mc
End Sub
As you can see, I'm attempting to run any macro in a specific module who's name begins with "spRegister". Obviously the code above will not work, partly because some of those objects don't even exist.
Is there any way to do this?

VBA UDF fails to call Range.Precedents property

I am trying to write a simple UDF, which is supposed to loop through each of the cells of a given_row, and pick up those cells which do not have any precedent ranges, and add up the values.
Here is the code:
Public Function TotalActualDeductions(given_row As Integer) As Integer
Total_Actual_Deduction = 0
For present_column = 4 To 153
Set precedent_range = Nothing
If Cells(2, present_column) = "TDS (Replace computed figure when actually deducted)" Then
On Error Resume Next
Set precedent_range = Cells(given_row, present_column).Precedents
If precedent_range Is Nothing Then
Total_Actual_Deduction = Total_Actual_Deduction + Cells(given_row, present_column)
End If
End If
Next
TotalActualDeductions = Total_Actual_Deduction
End Function
If I try to run it by modifying the top declaration, from:
Public Function TotalActualDeductions(given_row As Integer) As Integer
to:
Public Function TotalActualDeductions()
given_row = 4
then it runs successfully, and as expected. It picks up exactly those cells which match the criteria, and all is good.
However, when I try to run this as a proper UDF from the worksheet, it does not work. Apparently, excel treats those cells which have no precedents, as though they have precedents, when I call the function from the worksheet.
I don't know why this happens, or if the range.precedents property is supposed to behave like this.
How can this be fixed?
After a lot of searching, I encountered this:
When called from an Excel VBA UDF, Range.Precedents returns the range and not its precedents. Is there a workaround?
Apparently, "any call to .Precedents in a call stack that includes a UDF gets handled differntly".
So, what I did was use Range.Formula Like "=[a-zA-Z]" , because it satisfied my simple purpose. It is in no way an ideal alternative to the range.precedents property.
Foe a more detailed explanation, please visit that link.

VBA Compile error

I have very little experience with VBA and the last time I used it was years ago.
Heres my VBA:
Function MacIDGen(total, current)
If total - current = 0 Then
current -1
Else
current 1
End If
Macro1 (current)
End Function
Sub Macro1(cur)
Sheets("Donations").Cells(I2).Value = cur & "Test"
End Sub
It's its own module, no other code in with it at all.
So I have a cell which is calling MacIDGen(). It's passing MacID two other cell values. The error comes whenever it's executed, "Compile Error: Expected Sub, Function, or Property" and highlights the functions method signature.
I have no idea why its kicking this up here, I'm guessing its because I've either missed a major step or something about how you can't have a function in that context or some other such issue.
EDIT
As a little extra info, I'm creating these spreadsheets in Excel to serve as random data generation sheets to be imported into a drupal site. I've encountered a problem that cannot be resolved without the use of loops (I also can't hard code the number of iterations either), which formulas don't do.
Regarding the Compile Error, you are getting that because you forgot to use the = sign in current -1 and current 1
Like I mentioned, there are many errors but the main error is that you cannot use a UDF to write to another cell. It really doesn't matter if you break that function into functions or subs. You simply can't write to any other cell. You will get a #Value in the cell where you are using that function.
A Function is used when you want to return something. Now since you are using this as a UDF (user defined function), it should return something and to that particular cell.
If you are writing to the same cell where the function is called from then change your code to
Function MacIDGen(total, current)
If total - current = 0 Then
current = -1
Else
current = 1
End If
MacIDGen = current & "Test"
End Function
If you want to change a cell you can use a sub procedure instead of a UDF, in that case you will need a way to execute it from your spreadsheet such as a commandButton, a ribbon button or a key combination shortcut.
If so, your first line should be:
Sub MacIDGen(total, current)

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)