一种使用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。 要做到这一点,你需要:
- 通过调用GetForegroundWindow Windows API函数来获取活动应用程序的窗口句柄。
- 通过Process.GetProcessesByName(“Excel”)迭代所有当前正在运行的Excel进程,并将每个正在运行的Excel进程的Process.MainWindowHandle与之前使用GetForegroundWindow API获得的窗口句柄进行比较。 假设你有一个匹配,那么你已经确认一个Excel应用程序是当前活动的应用程序。 如果找不到匹配项,那么目前没有Excel应用程序的重点,你可能想要报告给用户。
- 确认活动窗口是正在运行的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(); } } } }