【问题标题】:Prevent Word macro in Normal.dotm for some templates防止某些模板在 Normal.dotm 中使用 Word 宏
【发布时间】:2016-05-21 21:38:31
【问题描述】:

我有一个包含 AutoNew 宏的 Normal.dotm 文件。 每次使用任何其他模板创建新文档时,都会自动执行此宏。

有什么方法可以阻止特定模板的这种自动行为? 我有一个 Word VSTO 插件正在运行,所以我可以挂钩 Word 的事件,但到目前为止我还没有找到防止这种情况发生的方法。

我知道我可以在以编程方式使用模板时阻止宏执行,例如:

' Disable auto-macros before opening document
wordApplication.WordBasic.DisableAutoMacros(1)

' Open document
newWordDocument = wordApplication.Documents.Open(template.FullName, ConfirmConversions:=False, [ReadOnly]:=True, AddToRecentFiles:=False, Revert:=True)

' Re-enable auto-macros
wordApplication.WordBasic.DisableAutoMacros(0)

但当用户使用 Windows 资源管理器中的 Word 模板或 Word 中的打开对话框时,此解决方案不起作用,因为在这些情况下,我无法执行代码,否则为时已​​晚。

或者我可以吗? 我希望有人对我有用:-)

-

编辑:在尝试不同的解决方案时,我发现了一些可以帮助处于类似情况的其他人的方法,但不幸的是它对我没有帮助。 似乎如果一个模板包含一个包含AutoNew(或AutoOpen)的模块,则执行该本地宏而不是Normal.dotm中的宏。

例子:

Normal.dotm 包含以下宏:

Sub AutoNew()
    MsgBox "Normal.dotm"
End Sub

Test.dotm 包含以下宏:

Sub AutoNew()
    MsgBox "Test.dotm"
End Sub

执行Test.dotm时会显示“Test.dotm”消息,而不会显示“Normal.dotm”消息。
如果将AutoNew 宏从Test.dotm 模板中删除,则确实会显示消息“Normal.dotm”。

因此,可以轻松覆盖自动宏。
AutoNewAutoOpen 的本地版本甚至可以是什么都不做的空子。它仍然有效。

在我的情况下这是不可能的,因为我使用的模板是由代码生成的,并且不能包含宏(因为以编程方式将宏添加到模板需要用户手动激活选项“信任对 VBA 项目对象模型的访问",这是我不能要求我的客户为所有用户做的事情。这也是一个安全风险。)

【问题讨论】:

  • 注意:在这种情况下,我无法在 Normal.dotm 中编辑提到的 AutoNew 宏。
  • 如果您无法编辑并且必须使用用户的 Word 实例,那么,不,我认为没有任何办法解决这个问题。宏有什么问题?
  • 好的,我希望在宏执行之前有一些事件,所以我可以阻止它。部分问题是这个宏修改了页眉和页脚,使得我的模板生成的文档看起来很不对。
  • @Gertsen,您的代码是否有某些原因无法删除有问题的页眉和页脚并将其替换为可接受的页眉和页脚?您还可以更改 AttachedTemplate 以使将来的家务管理更容易。如果您理解这种可能性并提出您的问题只是为了使您的代码更高效,我们深表歉意,但是在处理 Word 对象模型时,删除内容并重建它通常是唯一的行动方案。
  • Gertsen,鉴于您发布的其他信息,可能有一种方法,因为您的项目是 .NET 而不是 VBA。您可以使用 Open XML SDK 创建模板——或者至少附加它的宏部分。这不会在用户环境中运行,因此用户设置不会影响它。如果这是一个选项,我可以在“答案”中写出更多细节......

标签: vba ms-word vsto


【解决方案1】:

根据问题“编辑”部分中描述的解决方法 - 提供带有“空”自动宏的模板 - 可以使用 Open XML SDK 创建模板并将 VBA 项目按顺序添加到其中来提供这个功能。这种方法避免了用户需要允许访问其安装的 VBA 项目。唯一可以触发的“宏安全”是不允许宏运行。但是由于客户端使用宏,无论如何,这应该不是主要障碍。

最简单的方法是在 Word UI 中创建尽可能多的基本模板,并以此为起点。

由于您不熟悉 Open XML SDK,下一步将使用基本模板作为起点在 Word UI 中创建一个(或多个)模板,并以不同的文件名保存。

然后,您可以使用 Open XML SDK Productivity Tool 查看生成任何这些文件所需的代码,以及使用比较工具查看将基本模板转换为派生版本的代码。这应该为您提供 SDK 及其对象模型的良好开端。一旦您了解了 Open XML SDK 的工作原理,如果您熟悉 Word 的对象模型,那么使用 SDK 提供的模型就相对简单,因为我们已努力使其尽可能接近“ COM”对象模型。

VBA 项目可以稍后添加,但您也可以将其包含在基本模板中。那将是最简单的方法。

将此“起点”基本模板作为解决方案的一部分,并将其作为解决方案的一部分进行安装。

【讨论】:

  • 谢谢,这对我有用 :-) 特别是提到“Open XML SDK Productivity”会很有帮助,因为它会切断我原本需要生成的很多时间我使用 SDK 的模板。
【解决方案2】:

AutoNew 宏中,您可以检查AttachedTemplate 属性。只有当它是您要应用清理的模板时,您才能执行相应的宏。

Sub AutoNew()

    If ActiveDocument.AttachedTemplate <> "Normal.dotm" Then
        Exit Sub
    End If

    ' rest of the macro

End Sub

如果您不控制 Normal.dotm,您可以在自己的模板中放置一个空的 AutoNew 宏。作为 Word only executes the auto macro in the closest context,Normal.dotm 文件中的宏不会被执行。

如果您也不控制其他模板,您可以告诉您的用户在创建文档时按住 SHIFT 键。这可以防止自动宏的执行。

但是,如果您要求其他系统的所有者找到另一个不依赖于污染 Normal.dotm 文件的解决方案,这可能是最好的。

【讨论】:

  • 不幸的是,在这种情况下,我无法编辑 Normal.dotm 宏,但如果是这样,我相信您的解决方案会奏效。在这种情况下,宏是由另一个系统添加的(需要它们正常运行),所以我需要解决它:-/
  • 我找到了另一个类似于你的解决方案,并用这个更新了我的问题。我希望其他人会觉得它很有趣,即使它对我没有帮助。
猜你喜欢
  • 1970-01-01
  • 2014-02-04
  • 2013-09-29
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多