【问题标题】:Opening WinForm via Excel通过 Excel 打开 WinForm
【发布时间】:2014-03-29 04:29:02
【问题描述】:

我有一个处理 Excel 文件的 WinForm。现在它是一个.exe,它具有硬编码的文件加载或创建方法(仅用于测试)。我需要能够通过 Excel 文件打开.exe,然后将该文件(可能作为某个事件的发送者?)添加到表单中进行操作。

下面是我现在如何将 Excel 文件加载到表单中的示例。

public Excel.Application EXCEL_FILE;

public frmMain()
{
  InitializeComponent();
  this.EXCEL_FILE = new Excel.Application();
  this.EXCEL_FILE.SheetSelectionChange += new Excel.AppEvents_SheetSelectionChangeEventHandler(activeCellChanged);
  ExcelHandling.LoadExcelFile();
}

public static void LoadExcelFile()
{
    frmMain._frmMain.EXCEL_FILE.Workbooks.Open(@"F:\dsa.xlsx", 0, false, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
    frmMain._frmMain.EXCEL_FILE.Visible = true;
}

总结一下我需要建立的工作流程是:打开一些 Excel 文件->调用 WinForm(通过插件或其他方式?)->将调用 WinForm 的 Excel 文件加载到其中。

【问题讨论】:

  • 对,那么到目前为止您尝试过什么?您可以使用Shell 命令从 VBA 打开 *.exe 文件。较难的部分是通过您打开的那个 .exe 来获取已处理文件的句柄,但如果使用 winAPI 轻松打开 Excel 文件,您可以获取句柄
  • 到目前为止,我偶然发现了这个命令=EMBED("WinForms.Control.Host",""),我正在研究它作为一种方式,但我不确定它是否会有所帮助,这就是为什么我问是否有人知道一种做我所要求的方法。
  • @mehow 我的第一个想法是制作一个对话框将文件加载到表单中,但问题是客户希望能够通过 excel 文件调用表单,因为它以前是使用 VBA 编写的加载项/用户表单,他们希望保留以前的工作流程。
  • 对,那么它一定是exe吗?那么为什么不将它用作用户表单呢?如果它只是一个 Excel 的用户表单,那么它将消除调用外部 exe 的复杂性,只是为了完成一个非常简单的任务
  • 当时的想法是用户表单功能需要增长,而 VBA 代码变得非常难以维护和扩展,因此我将用户表单重写为更可扩展的 winform。我可以将 WinForm 用作用户表单吗?

标签: c# .net winforms excel vba


【解决方案1】:

您可以从 Excel 文件启动 C#-Exe,并通过 VBA 传递 excel 文件的文件名,如下所示:

Sub StartCSharpExe()
    Shell "<full path to your exe-file> " + ActiveWorkbook.FullName, 1
    Application.Quit //optional to close Excel
End Sub

然后您可以在 C#-Program 中读取 excel 文件的文件名作为命令参数,如下所示:

   private void GetCommands()
    {
        String[] arrCommands = Environment.GetCommandLineArgs();
        foreach (String command in arrCommands)
        {
            MessageBox.Show(command); // just for debugging purpose / if you'd like to see all parameters
            // get the excel-file-name and open it...
        }
    }

也许excel文件是只读的,因为它可能仍然是打开的,我还没有测试过,
但这是要走的路。

【讨论】:

  • 它工作正常,但正如你提到的,当我使用Workbooks.Open 将调用的 excel 文件加载到表单中时,它会再次以只读方式加载它。是否有任何其他命令可以将文件加载到变量中,或者我必须使用StreamReader 或其他东西来获取文件?
  • 问题是你先用excel打开文件。对于现在尝试访问该文件的所有其他程序,它是只读的,因为它已经打开。您可以尝试通过 VBA 关闭 Excel,然后使用 C#-Programm 中的计时器等待几毫秒或几秒钟,然后再打开 Excel 文件。那么它不应该是只读的了。
  • 我找到了一种不关闭文件的方法,但我不能确定我会以这种方式获得正确的文件,即EXCEL_FILE = (Excel.Application)Marshal.GetActiveObject("Excel.Application");。如果我能以某种方式获得所有活动的Excel.Applications,然后通过比较文件路径或其他方式选择调用 Winform 的那个,它将解决我所有的问题。
  • 也许这个链接对你有帮助:stackoverflow.com/questions/7646498/…
  • 从头开始,事实证明EXCEL_FILE = (Excel.Application)Marshal.GetActiveObject("Excel.Application"); 在我的情况下完美运行,我在打开 5 个 excel 窗口的情况下对其进行了测试,它总是得到调用 winform 的那个。
【解决方案2】:

我将在这里发布我的完整解决方案,因为我认为它可能对人们有用。
您将按照user1567896 的建议,使用以下代码在 Excel 中调用表单:

Sub StartCSharpExe()
    Shell "<full path to your exe-file> " + ActiveWorkbook.FullName, 1
    Application.Quit //optional to close Excel
End Sub

然后将 Excel 文件另存为 Excel 插件文件 (.xla)。
之后(在 Excel 中),转到 Developer Tab-&gt;Add-ins-&gt;[browse to your .xla file]-&gt;OK
然后,您可以通过以下方式将该加载项添加到您的 Quick Access Toolbar
File-&gt;Options-&gt;Quick Access Toolbar-&gt;[Choose commands from:]Macros-&gt;YourAddin.xla

c# 方法应该看起来像这样,并在表单初始化中调用:

using Excel = Microsoft.Office.Interop.Excel;
public static void LoadExcelFile()
{
    Excel.Application EXCEL_FILE = new Excel.Application();
    EXCEL_FILE = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
}

注意:我在打开几个窗口的情况下对此进行了测试,GetActiveObject("Excel.Application") 总是返回通过 Excel 调用 WinForm 的那个。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 2017-03-24
    • 1970-01-01
    • 2023-03-29
    • 2014-05-30
    • 2013-12-15
    相关资源
    最近更新 更多