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

我想更新当前文档中当前工作表的值,而不考虑excel的文件名。

在vb6.0我们可以做到

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

我曾经试图在C#中做同样的事情。

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

 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); } } 

我已经根据这里给出的例子修改了代码。

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

要么

您可以参考Microsoft.VisualBasic.dll。
并调用GetObject

编辑:你为什么需要这样的事情? 不会创build一个Excel加载帮助?

如果你必须在c#中编写代码,请注意释放使用Marshal.ReleaseComObject创build的COM实例

编辑2:为了得到ActiveSheet的引用,你可以写

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

我再次build议你不要走这条路。
在VB6中编写代码来做你所需要的,并从c#/ vb.net中调用它。

总之,答案绝对是。

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

您可能想要考虑创build一个托pipe的COM加载项,该加载项在Excel应用程序本身运行,因此从来没有任何关于它控制的“哪个”Excel应用程序实例的问题。 要做到这一点,您可以先看看文章如何使用Visual C#.NET构buildOffice COM加载项 。

如果您知道要控制的Excel应用程序实例的进程ID或主窗口句柄(又名“Hwnd”),则可以访问此精确实例。 要学习如何做到这一点,你可以阅读Andrew Whitechapel关于这个主题的讨论。 您感兴趣的部分从阅读“为了获得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方法的function。 要做到这一点,你需要:

  1. 通过调用GetForegroundWindow Windows API函数来获取活动应用程序的窗口句柄。
  2. 通过Process.GetProcessesByName(“Excel”)迭代所有当前正在运行的Excel进程,并将每个正在运行的Excel进程的Process.MainWindowHandle与之前使用GetForegroundWindow API获得的窗口句柄进行比较。 假设你有一个匹配,那么你已经确认一个Excel应用程序是当前活动的应用程序。 如果找不到匹配项,那么目前没有Excel应用程序的重点,你可能想要报告给用户。
  3. 确认活动窗口是正在运行的Excel应用程序之后,可以使用GetForegroundWindow API获得的窗口句柄来获取可以控制的Excel应用程序对象。 对此,请参阅Andrew Whitechapel 的“Shimmed Automation Add-in”中的文章“ 获取应用程序对象” ,从阅读“获取Excel应用程序对象,这是我们将要做的”一节开始。 这是一个复杂的话题,但文章中的描述非常好,代码示例完美地工作。 在你的情况,但是,你会想要代替第一行int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle; 用你之前find的活动窗口的窗口句柄。 换句话说,就像这样: int hwnd = theHwndOfTheActiveWindowYouFoundEarlier

我意识到这是很多消化,但如果你按照这些步骤,它会运行得很好。 最难的部分是安德鲁·怀特佩尔的代码,但是这将会按原样运行,而不是需要改变第一行。 祝你好运!

迈克

以下是使用Excel自动化访问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(); } } } }