views:

1683

answers:

5

Similar to this question (but in my case not VSTO SE), however, I just want to confirm that it is not possible to create a UDF using pure VSTO in Visual Studio 2005 and Excel 2003 - so, to absolutely clear, my question is:

Is it possible to create a Excel 2003 UDF using Visual Studio 2005 and a VSTO solution without using any VBA or other tricks?

I'm aware of ManagedXLL, ExcelDNA, Excel4Net etc but don't want to consider those for the moment.

Thanks

A: 

I am not familiar with a method of creating a UDF in Excel 2003 using VS2005 and VSTO without having at least a bit of VBA. Here are 2 links that discuss this a bit further:

http://geekswithblogs.net/Denis/archive/2007/01/03/102623.aspx

http://blogs.msdn.com/pstubbs/archive/2004/12/31/344964.aspx

Jon Tackabury
Thanks, but as per the question is there a way to do this without any VBA? It seems like it can be done with VSTO SE, but can it be done with just *pure VSTO* ?
ng5000
Sorry, I don't know of any pure VSTO way, just the VBA/VSTO combination.
Jon Tackabury
+1  A: 

In this article Eric Carter goes on to explain how to do what you're asking. At the top he even links to an update of the aforementioned blog post.

Thedric Walker
Thanks, but that linked solution does not use VSTO, it just exposes a .Net assembly's types to COM.
ng5000
You are still talking about two functionally different concepts and have not modified your question to state why it is so important to house the UDF in the same project as the VSTO project.
Anonymous Type
+4  A: 

Concerning whether there is a way around COM or VBA I don't think that it is possible (at least not without any very dirty tricks). The reason is that the only way Office can execute external code (i.e. you add-in) is via COM. Even VSTO is still using the old IDTExtensibility2 COM interface underneath. IDTExtensibility2 is a COM interface that all add-ins for Microsoft Office applications must implement.

Before VSTO, Office add-ins had to implement this IDTExtensibility2 interface themselves. In such a COM based add-in (or COM-visible managed add-in) you can simply add your UDF as described here.

However, now with VSTO, there is an additional layer of abstraction: VSTO uses a so-called Solution Loader implementing IDTExtensibility2, which is a dll provided by the VSTO runtime. This means that your add-in is no longer COM-visible. Hence, if you added a UDF to your VSTO add-in it won't be visible to Office.

Paul Stubbs explains on his blog how to do with VSTO and VBA: How to create Excel UDFs in VSTO managed code

  1. Create a class with your functions in VSTO

    <System.Runtime.InteropServices.ComVisible(True)>
    Public Class MyManagedFunctions
        Public Function GetNumber() As Integer
            Return 42
        End Function 
    End Class
    
  2. Wire up your class to VBA in VSTO

    Private Sub ThisWorkbook_Open() Handles Me.Open
        Me.Application.Run("RegisterCallback", New MyManagedFunctions)
    End Sub
    
  3. Create Hook for managed code and a wrapper for the functions in VBA

    In a VBA module in your spreadsheet or document

    Dim managedObject As Object
    
    
    Public Sub RegisterCallback(callback As Object)
        Set managedObject = callback
    End Sub
    
    
    Public Function GetNumberFromVSTO() As Integer
        GetNumberFromVSTO = managedObject.GetNumber()
    End Function
    

Now you can enter =GetNumberFromVSTO() in a cell, when excel starts the cell value should be 42.

0xA3
Hi - thanks. Yes I know that by using some VBA and COM decorating my class I can do this, but that doesn't answer the question given the question's caveats.
ng5000
I edited my answer to explain why I think there is no way around COM or VBA.
0xA3
+2  A: 

I don't understand why you want to do this?

VSTO and exposing UDFs via COM interop (from .NET) are two different tasks. Why do you want to host a UDF method inside of a VSTO project?

The way you register the .net UDF assembly means it will have to be in a seperate project to the VSTO project. However if you wanted to share data between the two apps then you have a variety of native .net methods for this, or simply "call" the UDF function from the appropriate range object within your VSTO project.

Is there a reason that you feel it is necessary to have UDF in VSTO?

Anonymous Type
+1  A: 

Create the UDF as Eric Carter explained and pass as parameter to your UDF an Excel range. You're able to access Excel's object model through VSTO by using the given range: Excel.Range rg = param1 as Excel.Range; Excel.Workbook wb = rg1.Worksheet.Application.ActiveWorkbook;

T.Molnar