C#Excel如何使用已经打开的工作簿

发布于 2025-01-30 01:02:00 字数 1059 浏览 2 评论 0原文

这个问题是从我最后一个问题的学习中提出的:上一个问题

我需要能够将文本发送到已打开的选定工作表。

我认为这很接近,但它没有起作用:

        string wb = cmb_BookName.Text.ToString();
        string ws = cmb_SheetName.Text.ToString();

        if (chkContainer.Checked)
        {
            Excel.Application oexcel = new Excel.Application();
            Excel.Workbook wkbk = (Excel.Workbook)oexcel.Workbooks[wb];
            Excel.Worksheet wksk = (Excel.Worksheet)wkbk.Sheets[ws];
            Range cellRange = wksk.Range["D48:D48"];
            cellRange.Value = cboContainer.Text;
        }

该代码没有错误构建,但是当运行时,该代码会停在线上试图获取工作簿,请参阅图像。

所以基本上我的问题仍然是如何我是否可以使用已经打开的Excel工作簿?

似乎我发现的大多数文章都在打开一个Excel文件,然后使用它。就我而言,我需要使用已经打开的Excel工作簿。

This is a question that was taken from the learning's of my last question: Previous Question

I need to be able to send text to a selected worksheet that is already opened.

This, I think is close but it didn't work:

        string wb = cmb_BookName.Text.ToString();
        string ws = cmb_SheetName.Text.ToString();

        if (chkContainer.Checked)
        {
            Excel.Application oexcel = new Excel.Application();
            Excel.Workbook wkbk = (Excel.Workbook)oexcel.Workbooks[wb];
            Excel.Worksheet wksk = (Excel.Worksheet)wkbk.Sheets[ws];
            Range cellRange = wksk.Range["D48:D48"];
            cellRange.Value = cboContainer.Text;
        }

The code builds without errors but when running it stops at the line trying to get the workbook, see image.enter image description here

So basically my question still is how do I work with an excel workbook that is already opened?

Seems like most of the articles that I find are opening an excel file and then working with it. In my case, I need to work with an already opened excel workbook.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瞳孔里扚悲伤 2025-02-06 01:02:01

There are some helpful answers (some of them, not the accepted answer) to this question here:

但这是我的摘要答案。

尝试一下:

首先
您必须访问当前正在运行的应用程序(如果已经有多个Excel运行的实例,这可能每次都无法正常工作)

using Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;

// I use a global application object
Application excelApp;

// Gets the first running instance of the Excel.Application
// If that fails, the error is caught, and a new application is created
try
{
   excelApp = (Application)Marshal.GetActiveObject("Excel.Application");
}
catch (COMException ex)
{
   excelApp = new Application
   {
      Visible = true
   };
}

second
通过路径获取所需的工作簿(必须是Windows样式,即“ C:\ Desktop \ Myworkbook.xlsx”)

Workbook myWorkbook = null;

foreach (Workbook xlWorkbook in excelApp.Workbooks)
{
   if (xlWorkbook.FullName == "<path to workbook>")
   {
      myWorkbook = xlWorkbook;
   }
} 

There are some helpful answers (some of them, not the accepted answer) to this question here: Accessing an open Excel Workbook in C#

But here is my summarized answer.

Try this:

First
You must access the currently running application (if there are multiple instances of Excel running already, this might not work everytime)

using Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;

// I use a global application object
Application excelApp;

// Gets the first running instance of the Excel.Application
// If that fails, the error is caught, and a new application is created
try
{
   excelApp = (Application)Marshal.GetActiveObject("Excel.Application");
}
catch (COMException ex)
{
   excelApp = new Application
   {
      Visible = true
   };
}

Second
Get the desired workbook by path, (must be windows style, i.e. "C:\Desktop\myWorkbook.xlsx")

Workbook myWorkbook = null;

foreach (Workbook xlWorkbook in excelApp.Workbooks)
{
   if (xlWorkbook.FullName == "<path to workbook>")
   {
      myWorkbook = xlWorkbook;
   }
} 
清音悠歌 2025-02-06 01:02:01

它看起来像元帅。getActiveObject在基于.net Core的.NET版本中消失了。
但是我在另一个论坛上找到了一个简单的解决方案。

using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;

public static partial class MarshalForCore
{
    internal const String OLEAUT32 = "oleaut32.dll";
    internal const String OLE32 = "ole32.dll";

