4

ワークブックを開くと一度インスタンス化されるクラスを含むカスタム Excel リボンと Excel アドインがあります。クラスのいくつかの属性に基づいて、カスタム リボン (すべて同じタブ内) から特定のボタンを非表示にする必要があります。

私のカスタム リボンは次のとおりです。

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="loadCustom">
<ribbon>
<tabs>
<tab id="tab1" label="customTab" getVisible="GetVisible" tag="myTab">
<group id="grp1" label="Group1" imageMso="ViewFullScreenView" getVisible="GetVisible">
    <button id="Bt1" size="large" label="Button1" imageMso="AccessListIssues" onAction="runBt1" visible="true"/>
    <button id="Bt2" size="large" label="Button2" imageMso="AccessListTasks" onAction="runBt2" visible="true"/>
    <button id="Bt3" size="large" label="Button3" imageMso="ControlLayoutStacked" onAction="runBt3" visible="true"/>
    <button id="Bt4" size="large" label="Button4" imageMso="ControlLayoutTabular" onAction="runBt4" visible="true"/>

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

次に、モジュールに次の VBA マクロを配置して、カスタム リボンをロードしたり無効にしたりします。

Public Sub loadCustom(ribbon As IRibbonUI)

    Set RibUI = ribbon

    If workbookTitle = "myWorkbook" Then
        MyTag = "show"
    Else
        MyTag = False
        RefreshRibbon MyTag
    End If

End Sub

Sub GetVisible(control As IRibbonControl, ByRef visible)

    If MyTag = "show" Then
        visible = True
    Else
        If control.Tag Like MyTag Then
            visible = True
         Else
            visible = False
        End If
    End If
 End Sub

Sub RefreshRibbon(Tag As String)
    MyTag = Tag
    If RibUI Is Nothing Then
        MsgBox "Error, Save/Restart your workbook"
    Else
        RibUI.Invalidate
    End If
End Sub

リボンをロードする必要がある特定のワークブックには、クラス モジュール クラスが各ボタンの値を読み取り、表示するかどうかを決定する非表示のシートがあります。この値を読み取ったら、個々のボタンを非表示にするにはどうすればよいですか? 私が見つけたすべての例は、タブに対してのみ機能するようです。リボン UI をクラスに渡して、各コントロールをループすることはできますか? これを行う方法を見つけることができませんでした。助けてくれてありがとう!

4

2 に答える 2

6

実行時にリボンをカスタマイズする必要があります。

ここで私の質問 (および回答) を確認してください。私の問題は PPT VBA にありましたが、Excel でテストを行ったところ、問題の解決策は非常に似ているはずです。

trueブール値のorfalsevisible各ボタンのプロパティに割り当てる代わりに、別のコールバックが必要です。これにより、このタブがロードされたときに、プロシージャがクラス オブジェクトがインスタンス化されているかどうかを確認し、必要に応じてtrueorfalseを設定します。

たとえば、私の XML の PPT 部分は次のようになります。

...
<tab idMso="TabView">
               <group idMso="GroupMasterViews" getVisible="VisibleGroup"/>
               <group idMso="GroupPresentationViews" getVisible="VisibleGroup"/>
           </tab>
           ...

そのため、グループのプロパティを使用する代わりに、マクロを呼び出すVisibleカスタム属性を使用します。たとえば、異なるタイプのコントロールで同じコールバック/マクロを使用できなかったため、まったく同じことを行う 2 つのコールバック (と) があるのです。理由はわかりませんが、残念ながら、開発のこの部分は十分に文書化されていないようです。getVisibleVisibleGroupEnabledControlVisibleGroup

コードをチェックして、テスト中にブレークポイントを配置したすべての場所を確認してください。動作させるには、かなりのデバッグを行う必要がありました。すべてのプロシージャにブレークポイントを配置し、コードをステップ実行します。お尻の痛みですが、ここまで来れば、きっとうまくいくと思います。

アップデート

PPT アドインで簡単なテストを行いました。機能的にはこれは似ているので、Excel ですべてを再作成するよりも簡単にテストできます。

私のアドインには、独自のメニュー グループといくつかのカスタム ボタンがあります。関連するボタン行は次のとおりです。

<button id="HelpButton" label="Help" getVisible="EnableControl" onAction="HelpFile" />

参照用の完全な XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
   <customUI onLoad="RibbonOnLoad" xmlns="http://schemas.microsoft.com/office/2009/07/customui">
         <commands>
           <command idMso="ViewSlideSorterView" getEnabled="EnableControl"/>
           <command idMso="ViewNotesPageView" getEnabled="EnableControl"/>
           <command idMso="ViewSlideShowReadingView" getEnabled="EnableControl"/>
           <command idMso="ViewSlideMasterView" getEnabled="EnableControl"/>
           <command idMso="ViewHandoutMasterView" getEnabled="EnableControl"/>
           <command idMso="ViewNotesMasterView" getEnabled="EnableControl"/>
           <command idMso="WindowNew" getEnabled="EnableControl"/>
       </commands>
       <ribbon startFromScratch="false">
           <tabs>
               <tab idMso="TabView">
                   <group idMso="GroupMasterViews" getVisible="VisibleGroup"/>
                   <group idMso="GroupPresentationViews" getVisible="VisibleGroup"/>
               </tab>
                <tab id="TabTiger" label="Chart Builder" insertAfterMso="TabDeveloper">
                    <group id="GroupTigerMain" label="XXXX Chart Builder">
                        <menu id="TigerMenu" image="XXXXLogo" size="large">
                            <button id="LaunchButton" label="Launch Chart Builder" onAction="ShowChart_Form" />
                            <button id="InfoButton" label="Info" onAction="Credit_Inf" />
                            <button id="VersionButton" label="Version" onAction="VersionNum" />
                            <button id="HelpButton" label="Help" getVisible="EnableControl" onAction="HelpFile" />
                        </menu>
                    </group>
                </tab>
           </tabs>
       </ribbon>
   </customUI>

ルーチンは次のEnableControlようになります (意図的にコメントを外してMsgBox、コードを中断して入力できるようにします。デバッグして、適切なブール値がコントロールに渡されていることを確認するためだけにこれを実行することをお勧めします)。

Sub EnableControl(control As IRibbonControl, ByRef returnedVal)
    returnedVal = Not TrapFlag 'TrapFlag = True indicates the Application is running.
    MsgBox ("GetEnabled for " & control.Id)
    'Debug.Print control.Id & " enabled = " & CStr(returnedVal)
    Call RefreshRibbon(control.Id)
End Sub

目的に合わせてを割り当てるロジックを変更する必要がありreturnedValます。しかし、基本的にこのマクロは、ボタンが表示されるたびに起動する必要があるため、私の場合は、それを含むメニューを開くたびに起動します。

returnedValの値がのFalse前にある限りCall RefreshRibbon(control.Id)、手順は機能し、ボタンはメニュー バーに表示されなくなります。

于 2013-08-04T14:27:09.163 に答える