5

I need to finish an application in C#.

Now I want to get a function that control a Excel file to get data.

I used getActiveObject("Excel.Application"), but this returns nothing. I can't use Excel.Application in VS2008, and Microsoft.Office.Interop.Excel.Application is used instead.

So is there another way to do this?

Microsoft.Office.Interop.Excel.Application e =
    (Microsoft.Office.Interop.Excel.Application)Marshal.GetActiveObject(
        "Excel.Application");
Steven
  • 166,672
  • 24
  • 332
  • 435

4 Answers4

3

After about a half a day of playing around I finally figured out how to make this work so you can latch onto an open copy of excel. My users have been complaining mightily about having too many instances of Excel open.

Here is a snippet of what I did to get it working:

_Application excelApp;

try
{
  excelApp = (_Application)Marshal.GetActiveObject("Excel.Application");
}
catch(Exception)
{
  // this is important. If Excel is not running, GetActiveObject will throw
  // an exception
  excelApp = null;
}

if( excelApp == null )
{
  excelApp = new ApplicationClass();
}

I have been chasing this for a while and finally had some time to hunker down and figure it out.

sth
  • 222,467
  • 53
  • 283
  • 367
Jager
  • 31
  • 2
  • I am trying to do the same thing with an ActiveQt object and a C++/CLI wrapper Form. I think the C# code will be very close to what I need for it. Thanks. – jetimms Apr 11 '11 at 20:00
2

I also have been working on Excel Addins, in namespaces use

using Excel=Microsoft.Interop.Office.Excel;

instead of Microsoft.Interop.Office.Excel use the above line, for more understanding look at my code:

using System.IO;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
using Excel = Microsoft.Office.Interop.Excel;
using Microsoft.Office.Interop.Excel;
using static MMCAPP2010.Profile;
using System.Runtime.InteropServices;

namespace MMCAPP2010
{
    public class ExcelTemplateLoad
    {
        public void DeserializeObject(string filename)
        {
            Excel.Application instance;
            Workbook wb = null;
            try
            {
                //getting the current running instance of an excel application
                instance = (Excel.Application)Marshal.GetActiveObject("Excel.Application");   
            }
            catch
            {
                instance = new Excel.Application();
            }

            //opening the template
            wb = instance.Workbooks.Open(@"C:\Users\U1152927\Downloads\sample.xltx");
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • thank you brian for editing my answer to be more understandable, i was trying to do that but i couldn't figure out how to do that – Hemanth Mannam Aug 08 '18 at 09:34
1

In order to be able to refer to the Excel object model as "Excel", then you can create an alias via a using statement at the top of your namespace (or document) as follows:

using Excel = Microsoft.Office.Interop.Excel;

Thereafter, you can refer to Excel.Application instead of the long-winded Microsoft.Office.Interop.Excel.Application.

As for why your call to Marshal.GetActiveObject is failing, I can't say for sure. A couple of thoughts:

(1) Are you certain that there is a running instance of Excel already present? If not, then create a new Excel application:

Excel.Application xlApp = new Excel.Application();

(2) If there definitely is an Excel application already running, then it is possible that the Excel instance has not yet been added to the Running Objects Table (ROT) if the Excel Application has never lost focus. See: Visual C# .NET Error Attaching to Running Instance of Office Application for more on this. I believe that the Marshal.GetActiveObject method should throw an exception in this case -- not quietly return null -- but this still seems potentially relevant.

I hope this helps...

Mike

Mike Rosenblum
  • 12,027
  • 6
  • 48
  • 64
1

Please see the MS KB as given in the link below...

http://support.microsoft.com/kb/238610

Eshwar
  • 37
  • 1
  • 6