    [System.Security.SecurityCritical]
    public static Object GetActiveObject(String progID)
    {
        Object obj = null;
        Guid clsid;

        try
        {
            CLSIDFromProgIDEx(progID, out clsid);
        }
        catch (Exception)
        {
            CLSIDFromProgID(progID, out clsid);
        }

        GetActiveObject(ref clsid, IntPtr.Zero, out obj);
        return obj;
    }

    [DllImport(OLE32, PreserveSig = false)]
    [ResourceExposure(ResourceScope.None)]
    [SuppressUnmanagedCodeSecurity]
    [System.Security.SecurityCritical]
    private static extern void CLSIDFromProgIDEx([MarshalAs(UnmanagedType.LPWStr)] String progId, out Guid clsid);

    [DllImport(OLE32, PreserveSig = false)]
    [ResourceExposure(ResourceScope.None)]
    [SuppressUnmanagedCodeSecurity]
    [System.Security.SecurityCritical]
    private static extern void CLSIDFromProgID([MarshalAs(UnmanagedType.LPWStr)] String progId, out Guid clsid);

    [DllImport(OLEAUT32, PreserveSig = false)]
    [ResourceExposure(ResourceScope.None)]
    [SuppressUnmanagedCodeSecurity]
    [System.Security.SecurityCritical]
    private static extern void GetActiveObject(ref Guid rclsid, IntPtr reserved, [MarshalAs(UnmanagedType.Interface)] out Object ppunk);
}

可以像这样使用:

using xl = Microsoft.Office.Interop.Excel;
...
    try
    {
        var excelApp = (xl.Application)MarshalForCore.GetActiveObject("Excel.Application");
        if (excelApp != null)
        {
            var wb = excelApp.ActiveWorkbook;

            xl.Worksheet? sh = null;
            foreach (xl.Worksheet _ in wb.Worksheets) 
              if (_.Name == "MyTable") 
              { 
                sh = _; 
                break; 
              };

            if (sh == null)
            {
                sh = (xl.Worksheet)wb.Worksheets.Add();
                sh.Name = "MyTable";
            }
            sh.Cells[1, 1] = "Hello World";
        }
    }
    catch
    {
        // Excel is not running.
    }
}

It looks like Marshal.GetActiveObject is gone in newer .NET Core based .NET versions.
But I found a simple solution on another forum.

using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;

public static partial class MarshalForCore
{
    internal const String OLEAUT32 = "oleaut32.dll";
    internal const String OLE32 = "ole32.dll";

    [System.Security.SecurityCritical]
    public static Object GetActiveObject(String progID)
    {
        Object obj = null;
        Guid clsid;

        try
        {
            CLSIDFromProgIDEx(progID, out clsid);
        }
        catch (Exception)
        {
            CLSIDFromProgID(progID, out clsid);
        }

        GetActiveObject(ref clsid, IntPtr.Zero, out obj);
        return obj;
    }

    [DllImport(OLE32, PreserveSig = false)]
    [ResourceExposure(ResourceScope.None)]
    [SuppressUnmanagedCodeSecurity]
    [System.Security.SecurityCritical]
    private static extern void CLSIDFromProgIDEx([MarshalAs(UnmanagedType.LPWStr)] String progId, out Guid clsid);

    [DllImport(OLE32, PreserveSig = false)]
    [ResourceExposure(ResourceScope.None)]
    [SuppressUnmanagedCodeSecurity]
    [System.Security.SecurityCritical]
    private static extern void CLSIDFromProgID([MarshalAs(UnmanagedType.LPWStr)] String progId, out Guid clsid);

    [DllImport(OLEAUT32, PreserveSig = false)]
    [ResourceExposure(ResourceScope.None)]
    [SuppressUnmanagedCodeSecurity]
    [System.Security.SecurityCritical]
    private static extern void GetActiveObject(ref Guid rclsid, IntPtr reserved, [MarshalAs(UnmanagedType.Interface)] out Object ppunk);
}

This can be used like so:

using xl = Microsoft.Office.Interop.Excel;
...
    try
    {
        var excelApp = (xl.Application)MarshalForCore.GetActiveObject("Excel.Application");
        if (excelApp != null)
        {
            var wb = excelApp.ActiveWorkbook;

            xl.Worksheet? sh = null;
            foreach (xl.Worksheet _ in wb.Worksheets) 
              if (_.Name == "MyTable") 
              { 
                sh = _; 
                break; 
              };

            if (sh == null)
            {
                sh = (xl.Worksheet)wb.Worksheets.Add();
                sh.Name = "MyTable";
            }
            sh.Cells[1, 1] = "Hello World";
        }
    }
    catch
    {
        // Excel is not running.
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文