使用自定义功能区关闭并重新打开文档后,Word 会话功能区会发生什么情况? [英] What happens to the Word session ribbon after closing and reopening a document with a custom ribbon?

查看:167
本文介绍了使用自定义功能区关闭并重新打开文档后,Word 会话功能区会发生什么情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Office 365 (Word 11929.20254) 和 Word 2016 的两个完全不同的 Windows 环境(家庭和工作)中遇到以下情况,使用一系列使用 VBA 和 customUI.xml 显示自定义功能区的文档和模板:

I have experienced the following situation in two totally different Windows environments (home and work) on Office 365 (Word 11929.20254) and Word 2016, using a range of documents and templates which use VBA and customUI.xml to display a custom ribbon:

  1. 我打开任何 Word 文档(现有文档或基于 Normal.dotm 的新空白文档).
  2. 我打开另一个 Word 文档,它有一个自定义功能区 (customUI.xml);下面的基本示例.
  3. 我使用自定义功能区关闭文档.
  4. 我使用自定义功能区重新打开文档.
  5. 此时自定义功能区有几个问题(没有发生 VBA 错误).即使第二个文档功能区上的第一个选项卡属于自定义功能区(即它在主页选项卡之前),它也不会激活.onLoad 回调不运行.这只能通过单击自定义功能区选项卡来解决,此时它会立即生效(并在加载时运行),或者关闭所有 Word 文档并重新打开.

如果我在 Excel 或 PowerPoint 中使用电子表格或演示文稿文件运行上述情况,该文件的自定义功能区与我在上面的 Word 中使用的完全相同,则步骤 5 不适用;功能区正常工作,onLoad 运行,等等.

If I run the above situation in Excel or PowerPoint with spreadsheet or presentation files with the exact same custom ribbon as I used in Word above, step 5 doesn't apply; the ribbon works properly, onLoad runs, and so on.

为什么 Word 功能区似乎存在其他 Office 功能区所没有的缺陷?开发加载项而不是 VBA 和 customUI.xml 会解决或绕过这个问题吗?

Why does the Word ribbon appear to be deficient in a way in which other Office ribbons are not? Would developing an add-in rather than VBA and customUI.xml resolve or bypass this issue?

自定义功能区和相关 VBA 的裸例如下.将这些放在一个 Word 文档的 customUI.xml 和 VBA 中,并将其用作第二个 Word 文档,在步骤 2 到 5 中提到.

A bare example of a custom ribbon and associated VBA follows. Put these in the customUI.xml and VBA of a Word document and use this as the second Word document, mentioned in steps 2 to 5.

将下面的功能区和 VBA 放入 Excel 电子表格,然后执行上面的步骤 1 到 5,除了使用 Excel 电子表格而不是 Word 文档.到达第 5 步时,功能区看起来不错,与 Word 不同.

Put the ribbon and VBA below into an Excel spreadsheet then run through steps 1 to 5 above, except using Excel spreadsheets instead of Word documents. Upon reaching step 5, the ribbon seems fine, unlike in Word.

customUI.xml:

customUI.xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="modRibbon.CustomUI_OnLoad">
    <ribbon>
        <tabs>
            <tab id="tabCustom" label="Custom" insertBeforeMso="TabHome">
                <group id="grpCustom1" imageMso="EditDocument" label="Custom group 1">
                    <button id="btnA" size="large" label="Aa" imageMso="EditDocument" onAction="modRibbon.btn1A_OnAction" screentip="Aa" supertip="A button."/>
                </group>
                <group id="grpCustom2" imageMso="EditBusinessCard" label="Custom group 2">
                    <button id="btnB" size="large" label="Bb" imageMso="EditBusinessCard" onAction="modRibbon.btn2B_OnAction" screentip="Bb" supertip="Another button."/>
                </group>
            </tab>
        </tabs>
    </ribbon>
</customUI>

modRibbon VBA 模块:

modRibbon VBA module:

'Callback for customUI.onLoad
Sub CustomUI_OnLoad(ribbon As IRibbonUI)
End Sub

'Callback for btnA_onAction
Sub btn1A_OnAction(control As IRibbonControl)
End Sub

'Callback for btnB_onAction
Sub btn2B_OnAction(control As IRibbonControl)
End Sub

推荐答案

我想出了一个解决方案,目前为止非常可靠,通过在 ThisDocument 中添加以下内容:

I've come up with a solution, which has been very reliable thus far, by adding the following to ThisDocument:

Private Sub Document_Open()

Application.OnTime Now, "modRibbon.ReloadRibbon"

End Sub

并将以下内容添加到 modRibbon VBA 模块(在 OP 中):

and adding the following to the modRibbon VBA module (in OP):

Sub ReloadRibbon()

With Application.CommandBars
    .Add "barRibbonRefresher", msoBarTop, False, True 'Adds a dummy bar
    .Item("barRibbonRefresher").Delete 'Deletes the dummy bar above, which appears to force the custom UI, including the custom ribbon, to (re)load
End With

End Sub

这个解决方案:

  • 修复了我在 OP 中概述的问题;因为
  • 它允许用户通过 VBA 随心所欲地重新加载功能区;和
  • 在以这种方式重新加载功能区后,回调会继续正常工作.

需要注意的是:

  • 修复在删除虚拟栏时生效,而不是在添加时生效;
  • 仅仅在 Document_Open() 中粘贴 With 块是不够的;OnTime 必须使用;
  • OnLoad 回调在功能区重新加载时运行,与打开文档时完全相同.
  • the fix kicks in when deleting the dummy bar, not when adding it;
  • simply sticking the With block in Document_Open() won't suffice; OnTime must be used;
  • the OnLoad callback runs when the ribbon reloads, exactly as it does when opening the document.

我认为 CommandBars 有一些特别之处,尤其是 .Delete 方法,它使功能区(返回)栩栩如生,这有点讽刺鉴于功能区应该替换 CommandBars,不要依赖它们来使技巧正常运行.

I assume there is something special about CommandBars, and in particular the .Delete method, which shocks the ribbon (back) into life, which would be a tad ironic given that the ribbon is supposed to replace CommandBars, not be dependent on them for tricks to function properly.

旁注:这可能还提供了一种在其指针丢失时恢复功能区的更简单方法,当 VBA 在执行功能区方法时遇到错误时,这种情况相当常见.当前解决方案(也适用于 Word)涉及将指针存储在某处(例如在 ThisDocument.Variables 中),然后通过 CopyMemory 恢复它.上述解决方案可能能够简单地重新创建色带,从而避免任何此类错误.

Side note: This could also provide a simpler way of restoring the ribbon when its pointer is lost, a fairly common occurrence when VBA encounters errors while executing ribbon methods. A current solution (which also applies to Word) involves storing the pointer somewhere (such as in ThisDocument.Variables) then restoring it via CopyMemory. The solution above may be able to simply create the ribbon anew and thus dispense with any such error.

这篇关于使用自定义功能区关闭并重新打开文档后,Word 会话功能区会发生什么情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