使用c#从活动Excel工作簿更新活动工作表的方法?

时间:2009-12-24 05:24:24

标签: c# excel vb6

我想更新当前文档中当前工作表中的值,而不管excel的文件名是什么。

在vb6.0中,我们可以做到

Set AppExcel = GetObject(, "Excel.Application")
Set SheetExcel = AppExcel.ActiveWorkbook.ActiveSheet

我怎么一直试图在C#中做同样的事情。

有没有办法在C#中做同样的事情。

3 个答案:

答案 0 :(得分:4)

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Reflection;

public class MyClass
{
    public static void Main()
    {
        object xlApp  = Marshal.GetActiveObject("Excel.Application");
        Type t = xlApp.GetType();

        t.InvokeMember("Quit", BindingFlags.InvokeMethod, null, xlApp, null);

    }
}

我已根据给定here的示例修改了代码。

话虽如此,我认为您可以在vb.net中编写代码(并使用GetObject)并使用c#中的库。

OR

您可以参考Microsoft.VisualBasic.dll 并致电GetObject

编辑:为什么你需要这样的东西?不会创建Excel Addin帮助?

如果你必须在c#中编写代码,请注意使用Marshal.ReleaseComObject

释放你创建的COM实例

EDIT2:为了获得对ActiveSheet的引用,你可以写

object sheet = t.InvokeMember("ActiveSheet", BindingFlags.GetProperty, null, xlApp, null);

同样,我建议你采取这条路线 用VB6编写代码来做你需要的事情&从c#/ vb.net中调用它。

答案 1 :(得分:4)

简而言之,答案绝对是肯定的。

但是您知道,使用“GetObject”获取用户现有Excel应用程序的方法可能容易出错。如果只有一个Excel应用程序在运行,那么'GetObject'将正常工作。但是,如果当前打开的Excel应用程序不止一个,则无法控制从“GetObject”函数返回的Excel应用程序 - 返回的Excel实例可能不是您想要的那个。

您可能需要考虑创建一个托管的COM加载项,该加载项在 Excel应用程序本身内运行,因此,对于它控制的“哪个”Excel应用程序实例始终没有任何问题。为此,您可以先查看文章How to build an Office COM add-in by using Visual C# .NET

如果您知道要控制的Excel应用程序实例的进程ID或主窗口句柄(a.k.a.“Hwnd”),那么可以 访问此精确实例。要了解如何执行此操作,您可以阅读Andrew Whitechapel对主题here的讨论。您感兴趣的部分从“获取Excel应用程序对象,这是我们要做的”这一行开始。讨论有点复杂,但是如果你按照他的代码来完成它的工作就完全如上所述。

如果您想继续使用'GetObject'方法,那么下面的代码示例使用早期绑定来获取当前运行的Excel应用程序的活动工作表。它假定您在代码模块的顶部有“使用”语句using Excel = Microsoft.Office.Interop.Excel以及using System.Runtime.InteropServices

// Note:
// using System.Runtime.InteropServices;
// using Excel = Microsoft.Office.Interop.Excel;

Excel.Application excelApp = 
    Marshal.GetActiveObject("Excel.Application");

object activeSheet = excelApp.ActiveSheet;

如果您使用后期绑定,那么它可能如下所示:

// Note:
// using System.Runtime.InteropServices;

object excelApp = 
    Marshal.GetActiveObject("Excel.Application");

object activeSheet = 
    excelApp
        .GetType()
        .InvokeMember(
            "ActiveSheet", 
            BindingFlags.GetProperty, 
            null, 
            excelApp, 
            null);

希望这会有所帮助......

跟进回复:

  

嗨,即使有多个excel应用程序正在运行我的逻辑是使用当前正在突出显示的应用程序,即当前活动的应用程序(具有焦点)。

啊,您应该说...您的原始问题表明您希望复制从VB 6.0调用的GetObject方法的行为。为此,你在这里得到的答案都正确回答了这个问题。

所以,首先,请记住,您现在要求的是超越 VB 6.0的GetObject方法的功能。为此,您需要:

  1. 通过调用GetForegroundWindow Windows API函数获取活动应用程序的窗口句柄。
  2. 通过Process.GetProcessesByName("Excel")迭代所有当前运行的Excel流程,并将每个正在运行的Excel流程的Process.MainWindowHandle与之前使用GetForegroundWindow API获得的窗口句柄进行比较。假设您有匹配项,那么您已确认Excel应用程序是当前活动的应用程序。如果未找到匹配项,则当前没有Excel应用程序具有焦点,您可能希望向用户报告此情况。
  3. 确认活动窗口是正在运行的Excel应用程序后,您可以使用使用GetForegroundWindow API获得的窗口句柄,以获取可以控制的Excel应用程序对象。对此,请参阅安德鲁·怀特查佩尔(Andrew Whitechapel)撰写的文章Getting the Application Object in a Shimmed Automation Add-in,从阅读“抓住Excel应用程序对象,这就是我们要做的事情”一节开始。这是一个复杂的主题,但文章中的描述非常好,代码示例完美无缺。但是,在您的情况下,您将需要使用之前找到的活动窗口的窗口句柄替换代码int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle;的第一行。换句话说,就像这样:int hwnd = theHwndOfTheActiveWindowYouFoundEarlier
  4. 我意识到这需要消化很多,但是如果你按照这些步骤操作,它就会运行得很好。最难的部分是Andrew Whitechapel的代码,但除了需要更改第一行之外,这将按原样运行。祝你好运!

    - 迈克

答案 2 :(得分:2)

以下是使用Excel Automation访问ActiveSheet的示例控制台应用程序。

using Microsoft.Office.Interop.Excel;
using System.Reflection;

namespace ExcelAutomationConsole
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            _Application excelApp = null;
            try
            {
                excelApp = new Application();
                excelApp.Visible = true;

                Missing missing = Missing.Value;
                excelApp.Workbooks.Add(missing);
                // or
                //excelApp.Workbooks.Open("file.xlsx", missing, missing, missing, missing,
                //                        missing, missing, missing, missing,
                //                        missing, missing, missing, missing,
                //                        missing, missing);

                Worksheet sheet = excelApp.ActiveWorkbook.ActiveSheet as Worksheet;
                Range r = sheet.Cells[1, 1] as Range;
                r.FormulaR1C1 = "Test";
            }
            finally
            {
                excelApp.Quit();
            }
        }
    }
}