使用自定义 UI 功能区部署启用 Word 宏的模板 (.dotm)

Posted

技术标签:

【中文标题】使用自定义 UI 功能区部署启用 Word 宏的模板 (.dotm)【英文标题】:Deploying Word Macro-Enabled Template (.dotm) with a Custom UI Ribbon 【发布时间】:2018-07-13 10:33:38 【问题描述】:

我已经构建了一个 Word 启用宏的模板 (.dotm),当我将它保存到我的 Word 启动文件夹时,它可以在我的机器上完美运行。但是,当我将.dotm 文件发送给我的同事(有些与我在相同的环境中,有些不是)时,按下自定义 ui 功能区按钮时会生成错误:

由于您的安全设置,找不到或已禁用宏

宏设置设置为运行所有宏,包含模板的文件夹>是受信任的位置

....更多帮助选项如下

我的同事也将文件保存到他们的启动文件夹并加载 Word。功能区显示完美,但宏不运行。我和我的同事在网上进行了大量搜索,但无法找出问题所在,因为我的所有配置都是正确的,据我所知,我将在下面列出:

宏设置:启用所有宏 已检查对 VBA 项目对象模型的信任访问 启动文件夹已建立为受信任位置

自定义 UI XML

<?xml version="1.0" encoding="utf-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
  <ribbon>
    <tabs>
      <tab id="customTab" label="WebMerge">
        <group id="CustomHelp" label="Map Tags">
          <button id="mapper"
                  visible="true"
                  size="large"
                  label="Open Mapper"
                  screentip="Opens Mapping Engine"
                  onAction="LoadMappingGuide"
            imageMso="FindDialog"/>
        </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>

标准模块中的 UI 功能区连接

Option Explicit

Sub LoadMappingGuide(ByVal Control As IRibbonControl) 'also tried without ByVal

    'select business unit or automatically detect based on username against our database ...
    Dim mappingForm As New mappingGuide
    mappingForm.Show vbModal

End Sub

ma​​ppingForm(用户窗体)代码

Option Explicit

Private Sub cancelButton_Click()

    Unload Me

End Sub

Private Sub searchBox_Change()

    generateList

    Dim n As Long, index As Long

    index = 0

    For n = 0 To smartTagList.ListCount - 1
        If InStr(1, smartTagList.List(index, 0), searchBox.Value, vbTextCompare) > 0 Then
            index = index + 1
        ElseIf InStr(1, smartTagList.List(index, 1), searchBox.Value, vbTextCompare) > 0 Then
            index = index + 1
        ElseIf InStr(1, smartTagList.List(index, 2), searchBox.Value, vbTextCompare) > 0 Then
            index = index + 1
        Else
            smartTagList.RemoveItem (index)
        End If
    Next n

End Sub

Private Sub smartTagList_Click()

    If smartTagList.ListIndex > -1 And smartTagList.Selected(smartTagList.ListIndex) Then

        Dim smartyTag As String
        smartyTag = smartTagList.List(smartTagList.ListIndex, 2)

        Selection.Range.Text = smartyTag

    End If

    Unload Me

End Sub

Private Sub UserForm_Initialize()

    generateList

End Sub

Private Sub generateList()

    'replace with code to get values from database

    Dim fields() As String
    Dim descriptions() As String
    Dim smartyTags() As String

    fields = Split("Producer Name,Producer Address,Producer City,Producer State,Producer Zip,Insured Name,Insured Address,Insured City,Insured State,Insured ZIp,Risk Premium,TRIA Premium,Final Premium", ",")
    descriptions = Split("Name of Producer,Address Line of Producer,City of Producer,State of Producer,Zip Code of Producer,Name of Insured,Address of Insured,City of Insured,State of Insured,ZIp of Insured,Total Premium for all risks excluding terrorism taxes and surcharges.,Premium resulting from acceptance of terrorism protection,Total Premium of quote / policy", ",")
    smartyTags = Split("$Producer Name,$ProducerAddress,$ProducerCity,$ProducerState,$ProducerZip,$InsuredName,$InsuredAddress,$InsuredCity,$InsuredState,$InsuredZIp,$RiskPremium,$TRIAPremium,$FinalPremium", ",")

    Dim i As Long
    For i = LBound(fields) To UBound(fields)

        With smartTagList

            .AddItem
            .List(i, 0) = fields(i)
            .List(i, 1) = descriptions(i)
            .List(i, 2) = smartyTags(i)

        End With

    Next

