我想更新当前文档中当前工作表中的值,而不管excel的文件名是什么。
在vb6.0中,我们可以做到
Set AppExcel = GetObject(, "Excel.Application")
Set SheetExcel = AppExcel.ActiveWorkbook.ActiveSheet
我怎么一直试图在C#中做同样的事情。
有没有办法在C#中做同样的事情。
答案 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
。
如果你必须在c#中编写代码,请注意使用Marshal.ReleaseComObject
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
方法的功能。为此,您需要:
int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle;
的第一行。换句话说,就像这样:int hwnd = theHwndOfTheActiveWindowYouFoundEarlier
。我意识到这需要消化很多,但是如果你按照这些步骤操作,它就会运行得很好。最难的部分是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();
}
}
}
}