【问题标题】:How set a (Word/Excel).Document.BeforeCloseEvent (using Interop) to prevent them being closed?如何设置 (Word/Excel).Document.BeforeCloseEvent(使用互操作)以防止它们被关闭?
【发布时间】:2018-04-21 22:22:44
【问题描述】:

我有一个Windows.Form application,它与WordExcel 一起使用。为了与他们合作,我使用Interop package。另外,我正在使用 Visual Studio 和 C# languaje 进行编程。

我创建了一个EventHandler,它在 Word 文档关闭之前执行,另一个 EventHandler 在 Excel 文档关闭之前执行。这两个事件的作用是:取消关闭文档,并隐藏它而不是关闭,因此文档继续在内存中运行。

ExcelDocument->BeforeCloseEvent 工作正常,但 WordDocument->BeforeCloseEvent 给出错误:

System.NullReferenceException:对象引用未设置为实例 一个对象。

下面的代码中指出了我得到错误的行。 (在代码中,我只展示了如何包含 Word/Excel、启动它们以及两个 EventHandlers...在完整代码的其他部分中,我展示了使用 aplicacionWord/aplicacionExcel .visible = true,...)的应用程序。 p>

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
// Include Word
using Word = Microsoft.Office.Interop.Word;
// Include Excel
using Excel = Microsoft.Office.Interop.Excel;

public partial class formWord : Form
{
    // New object type application of Word
    Word.Application aplicacionWord = new Word.Application();
    // New instance for Word document
    Word.Document documentoWord;
    // New object type application of Excel
    Excel.Application aplicacionExcel = new Excel.Application();
    // New instance for Excel document
    Excel.Workbook documentoExcel;
    // New instance for Excel Worksheet
    Excel.Worksheet documentoExcelPrimeraHoja;

    private void formWord_Load(object sender, EventArgs e)
    {
        // Word application is not visible
        aplicacionWord.Visible = false;
        // Create new Word document
        documentoWord = aplicacionWord.Documents.Add();
        // Excel application is not visible
        aplicacionExcel.Visible = false;
        // Create new document and get its first worksheet
        documentoExcel = aplicacionExcel.Workbooks.Add(Missing.Value);
        documentoExcelPrimeraHoja = (Excel.Worksheet)documentoExcel.Worksheets.get_Item(1);

        // Word document event before close
        aplicacionWord.DocumentBeforeClose +=
            new Word.ApplicationEvents4_DocumentBeforeCloseEventHandler(
                (Word.Document Doc, ref bool Cancel) => {
                    // If Word aplication is visible, then:
// HERE IS THE ERROR ---------------------------------
// ------- in aplicacionWord --> NULL REFERENCE
                    if (aplicacionWord.Visible)
                    {
                        // Cancel closing document
                        Cancel = true;
                        // Hide againg Word application
                        aplicacionWord.Visible = false;
                    }
                }
            );

        // Excel document event before close
        documentoExcel.BeforeClose +=
            new Excel.WorkbookEvents_BeforeCloseEventHandler(
                (ref bool Cancel) => {
                    // If Excel aplication is visible, then:
                    if (aplicacionExcel.Visible)
                    {
                        // Cancel closing document
                        Cancel = true;
                        // Hide Excel aplication again
                        aplicacionExcel.Visible = false;
                    }
                }
            );
    }
}

// How I close both documents
private void formWord_FormClosing(object sender, FormClosingEventArgs e)
{

    // Closing applications
    aplicacionWord.Quit();
    aplicacionWord= null;
    aplicacionExcel.Quit();
    aplicacionExcel = null;
}

正如我所说,Excel 的事件没有错误,但在 Word 中却有。错误是由于文档被关闭,所以... BeforeClose 没有按预期工作。有没有其他方法可以处理 BeforeClose 事件?还是我做错了什么?

另外,我不确定这是否是处理 Word 和 Excel 的 Document.BeforeCloseEvent 的最佳方式。任何升级它的想法都会很棒。

提醒:我希望在关闭 Word/Excel 文档时 - Word/Excel 应用程序可见 - (用户单击 Top-Right-X 退出)而不是关闭文档,而是将其隐藏以使其保持打开状态。

PS:如果你想在你的机器上尝试这个问题,你只需在我的代码中改变这个:

// Word application is not visible
aplicacionWord.Visible = true;
// Excel application is not visible
aplicacionExcel.Visible = true;

然后,当 c# 应用程序运行时,关闭两个程序(Word/Excel),您将看到错误。

【问题讨论】:

  • 此类程序中的传统错误是在程序终止时试图让 Word 进程终止的代码。它倾向于做一些事情,比如调用 Marshal.ReleaseComObject()。这样做总是错误的方法,但是互联网上充斥着关于它的不良信息。我的水晶球告诉我,这段代码还将 apliacionWord 设置为空。卡布姆。删除该代码,全部删除。
  • 是的,这就是它的样子,它将它设置为 NULL。我的结论是:首先,BeforeDocumentClose 事件不起作用,因为在这种情况下,对象不应设置为 NULL。其次,如果它有效,您也不应该将对象设置为 NULL,因为我正在关闭文档,而不是应用程序。关于删除代码......我被明确要求使用interop......所以我必须这样做。

标签: c# visual-studio office-interop


【解决方案1】:

我只能与 Word 对话 - 但由于您遇到了错误...您说

提醒:我希望在关闭 Word/Excel 文档时 - Word/Excel 应用程序可见 - (用户单击右上角 X 以 exit) 而不是关闭文档,而是隐藏它以使其保持打开状态。

如果用户单击应用程序的 red-x 按钮,那么他关闭的不是文档,而是退出 Word.Application。这也将关闭触发 BeforeClose 的文档,但由于应用程序不再可用,您会收到错误 - 对象 aplicacionWord 为“null”。

Word 有一个Quit 事件,但这没有提供取消选项 - Word 将退出。

您可以将代码放在Quit 事件中,但是,要执行某些操作,例如设置布尔值,您可以签入BeforeClose,保存文档,启动 Word 的新实例 - 不可见 - 然后打开在新实例中再次查看该文档。

请务必注意,Excel 和 Word 在许多方面不同。尽管两者都在“Microsoft Office”的保护伞下,但它们的起源却截然不同,并且由不同的团队开发。偶尔会尝试将所有“核心”MS Office 应用程序更紧密地结合在一起,因为它们确实有一些共同点(打开、保存和关闭用户界面就是一个很好的例子),但它们“内部”的行为方式是完全独立的并且不相关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 2018-05-12
    • 2021-02-09
    • 2013-02-21
    • 1970-01-01
    相关资源
    最近更新 更多