Excel-DNA: Unregister methods in a running instance of Excel - c#

Is it possible to unregister methods that I previously registered via ExcelIntegration.RegisterMethods without restarting Excel?
Basically, I'm looking for the opposite of ExcelIntegration.RegisterMethods.

Excel-DNA does not currently let you unregister methods in a loaded add-in. This is just a limitation of the implementation, and how exported functions are hooked up to the native exports of the .xll. You an however unload an entire Excel-DNA add-in, (from another add-in) as long as it only exports UDFs and not ribbons, an RTD server or other COM features.
Another workaround is to re-register the function as "hidden". The new registration will take up another slot in the (fixed-size) .xll export table, but will at least not appear in the worksheet function completion list anymore.

Related

Call xll functions in c# app

Is there any way I can import an xll into my C# WPF project? I require some of the functions that are usually called via the xll addin in Excel. I have read that xll performs like normal dlls, but sharpdevelop does not seem to be able to read any of its functions and methods. I know the formulas that are usually called in excel, can I access those same functions in my WPF app?
If, and only if :
you know the prototype of the function.
arguments are only primitives C type , (no xloper type).
the function is independent of Excel (does not require to be initialized by excel)
then yes you can call it from C# thanks to DllImport

How to call a C# method for OnUndo in an Excel VSTO add-in?

I'm currently writing a VSTO add-in for Excel in C#, and am having trouble getting the undo functionality to work correctly.
As far as I can tell from the documentation, you are meant to use Application.OnUndo to register an undo callback. However, it's not clear to me whether it's possible for the Procedure argument to refer to a C# method.
Ideally I would like to set the undo callback to an instance method, eg:
this.Application = Globals.ThisAddIn.Application;
// ...
this.Application.OnUndo("Undo color change", "this.UndoTextColorChange");
Unfortunately, while this registers an undo, actually clicking 'undo' in Excel gives the error:
Cannot run the macro 'this.UndoTextColorChange'. The macro may not be available in this workbook or all macros may be disabled.
To me, this almost suggests that the Procedure argument has to be a VB macro (rather than a C# method). However, it's also possible that I haven't been able to work out the fully-qualified procedure name to use in the .OnUndo call.
Is it possible to have Application.OnUndo call a C# method? If so, what should I use as the argument for Procedure? If not, how is undo functionality typically implemented in C# VSTO add-ins?
You are right that the Procedure argument of the Application.OnUndo has to be a VBA macro.
If you want the Application.OnUndo to call a C# method you will have to add a VBA macro to your workbook which will be triggered by the Application.OnUndo. Then the macro may call C# code from your VSTO add-in. Here is a good article describing how you can call VSTO code from VBA macro.
In order to inject a VBA macro into a workbook from your VSTO add-in you may create an .xlam Excel Add-in and distribute it together with the VSTO Add-in (basically put it into the same folder or even embed it into VSTO Add-in itself as a resource file).
The .xlam Excel Add-in will be very simple and will contain a single function like below:
Sub UndoLastAction()
Application.COMAddIns("YourVSTOLibraryName").UndoInVSTO
End Sub
When VSTO Add-in is started it can load .xlam add-in, so all the workbooks will have access to that VBA macro even if the workbook itself is not macro-enabled.
Below is a sample how you can load .xlam Excel Add-in from VSTO:
var undoManager = Globals.ThisAddIn.Application.AddIns.Add("UndoManager.xlam", true);
undoManager.Installed = true;
Now, when you execute a certain modification via your VSTO Add-in and then would like to be able to Undo it you will have to call Application.OnUndo:
Globals.ThisAddIn.Application.OnUndo("Undo Last Operation", "UndoManager.xlam!UndoLastAction");
When Application.OnUndo is executed the Excel will allow user to click "Undo" button which will trigger UndoLastAction macro declared in the .xlam Add-in which will trigger UndoInVSTO function declared in YourVSTOLibraryName dll where you can do whatever you need to undo your last operation.

external application to invoke an event in a Excel VSTO add-in

A Refresh button/method in an Excel Add-In needs to be invoked via an external winform application. Here is where I am up to:
private Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
public FormMain()
{
InitializeComponent();
RefreshExcelSheet(#C:\a.xls");
}
private bool RefreshExcelSheet(string path)
{
using (var wb = excel.Workbooks.Open(path).WithComCleanup())
How do I click the Refresh button or simply invoke its event?
I was looking at these articles but they are using VBA, I want a Winform app to open the spreadsheets and click the button:
Accessing a VSTO application-addin types from VBA (Excel)
Expose VSTO functionality to VBA w/o local admin
The simplest way to solve this problem is to just expose the existing custom .net method as a COM method by making is a com callable wrapper object (CCW).
VSTO provides you with a simple method to expose the COM Automation server.
http://blogs.msdn.com/b/andreww/archive/2007/01/15/vsto-add-ins-comaddins-and-requestcomaddinautomationservice.aspx
EDIT BY OP:
Andrew Whitechapel has updated the article, but I cannot get it to work. Even with StandardOleMarshalObject and Register for COM interop I still get the same error message as detailed in this article: http://blogs.msdn.com/b/andreww/archive/2008/08/11/why-your-comaddin-object-should-derive-from-standardolemarshalobject.asp
Anonymous Type's suggestion is surely the best approach if you can extend the Excel add-in.
If it's a 3rd party tool it's still possible to use the ribbon's IAccessible interface to invoke the ribbon button. However, you can expect this to be much more complicated. In case you have to follow that path here are some links to get you started:
How to get Ribbon custom Tabs IDs?
http://www.codeproject.com/Articles/38906/UI-Automation-Using-Microsoft-Active-Accessibility

Calling function in XLL file from C#

I have a xll file which have a function and I want to call that function from C#.
This xll file is used in excel.any body have idea how to do that?.I tried refrencing the xll file but I am not getting the value.If I open excel like start-->programms-->excel and
in excel if i directly give the function I am getting right value.Same thing If i automate excel in c# and opened excel from Microsoft.Office.Interop.Excel and applied the function I am getting error
You probably won't be able to invoke the function directly because an XLL will expect the Excel interfaces to be driving. You'd have to do some serious faking.
Automating it through Excel will work though.
An xll is just a dll. If you know the signature of the function you want to call, you can call it just like any other function. If you don't know the signature but can load the add-in in Excel, there is a way to get Excel to tell you the signature.
Automation only works if you are running Excel. There is no need for that once you know the signature.
There is a few tools you can use:
XLL Plus
XLL Host
The question has also been asked on MSDN Use XLL from C#, this is the answer:
If it is a COM project, you can add it via the COM tab in the Add reference window.
If you need to create a .NET assembly from the dll, you can try to use Type Library Import tool to create a wrapper around the dll:
tlbimp.exe xll.dll /out:xllnet.dll
If the object does not support COM, but only native calls, you will need to platform invoke the methods using the DllImport attribute. See the Platform Invoke tutorial for more information.
I gave all 3 suggestions a go but didn't have any luck. Given the author of the XLL tool Excel-DNA recommends using a tool I suspect consuming a XLL in a Winform/WPF/Console or Web app is not trivial:
https://stackoverflow.com/a/2865023/495455

Create UDF using VSTO and no VBA

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
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
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
Wire up your class to VBA in VSTO
Private Sub ThisWorkbook_Open() Handles Me.Open
Me.Application.Run("RegisterCallback", New MyManagedFunctions)
End Sub
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.
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?
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.
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;
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:
<Link>
<Link>

Categories

Resources