End Sub

这是我的 VBE 在打开 .dotm 时的样子。

【问题讨论】:

为了完整起见,我不得不问:功能区的宏在模板文件文件中,而不是(也)在您的 Normal.dotm 中? (那个“也”很重要......)如果您在模板中放入任何其他宏,其他人可以运行它们吗?如果是,如果您的同事将他们分配到功能区或 QAT,他们会运行吗?哪个版本的 Word? @CindyMeister - 谢谢你的完整性。我需要它。第一次开发 Word 插件。我认为你在做某事。我发布了一张打开模板文件的 VBE 图片。我想我确实不小心在我的Normal 模板而不是加载项文件中构建了它。我正在使用 2010 Word。 【参考方案1】:

错误消息最可能的原因是宏在包含功能区自定义的模板中不可用。通常,它们保留在开发机器上的Normal.dotm 模板中。

背景:

VBA 开发人员在开始一个项目并在 Word 中进行测试时始终需要牢记的是,Word 可以使用多个“上下文”。首先,在私人用户环境中录制宏和创建功能时,最重要的默认设置是Normal.dotm 模板。这是“通用的”:无论您在哪个文档中工作,它都会发挥作用,即使该文档附加到不同的模板。

这样做的最大危险是您可能忘记将用于特定模板的代码从 Normal.dotm 移动到该模板。或者,即使您确实复制了代码,如果两个模板中都存在具有相同过程名称的代码,Normal.dotm 中的代码可能会保持优先级。

在将宏分配给功能区和 QAT 按钮时尤其会出现这个问题。即使来自开发人员计算机的Normal.dotm 不再存在,功能区或 QAT 分配仍会查找它并且不会检查备用源。

因此,如果您决定将代码保留在 Normal.dotm 以及特定模板中,最好重命名 Normal.dotm 中的过程以避免冲突。

【讨论】:

欣赏解释。我在想我只是把代码放到了错误的地方,但现在我看到它的行为是默认它在那里。疯狂的。但现在我知道要更加小心。 @ScottHoltzman 当我看到您的代表时,我认为这会有所帮助 :-) 对于非 Office 开发人员来说,通常难以理解的是 Word 的对象模型在很大程度上反映了 UI 中的工作方式。不像旧的 WordBasic 那样糟糕,但对于那些来自其他语言和环境的人来说仍然不合逻辑。 您好,您能告诉我您为解决错误所做的工作吗?我面临着完全相同的错误。如何获取我添加到我创建的新宏模板中的代码?这是与此完全相同的问题。 [***.com/questions/56188333/…。此外,我没有单独的 UI 功能区代码和表单代码。我这样命名我的宏子 - Sub ExtractCommentsFromWord(ByVal control As IRibbonControl) @DeepakV 如果您有问题,您需要将其作为问题提出,而不是对答案添加评论。包括与问题有关的所有相关信息,以便无法回头看的人可以了解您拥有什么以及您正在尝试做什么。

以上是关于使用自定义 UI 功能区部署启用 Word 宏的模板 (.dotm)的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 Word 的自定义后台 UI 不显示其用户界面?

用于启用宏的 VBA 或 VBA ms 字

VBA 代码无法在启用宏的文件类型中运行

Word-press显示图像类型plgin+自定义post类型Ui

自定义环境中运行应用程序中的 Grails 自动重新加载功能

WORD中的宏被禁止怎么办?