使用自定义功能区关闭并重新打开文档后,Word 会话功能区会发生什么情况? [英] What happens to the Word session ribbon after closing and reopening a document with a custom ribbon?
问题描述
我在 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:
- 我打开任何 Word 文档(现有文档或基于 Normal.dotm 的新空白文档).
- 我打开另一个 Word 文档,它有一个自定义功能区 (customUI.xml);下面的基本示例.
- 我使用自定义功能区关闭文档.
- 我使用自定义功能区重新打开文档.
- 此时自定义功能区有几个问题(没有发生 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 inDocument_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屋!