Call methods written in C# in Excel 2007 from cell formulas - c#

I am using Excel 2007. I have C# code written in a separate binary. The code uses static classes and static methods on the classes. I have a reference to the DLL in my VSTO Excel Worksheet project. What do I have to add or modify to get this to work?
My C# code looks like this:
using System;
using System.Collections.Generic;
using Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
namespace FooStatistics
{
[ComVisible(true)]
public static class Statistics
{
public static int Count(Range range)
{
return range.Count;
}
I want to be able to put a formula into an Excel cell that looks like this:
=FooStatistic.Statistic.Count(A1:A10)
Or whatever.
I've seen this but it appears to be for non-static classes in Excel 2003. I can't believe the integration is not better by now.
I've looked at a lot of StackOverflow questions on this. They don't appear to provide native integration (many say, "Use X open source library") and, ominously, many are not accepted by the OP. I am not looking for, "Make it into a COM object and call it from VBA."
So I'm looking for:
Excel 2007
code in C# DLL
call from Excel cell as UDF
native integration
So here's another StackOverflow link, in which two responders say:
As far as I know, you cannot directly create UDFs in VSTO.
VSTO has no support for creating Excel UDFs. Automation Add-Ins can be created in .Net, and seem to be the Microsoft approved way of doing it.
This is a question from June 2009. Is this true -- in 2009 you have to expose your .NET components as COM servers to get callable UDFs for Excel?

If these are your four requirements -- (1) Excel 2007, (2) code in C# DLL, (3) call from Excel cell as UDF, (4) native integration -- then, yes, this can be done, and pretty easily. One of the best tutorials on how to do this is Eric Carter's article Writing user defined functions for Excel in .NET.
If you additionally want your code be hosted via VSTO, then I am virtually certain that you are required to use a VBA wrapper in this case. See Paul Stubbs' article How to create Excel UDFs in VSTO managed code where he uses a VBA add-in to expose VBA UDFs, which in turn call his Managed UDFs written in VSTO.
To be honest though, for Excel UDFs, I would simply avoid the use of VSTO. VSTO is a great designer for managed COM add-ins, allowing you to easily add Ribbon controls and the like. But it is of no help for UDFs (and in fact, does not even support it). So my advice is to create a managed automation add-in, as per Eric Carter's article, and drop the VSTO requirement.
If you do this, you will have no problems, I promise. :-)
Mike

Hugh,
I understand your desire for a 'native' solution, rather than to "Use X open source library". But even VSTO does not seem very 'native' to Excel.
Your requirement is exactly what lead me to develop ExcelDna (http://exceldna.codeplex.com) after finding the Automation add-ins inadequate. The support for Automation Add-Ins has not improved in recent Excel versions, whereas the .xll add-in API (that ExcelDna uses) has seen updated support in recent versions, now supporting multi-threaded recalculation, and with async calls coming in Excel 2010.
Even though ExcelDna is an extra part to introduce into your solution, you'll be pleased at the result. Sadly there has been no clear direction from Microsoft on managed UDF add-ins, or any sign of support for this in VSTO, but in practice doing it with ExcelDna is easy, light-weight and it works very well.
Govert

# hughdbrown: just follow the example in Erics article. If you do that it will work.
No you can't use static class. your instaniating a .net class with a COM wrapper (registering it for com interop).

Related

A general Addin for office solution

Is there a possibility of having a general addin for Microsoft office and the same addin is visible in all Office solutions such as EXCEL, WORD, POWERPOINT etc. We can create individual addins for these applications separately but having a common solution would serve my purpose e.g. if I need to tag some information to all of my documents to be printed.
Any sort of information is highly appreciated.
Thanks.
Is there a possibility of having a general addin for Microsoft office and the same addin is visible in all Office solutions such as EXCEL, WORD, POWERPOINT etc.
Yes
There are two types of Add-In
VSTO Add-Ins (I will use VAI for short in describing them below)
Shared Add-Ins (I will use SAI for short in describing them below)
VAI are application-specific viz, MS Excel, MS Word etc. On the other hand SAI can be written for more than one application i.e can be shared between MS Excel, MS Word etc. Also I am sure that you are aware that VAI has only two main methods. One for startup and the other for shutdown. However SAI has to implement different methods for connection, unconnecting, startup and shutdown.
Another thing that is important to note is that since VAI is application specific there is not too much of code involved as compared to SAI. The reason being SAI work across different applications and hence you need to extra code to distinguish which application is currently calling your Add-in.
I prefer VAI because it lets me use additional programming "shortcuts" and useful objects not available in a Shared Add-in. Not that these are cannot be used in SAI but then you will have to specifically create them. An unnecessary added work if I may say so.
And the last that I can think of is the deployment. They both have a different deployment method.
Hope this clears the concept of a VAI and SAI

Using C#/Java/Visual Basic to populate a Word 2007 template

I've recently been given a task to populate a Word 2007 file with information retrieved from Rhapsody using the Rhapsody API. I'm not super familiar with Rhapsody, but I'll learn. I'm having difficulty tracking down a good way to write a program that can write to a formatted (read: tables) word document. I'm best at java, but I'm capable of using C#, C++, or VB. The problem seems to be that all options for java require the use of 3rd party libraries, and I'm not sure if I'm comfortable using them. All of the languages available in the Microsoft Visual Studio seem to have options for writing out to a Word Document, but I can't seem to figure them out. What would be my simplest option in attempting to tackle this task?
Aspose words does a really good job integrating C# with MS word.
http://www.aspose.com/categories/.net-components/aspose.words-for-.net/default.aspx
I am not sure if you already tried all features of Rhapsody Reporter Plus (in built) and Rational Publishing Engine (additional licenses might be required). With them you can produce html, pdf, word documents...
If this is not your use case and you need your own plug ins in java, we have good experiences with Apache POI, which I could recommend.
I don't understand why you might have issues using 3rd party libraries, when you write everything by yourself you might end doing such a similar library, expending of course "some" time and "some" headaches until having it ready...

Create COM Surrogate server (exe) in C#

I know how to create a COM DLL (a Class Library) in C#. Is it possible to create a COM Surrogate EXE using C#?
This would be a standalone server capable of launching and hosting COM objects, which would then be accessible to COM clients.
The default surrogate process for COM - the thing that hosts COM DLLs, aka the COM Surrogate - is dllhost.exe. It is possible to create a surrogate process in C++. This article explains how.
But those APIs are not exposed in wrappers as part of the base class library in the .NET Framework. If you want to write to write only managed code, you need something else.
I see a couple options.
The Visual Studio SDK, a free download that is intended for devs who want to extend Visual Studio. Within that SDK, there's a class lib that has such wrappers. In particular, look at the ISurrogate class.
BUT, the VS SDK license says that the SDK is ok to use only for products that extend or add value to Visual Studio. I am no lawyer, but that is my understanding of the license, which is pretty clear. These terms means the VS SDK would not be useful for general app building.
The one remaining question is, exactly how do you use the VS SDK technically to produce a COM Surrogate using only C# code? Again, here I don't know. I looked in the docs briefly for guides on using the ISurrogate wrapper, but found none.
Use the code in this article.
The article explores a bunch of different aspects around COM and .NET interop. Towards the end of the article it offers source code for building your own COM server in C#, complete with all the p/invoke calls to CoRegisterClassObject() and friends.
I wanted to make same thing and found excellent project example CSExeCOMServer on All-In-One Code Framework. It actually reconstructs normal COM server logic by means of .NET and native calls to Windows API. But it looks all still overcomplicated. I suppose there is no simple and fast way to expose .NET objects as COM in out-of-process server and it is not the architecture of choice.
One option, if you want an out-of-process COM component, is to host a dll in COM+ via serviced components. This only supports dll though, but you could write a shell exe (for standalone use) that simply defers to the dll.
Not quite as simple as VB, but it works.
I do remember somebody showing me a more direct way (no COM+), but I can't for the life of me remember what it was...

com interop: how to consume c# from Excel or Access

I see plenty on the web about VSTO and automating excel from c#, but very little to get started on wiring up a c# assembly to make it visible from Excel.
Can someone point me to some very basic info explaining how to create a COM interface, GUIDS, ComVisible etc?
Basically all you need to do is
Make your assembly COM visible using the respective attribute in the project property Assembly version information dialog
For every public class, add the following block (see [1]) of code above the class definition
Register DLL using the regasm.exe tool found in the .NET 2 installation folder
Also, make sure to add a descriptive name to both application name and description in the Assembly version information dialog (they are later used to pick the COM classes).
[1] Block of code to add before class definition:
[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("SomeNameHere")]
[ComVisible(true)]
[Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx")]
After that you should be able to use the class like any other normal COM class.
EDIT
It should be noted that I do not have experience with Excel and C# COM classes - I'm using C# together with Microsoft Navision, which works great the way I described above.
There are many books out there that might get you going. "Pro C# 2008" from Wrox has a great chapter on this.
Also, here is a MSDN blog article about COM Visible to Excel.
Rather than go down the COM route, it is considerably easier (and less of an install issue) to use something like ExcelDNA. It allow you to write XLLs in .Net that don't require registering. It is also open-source and very well community supported.

Does anyone have a good example of controlling multiple Excel instances from a .Net app?

We have an Excel 2002/XP based application that interacts with SQL 2000/5 to process fairly complex actuarial calculations. The application performs its function well, but it's difficult to manage.
We're trying to create a "controller" application or service that can manage and monitor these various instances of Excel (start/stop/process commands etc) but it's a bit of an InterOp nightmare unfortunately.
Does anyone have a good (i.e. working) example of doing something like this in VB.Net or C#?
Don't do it!
We tried for weeks to get something like that to work and it simply does not behave as advertised. Don't even start - give up immediately!
The only options that you really have is a heavy server-side MOSS based implementation - Excel (Web) services (they call it something like that). Windows based COM Excel interop is pretty much dead and will be replaced by MOSS.
The other option is to use SpreadsheetGear. It is actually a fantastic product
It is lightlingly fast
The engine is separate from the UI so you can use it to do Excel stuff server side (with no office installed)
Fairly cheap
Has an API similar to the existing Excel COM api so moving code across is relatively easy
It all depends on the formulas that you need in your spreadsheet. Have a look at the formula list for Spreadsheet Gear and if there is a match go for it.
Interop works fine except that you always end up with references to Excel objects that aren't released, so Excel instances won't close. The following KB article explains why:
http://support.microsoft.com/default.aspx/kb/317109/EN-US/
You can avoid the problem if you have very carefully written code for a limited set of Interop scenarios. But in the general case it's very difficult to get it working reliably.
You might want to take a look at this product: http://www.spreadsheetgear.com/products/spreadsheetgear.net.aspx
It's all managed code and direct .NET libraries. No InterOp headaches. I haven't used it myself, but I've heard very good things from people in the finance world.
We have written a service that controls a single instance of Excel 2003. We never managed to get Excel instances to close cleanly, so we start one instance when the service is first accessed and use only that, serializing client requests.

Categories

Resources