【问题标题】:Dynamically changes ribbon's button label Excel动态更改功能区按钮标签 Excel
【发布时间】:2016-03-31 14:46:55
【问题描述】:

我正在使用以下 XML 代码为 Excel 加载项创建自定义功能区。

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
    <ribbon startFromScratch="false">
        <tabs>
            <tab id="ComdinheiroTab" label="COMDINHEIRO">
                <group id="ComdinheiroButtons" label="Comdinheiro">

                    <button id="Login" getLabel="getLabelLogin" image="Login" size="large" onAction="OnActionLogin"/>

                </group>
            </tab>
        </tabs>
    </ribbon>
</customUI>

我正在使用以下 VBA 代码为按钮登录设置标签:

Sub getLabelLogin(control As IRibbonControl, ByRef returnedVal)
 if loggedIn = true then
    returnedVal = "Logged"
 else 
    returnedVal = "Disconected"
 end if
End Sub

标签的名称在加载功能区时根据变量 loggedIn 的值成功更改。但是我希望我可以在程序执行期间更改标签的值。是否可以使用 VB 代码调用 getLabel 事件?无论如何要刷新我的功能区,以便再次调用此事件?

【问题讨论】:

    标签: excel xml vba ribbon


    【解决方案1】:

    是的,以后可以运行“get”回调。为此,您需要创建一个模块级或全局级变量来保存“功能区 UI”对象。该对象有两个有用的方法:Invalidate 和 InvalidateControl。第一个触发所有功能区 XML 中的“获取”回调。第二个仅触发指定控件的回调。

    加载功能区时,您的功能区 ui 必须分配给此对象。为了实现这一点,您需要在功能区 XML 的 customUI 标记中添加属性 onLoad,并在您的 VBA 中使用它的回调。

    <customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="ribbonLoaded">
        <ribbon startFromScratch="false">
            <tabs>
                <tab id="ComdinheiroTab" label="COMDINHEIRO">
                    <group id="ComdinheiroButtons" label="Comdinheiro">
    
                        <button id="Login" getLabel="getLabelLogin" image="Login" size="large" onAction="OnActionLogin"/>
    
                    </group>
                </tab>
            </tabs>
        </ribbon>
    </customUI>
    

    在下面的 VBA 示例代码中,UpdateTheLabel 是从问题中提到的“我的程序的执行”中调用的。此过程不需要以任何方式连接到 RibbonXML。

    UpdateTheLabels action,然而,is 连接到功能区:通过调用InvalidateControl 会导致功能区控件(在本例中为“登录”)重新评估其所有动态(“get”)回调,例如getLabelLogin(位于功能区 XML 中)。

    Dim ribbonUI as IRibbonUI
    
    Sub ribbonLoaded(ribbon as IRibbonUI)
      Set ribbonUI = ribbon
    End Sub
    
    Sub UpdateTheLabel
      ribbonUI.InvalidateControl("Login")
    End Sub
    
    Sub getLabelLogin(control As IRibbonControl, ByRef returnedVal)
     if loggedIn = true then
        returnedVal = "Logged"
     else 
        returnedVal = "Disconected"
     end if
    End Sub
    

    只要过程可以访问ribbonUI 对象,调用InvalidateControl 的过程并不重要。

    可以在 MSDN 文章 https://msdn.microsoft.com/en-us/library/aa338202(v=office.12)#OfficeCustomizingRibbonUIforDevelopers_Dynamically 中找到更多信息

    【讨论】:

    • @Ihidan 如果 Cindy 的建议解决了您的问题,您可能希望将其标记为 Answer,以便其他读者(如我自己)可以更好地从中受益。