0

我们为 Excel 开发了一个 VSTO 插件,它从 Web 服务器中提取 Excel 表格,并允许用户操作表格上的数据。它适用于文件的本地副本,但我们并不真正关心该副本。但是我们的一些客户也安装了“iManage Integration for Office”,这些客户遇到了奇怪的行为。在这种环境下,我们无法取消 Close 事件。

更具体地说,如果用户打开我们的文件并进行更改,然后关闭文件,我们的事件处理程序将触发并提示他们保存更改(对服务器上的数据)。如果他们选择取消,或者如果他们选择保存并且由于某种原因保存失败,我们设置 Cancel = true 以尝试保持文件打开。通常这可以完美地工作。

对于那些使用 iManage 的客户,文件无论如何都会关闭。如果我们的代码已经保存了文件的本地副本,那么文件就会关闭。如果本地副本尚未保存,用户会在我们的提示之后从 iManage 收到另一个提示,询问他们是否要保存文件。从这里,用户可以单击取消,文件保持打开状态。但是用户报告说,在第一次单击“取消”后看到第二个提示令人困惑。他们不愿意禁用 iManage 插件。在这种情况下,我们希望能够保持文件打开,最好不要看到 iManage 提示。

在客户为我设置的测试环境(Excel 2010)中工作,我尝试了一些事情:

  • 我尝试在工作簿级别 BeforeClose 和应用程序级别 WorkbookBeforeClose 上设置取消;两者都不起作用(只要启用 iManage,文件仍会关闭)
  • 我试图确保我的 WorkbookBeforeClose 处理程序是最后注册的,方法是在工作簿级别的事件处理程序中注册它;没变
  • 我可以使用 iManage 功能区手动切换到本地模式,这使一切正常,但我不知道是否/如何通过代码进行更改。
  • 我可以在 Globals.ThisAddIn.Application.COMAddIns 中找到 iManage 插件;我尝试设置它的 Connect = false,但这会产生一个错误,即只有管理员可以连接/断开插件。
  • 我可以在 Closing 事件期间保存本地文件,然后执行 SaveAs 创建第二个副本;第二个副本现在处于活动状态,iManage 将其关闭;然后我重新打开原始本地文件。它对用户来说看起来不错,但是我有一堆对旧文件中单元格的 COM 引用,这些都是垃圾。我可能可以循环并序列化它们并使用新文件重新创建它们,但是编码和运行会很耗时,所以我首先在寻找其他想法。

有什么办法可以让文件保持打开状态,而不让用户做任何额外的事情?

更新

使用 iManage 9.3.0.0 和 Excel 2010,我创建了一个 VBA 宏,并引用了 Worksite Integration Interfaces Library(Ex)。事件触发,但文件仍然关闭。如果我没有设置 Saved 属性,而是在网格上键入,我总是会收到 iManage 的提示,询问我是否要保存。

Private WithEvents oWS As iManageExtensibility

Private Sub oWS_DocumentBeforeClose2(ByVal Doc As Variant, IgnoreIManageClose As Boolean, Cancel As Boolean)
    IgnoreIManageClose = True
    Cancel = True
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Set oWS = Application.COMAddIns("WorkSiteOffice2007Addins.Connect").Object
    Cancel = True
    ActiveWorkbook.Saved = True
End Sub
4

1 回答 1

1

您无需禁用适用于 Office 的 iManage 集成加载项。您的应用程序应检测 iManage 集成插件的存在,然后处理该插件自己的等效关闭事件

WorkSiteOffice2003Addins.Connect为此,首先通过检查 Excel Application.COMAddins 集合并使用(Excel 2003 或更早版本)或WorkSiteOffice2007Addins.Connect(Excel 2007 或更高版本)的 ProgID 取回 COM 加载项实例来获取 iManage 加载项的实例。

实际上,还应该安装一个所谓的“向后兼容性”加载项,该加载项也注册了oUR02k.Connect您可以引用的 ProgID。同样,是否安装在某种程度上取决于机器上安装的 FileSite/DeskSite 的版本。

这一切可能会让您感到困惑,但这是因为这些年来加载项发生了变化,因此这取决于 iManage 客户端的年龄(即 FileSite、DeskSite)以及您所针对的 Office 版本。您可能需要在代码中补偿不同的 Excel/iManage 客户端版本

获得正确的 COM 加载项引用后,请检查该COMAddin.Object属性。此值表示 iManage Office 集成加载项的实例

从那里您可以将该对象转换为强类型 COM 接口iManageExtensibility

然后,您可以连接到 iManage 劫持的所有 Office 应用程序事件(就像您在应用程序中所做的那样)并响应这些事件而不是原生 Excel 事件。

在您的情况下,您将需要监视DocumentBeforeClose2事件。请注意末尾的字符“2”。还有一个名为的旧事件DocumentBeforeClose,但较新的事件DocumentBeforeClose2具有以下方法签名:

DocumentBeforeClose2(object doc, ref bool ignoreimanageclose, ref bool cancel)

最后,在您的DocumentBeforeClose2事件处理程序中添加您的业务逻辑以取消关闭事件和/或 iManage 关闭事件。您可以通过将ignoreimanageclose和/或cancel布尔值适当地设置为 true/false 来做到这一点。在这种情况下,doc参数将是 Excel 工作簿实例,因此Excel.Workbook如果您愿意,可以安全地将其转换为界面

PS:如果您针对 iManage API 进行开发并需要支持,您应该考虑购买 iManage SDK。该 SDK 包含有关各种 API、代码示例的帮助,而且至关重要的是,我相信它可以让您获得一些开发支持。

于 2016-12-17T17:07:57.113 回答