I am trying to evaluate Excel DNA to use it in one of my excel add-in. I use C# functions (.NET 4.0) and want to invoke these functions from Excel. The reason I am interested is, the users of my addin are non-admins and hence would be a breakthrough, if I can find a solution not to do a regasm on my .NET dll, to get my addin working.
I understand that if it is like a worksheet function (with simple return types and arguments), as in: private string Add (int a, double b)
I can easily wrap expose them using excel dna. Also, I understand that, I can also call these simple functions using Application.Run from VBA.
But, if I have a complex type involved in the API and want to use this from VBA then do I require to regasm that assembly and types? example as in this:
private MyType AddLogic (myType1 A, myType2 B)
Or is there any way in Excel DNA, that I can also consume such kinds of functions in VBA without any regasm or regsvr32 ?
Thanks
Mani
You are referring to the built-in COM server support in Excel-DNA. There are a few options, all of them work fine for users without administrator rights.
You can register the COM types at runtime in your AutoOpen - they will then be available late-bound from VBA (so everything in VBA calling those COM types will be 'Variant' and you get no intellisense).
You can register the COM types with regsvr32, using the .xll as your COM server. The Excel-DNA registers its types in the HKEY_LOCAL_USER part of the registry, which the user can always write to.Then the VBA project that uses the COM-exposed types will run even if the .xll add-in is not loaded.
To add type library information for the COM-exposed types, you will have to do the regsvr32 registration, which again works without admin rights, and then you get intellisense etc. in VBA.
In none of these cases do you use RegAsm - which registers managed assemblies for runtime activation - since the native Excel-DNA .xll mediates the COM activation of your .NET types itself.
If you are not interested in providing worksheet functions, ribbons etc. you probably don't need Excel-DNA for this. You can register .NET assemblies for use by non-admin from VBA by just making a .reg script which will right the registry entries in HKEY_LOCAL_USER instead of HKEY_CLASSES_ROOT. I mean to say that the non-admin registration of Excel-DNA is no special magic. The main reason for integration of this feature in Excel-DNA is to ensure that those objects are activated in the same AppDomain as the rest of the Excel-DNA add-in, which is tricky and sometimes important.
Related
Is there a way of storing VBA source code that's common and accessible to all Microsoft Office products..? I have a variety of functions which I use in both Access and Excel, and sometimes even Word. I modify and add to the the functions and modules frequently. The copying, pasting, and maintaining of code between projects can get tedious, and I inevitably overlook something.
I know I could do something like write a class/ocx/addin in VB6 or DotNet, compile it, and reference it in my VBA projects, but I was hoping for something more simple.
If there was a way to store VBA code in independent files, and open them with the VBA IDE in a standalone mode of some sort, that would be outstanding, but I know the IDE doesn't work that way...as far as I know.
I know I could do something like write a class/ocx/addin in VB6 or DotNet, compile it, and reference it in my VBA projects, but I was hoping for something more simple.
Unfortunately that's your best bet.
As you know VBA code is hosted, wrapped-up in a host document: a VBA add-in is still tied to its host document (.xlam, etc.), and as such can't be shared with another host.
In VBA-land what's meant to be shared between VBA projects, is type libraries - things you compile separately from the VBA project, and reference from as many projects as you like.
If you have a VB6 IDE, you can compile a 32-bit DLL that VBA projects can reference. The problem is that it won't work with 64-bit hosts - the solution is a .NET type library, written in the .NET language of your choice, made COM-visible. Note that COM-compatibility does restrict what you can expose in your API: for example you can't expose generics, and method overloads will look weird.
If a type library isn't an avenue you wish to explore, then your choices are rather limited, and IMO sub-optimal.
IMO the only thing that can "work" is a bunch of exported code files in some common folder, and the VBA projects that need to use that code need to literally import these code files. The risk here being, that if you make any changes, other VBA projects using an unmodified version of that code will not "see" these changes, IOW by doing that you're multiplying the number of times you need to fix a bug by the number of projects using that code.
Or you could have some code that uses the VBIDE extensibility type library to ensure the set of imported modules always match exactly with the exported files in that common location.
If you want to use VBA in the same Office program (e.g. one Excel file to another, or one Access file to another), you don't need to use any special kind of file. You can add a reference to an external database or worksheet with macro's enabled.
Navigate Tools - References - Browse - Excel/Access file - Add the file
See the following screenshot:
You can't use files across different Office applications this way, but you shouldn't. Each application has different built-in functions, so your code is likely incompatible anyway.
I have a SAP Business Objects Web 7.5 Add-in in Excel 2007.
The add in itself is made up of a compiled .xll file (CtExcelLinksWeb.xll) and a number of dll's.
A bit of vba shows the xll is registered, and all of its registered functions.
However, when I try to use one of these functions in VBA using Application.Run(), I get
Runtime 1004 - Macro may not be available or may be disabled.
I have tried registering the xll within the same sub (Application.RegisterXLL ()) and upon registering a VBAProject called CtEmpty.csv is created
I want to be able to automate the use of this add-in using VBA as it does long winded repetitive tasks, and then I can work on figuring out how to use the functions
Any help will be appreciated
Are the DLLs on the PATH? It may be that Excel can't load the DLLs that the XLL is dependent upon. Dependency Walker (depends.exe) is a handy tool for troubleshooting this kind of issue.
Also, have you tried using File/Options/Addins to register the XLL, as well as VBA code?
So I want to capture some key-commands in our Docuement-level Excel VSTO addin. I can't seem to find a way to do it, other than to use VBA and have our addin talk to the VBA. Any help/examples would be greatly appreciated.
I am using Excel 2007.
One method involves using the 3rd party solution from Addin-Express. Their product includes the ability to add a keyboard shortcut as a property to the ribbon menu commands.
The other way is to make use of low level keyboard hooks, through some Win32 API's which is generally referred to as windows subclassing. Here is an excellent explanation with code sample of how to do it. Note that the only "extra" thing you need to do to get this code to "work" in VSTO is moving the SetHook() method to the Startup event, and the UnhookWindowsHookEx() method to the Shutdown event.
Check out the article on MSDN here by Stephen Toub.
Finally there is the use of the OnAction property of the Addin class. This method requires the use of some VBA (in terms of a callback method that points back to the underlying .net addin), and works ok so long as you are willing to distribute some VBA in your solution (i.e. a xls or doc w/ vba project, or perhaps a native addin). Note you will also need to mark comvisible = true, and expose the GetAutomationServiceObject method so that your VBA can reference your addin from VBA code.
see here for a thread on it...
You can only do this through API calls to subclass Excel and watch for key commands. This is older, but it still applies.
I'd like to be able to call a function exposed by a VSTO addin from a cell in an excel worksheet. More specifically, if I have a VSTO function Foo() that returns "bar" I'd like to be able to write =Foo() in A1 which evaluates to "bar" on calculation.
Is this possible? What are the key steps I'd need to take?
The prospect of being able to leverage managed code and the VS08 IDE for excel development is very appealing. I thought VSTO would allow me to easily do this but I'm no longer sure. Am I misunderstanding the architecture here? The documentation is a little shoddy.
Excel-DNA (which I develop) is an open-source project that allows you to create user-defined worksheet functions (UDFs) for Excel, as you describe.
With Excel-DNA you can also make full-featured Excel add-ins that include ribbon customization, macros, async function and RTD servers. Excel-DNA uses the native Excel XLL interface to integrate with Excel, so you get very good performance too, compared to solutions based on COM integration.
I don't believe you can do so directly, though you can use a VBA wrapper, see for example http://blogs.msdn.com/pstubbs/archive/2004/12/31/344964.aspx.
You can also use a third party product like ManagedXll to create Excel UDFs in managed code.
I think you can make use of COM Interop.. here is a webpage where I've seen the process described.
http://www.cpearson.com/excel/creatingnetfunctionlib.aspx
We have an existing add-in that we publish to users via click once. We would now like to use this as a vehicle to publish some of our existing C# methods directly into Excel so that the users can call them as a UDF.
For example - I have an assembly called MyAssembly, that has a class called MyClass with a public method called MyMethod. I also have an excel addin which adds some item to the ribbon for some custom functionality. I would now like to publish MyAssembly with my existing addin so that a person who has the addin installed can enter =MyMethod into a cell and have my custom method run.
How would one go about doing this?
I solved this quite comprehensively by using ExcelDna, an open source XLL implementation which is very simple to use, and pretty much avoids the whole COM debacle all together. So far it has matched our requirements perfectly...
http://groups.google.com/group/exceldna
you have not been very verbose about what you want to do. What do you mean with "users can call them"?
If you mean that add-in methods should be exposed to VBA you can find two articles on that here:
http://blogs.msdn.com/andreww/archive/2008/08/13/comaddins-race-condition.aspx
http://blogs.msdn.com/andreww/archive/2008/08/11/why-your-comaddin-object-should-derive-from-standardolemarshalobject.aspx