I'm using Excel 2010, and have defined the following 3 functions in spreadsheet's Module.
Option Explicit
Public Function AAA() As Double
AAA = 3
End Function
Public Function AAA2() As Double
AAA2 = 4
End Function
Public Function AAA3AAA() As Double
AAA3AAA = 5
End Function
When I reference the three functions in my spreadsheet by entering the following into 3 adjacent cells
=AAA()
=AAA2()
=AAA3AAA()
The second function generates a #REF error. The other functions work as expected. Anyone know why this is happening? The reason I'm asking is a few of my macros quit working when I upgraded from Office XP to Office 2010. After quite a bit of experimenting, it appears the function name itself is the culprit? The error did not occur in Excel from Office-XP.
Same thing happened to me. What I notice is that unlike the other two, "AAA2" could be the text of a cell address. I suspect that's the problem.
Related
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.
Edit: The real solution to what I wanted to do can be found on this post here. I just wanted to expose some compiled functions to excel. This proved to be very easy using the Excel DNA nuget package. You just add a class library, add the nuget package, and copy paste the code found in the readme. Click F5 and it launches excel with the add-in already loaded. If you want your functions to be persisted you just need to manually add the add-in to the excel file through the "developer" ribbon section.
Original Post:
I was following the instructions from this microsoft post on how to create an automation add-in. Code compiles fine and I can access the functions from within Excel. However the functions do not work. I almost always get a #value or a #ref error when I try to assign to a cell the result of a function call. To be more specific:
The following function that is provided by Microsoft does not work. It shows me a #value error in the cell where I try to use it. I select using the mouse a random cell range as a parameter for the function.
Public Function NumberOfCells(ByVal range As Object) As Double
Dim r As Excel.Range = TryCast(range, Excel.Range)
Return CDbl(r.get_Cells.get_Count)
End Function
The following function that I created does not work. I get a #ref error. I called it by passing either directly integers ( Add1(1,2) ) or cells that contain numbers.
Public Function Add1(ByVal i1 As Integer, ByVal i2 As Integer) As Integer
return i1+i2
End Function
The following function that I created works(?!?):
Public Function Add1(ByVal i1 As Integer, ByVal i2 As Integer) As Integer
return 222
End Function
I am quite experienced in c# but not at all in vb.net, however for this add-in I need to use vb.net. I suspect that there is something simple that I am missing here but I have no idea what it is. It is also strange that the code provided by Microsoft doesn't work.
Edit: I also copy pasted the function presented here and I get the same #Value error inside excel. I did not follow the tutorial from this post from the beginning but I will during the day.
Edit 2: I figured out that the code from Microsoft doesn't work for some reason whenever you add a number in the function name. If I renamed Add1 on the sample code above to Addqweqew it would work!
MSDN Ref: http://blogs.msdn.com/b/andreww/archive/2008/01/23/managed-automation-add-ins.aspx
It has to do with a locale ID (LCID) issue. This is a known issue when
developing Excel solutions in a mixed culture environment. For more
information, see here: http://support.microsoft.com/kb/246501/.
VSTO solves this problem via its LCID Proxy. Although you can only use
this with VSTO solutions, its worth reading the documentation so you
can understand the problem:
http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.excellocale1033proxy.aspx
and
http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.excellocale1033attribute.aspx.
I got the same problem #Value results, I mucked around a bit and got this working (obviously it could be cleared up - but this code definitely works for me while keeping my PC set to my Australian locale ID. I'm not sure which part of the world you live but I am guessing not the United States as that's the locale where it works by default)
Public Function AddNumbers1(ByVal num1 As Double, _
ByVal num2 As Double) As Double
Dim oldCI As CultureInfo = Thread.CurrentThread.CurrentCulture
Dim english As System.Globalization.CultureInfo = System.Globalization.CultureInfo.GetCultureInfo("en-US")
System.Threading.Thread.CurrentThread.CurrentCulture = english
System.Threading.Thread.CurrentThread.CurrentUICulture = english
Dim valresult As Double = num1 + num2
Thread.CurrentThread.CurrentCulture = oldCI
Return valresult
End Function
Related question: https://social.msdn.microsoft.com/Forums/en-US/dafe71c5-d390-44bc-b4d3-b133444a02fe/excel-automation-addin-udf-returns-error-on-different-regional-settings?forum=vsto
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)
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().
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)