Office 2010 の新機能である Microsoft Office Backstage ビューは、従来の [ファイル] メニューに代わるものとして、新規ファイルや既存ファイルの表示、ドキュメントのプロパティの定義、情報の共有などの管理タスクを集中的に実行する場所を提供します。Microsoft Office Fluent リボンと同様に、Backstage ビューも、XML を使用して構造、コンポーネント、コールバック プロシージャを定義し、これらのコンポーネントに機能を提供することで、完全に拡張できます。
場合によっては、Backstage ビューのコントロールでユーザーが行ったアクションを基にして、Backstage ビューの他のコントロールの非表示/表示を切り替えることがあります。この記事では、Backstage ビューの group コントロールの表示を動的に変更する方法、およびユーザーのアクションに基づいて個別のコントロールの表示を動的に変更する方法を示します。
この記事では、Trang Luu のカスタム UI エディター (英語)を使用して、カスタム ユーザー インターフェイス (UI) の XML を Microsoft Excel 2010 のブックに簡単に追加できるようにします。この記事で説明する手順を実行するには、Custom UI Editor をダウンロードしてインストールする必要があります。
この記事では、XML と Microsoft Visual Basic for Applications (VBA) コードを組み合わせて使用し、Microsoft Excel 2010 ブック用の Backstage ビューをカスタマイズします。XML では、Backstage ビューに表示するカスタム タブとコントロールを定義します。VBA コードでは、カスタム UI XML で定義されているコールバック プロシージャに必要な機能を提供します。また、以下の手順では、Excel 2010 ブックにカスタマイズされた Backstage ビューを作成する方法も示します。
Backstage ビューを含むサンプルの Excel ブックを作成します。
カスタム UI XML を追加します。
VBA のコールバック コードを追加します。
カスタム Backstage ビュー ページを表示します。
サンプル Excel ブックの作成
この Visual How To では、カスタム UI の XML と VBA コードを Excel 2010 ブックに追加します。
> [!NOTE]
> VBA コードをサポートするには、Excel ブックをマクロが有効なブック (.xlsm) として作成する必要があります。
Microsoft Excel 2010 を起動します。
[ファイル] メニューの [名前を付けて保存] をクリックします。
[名前を付けて保存] ダイアログ ボックスの [ファイルの種類] ドロップダウン リストで、[Excel マクロ有効ブック (*.xlsm)] を選択します。
ドキュメントを C:\Temp\BackstageViewDynamicVisibility.xlsm として保存します。
カスタム UI XML の追加
カスタム UI エディターを使用すると、前の手順で作成したブックにカスタム UI XML を簡単に追加できます。
VBA コールバック コードの追加
VBA コールバック プロシージャにより、前の手順でカスタム UI XML を使用して追加したカスタム Backstage ビュー コンポーネントに機能が追加されます。
Microsoft Excel 2010 を起動します。
[ファイル] タブの [開く] をクリックします。
C:\Temp\BackstageViewDynamicVisibility.xlsm ブックを開きます。
[開発] タブをクリックします。
[Visual Basic] をクリックします。
[挿入] メニューで [標準モジュール] をクリックします。
[Module1] を選択し、そのファイル内に次の VBA コードをコピーします。
'Reference to the ribbon for refreshing the UI.
Public processRibbon As IRibbonUI
'Variables that track the group that is displayed.
Public engineeringGroupVisible As Boolean
Public marketingGroupVisible As Boolean
'Variables that track the completed tasks.
Public taskOneComplete As Boolean
Public taskTwoComplete As Boolean
Public taskThreeComplete As Boolean
Public taskFourComplete As Boolean
'Callback for customUI.onLoad.
Sub onLoad(ribbon As IRibbonUI)
'Store a reference to the ribbon for refreshing the UI.
Set processRibbon = ribbon
'Initialize to display the Engineering Group first.
engineeringGroupVisible = True
End Sub
'Visibility for the Engineering Group group control.
Sub GetEngineeringGroupVisibility(control As IRibbonControl, _
ByRef returnedVal)
returnedVal = engineeringGroupVisible
End Sub
'Visibility for the Marketing Group group control.
Sub GetMarketingGroupVisibility(control As IRibbonControl, _
ByRef returnedVal)
returnedVal = marketingGroupVisible
End Sub
'Called when the Switch Groups button is clicked.
'The variables tracking the visible group are swapped
' to switch the display between the two groups.
Sub SwitchGroups(control As IRibbonControl)
engineeringGroupVisible = Not engineeringGroupVisible
marketingGroupVisible = Not engineeringGroupVisible
'Invalidate resets the UI. This causes all controls
' to redisplay and execute all relevant callbacks.
processRibbon.Invalidate
End Sub
'Label to display for the Switch Groups button.
'Text returned is based on the current group that is displayed.
Sub GetSwitchGroupsLabel(control As IRibbonControl, ByRef returnedVal)
If (engineeringGroupVisible) Then
returnedVal = "Switch to Marketing Group"
Else
returnedVal = "Switch to Engineering Group"
End If
End Sub
'Returns the text to display for each Specification Detail editBox.
Sub GetSpecDetailText(control As IRibbonControl, ByRef returnedVal)
Select Case control.ID
Case "specTitle"
returnedVal = "Flexible Bracket"
Case "specDesigner"
returnedVal = "Andrew Fuller"
Case "specEngineer"
returnedVal = "Nancy Davolio"
Case "specTeam"
returnedVal = "Design"
Case "specCost"
returnedVal = "$896,210"
End Select
End Sub
'Returns the text to display for each Marketing editbox.
Sub GetMarketingDetail(control As IRibbonControl, ByRef returnedVal)
Select Case control.ID
Case "marketingManager"
returnedVal = "Janet Leverling"
Case "marketingBudget"
returnedVal = "$144,078"
Case "marketingEndDate"
returnedVal = Date + 20
End Select
End Sub
'Returns the text to display for each Engineering editbox.
Sub GetEngineeringDetail(control As IRibbonControl, ByRef returnedVal)
Select Case control.ID
Case "engineeringManager"
returnedVal = "Robert Jones"
Case "engineeringBudget"
returnedVal = "$197,955"
Case "engineeringEndDate"
returnedVal = Date + 10
End Select
End Sub
'Visibility for the second task category.
'The second task category does not display until tasks in the
' first task category are marked complete.
Sub GetCalculateCostsVisibility(control As IRibbonControl, _
ByRef returnedVal)
If (taskOneComplete And taskTwoComplete) Then
returnedVal = True
Else
returnedVal = False
End If
End Sub
'Visibility for the task complete controls.
'The task complete controls do not display until all tasks
' are marked complete.
Sub GetTasksCompleteVisibility(control As IRibbonControl, _
ByRef returnedVal)
If (taskOneComplete And taskTwoComplete _
And taskThreeComplete And taskFourComplete) Then
returnedVal = True
Else
returnedVal = False
End If
End Sub
'Called when a task is clicked.
'Marks the task as complete and then calls the InvalidateControl method to
' redisplay only the controls impacted by the change in status.
Sub SetTaskComplete(control As IRibbonControl)
Select Case control.ID
Case "defineScope"
taskOneComplete = True
'Redisplay the second category control
processRibbon.InvalidateControl("calculateCostsCategory")
Case "assignTasks"
taskTwoComplete = True
'Redisplay the second category control
processRibbon.InvalidateControl("calculateCostsCategory")
Case "calcManHours"
taskThreeComplete = True
'Redisplay the task complete controls
processRibbon.InvalidateControl("tasksCompleteImage")
processRibbon.InvalidateControl("tasksCompleteLabel")
Case "calcOverheadCosts"
taskFourComplete = True
'Redisplay the task complete controls
processRibbon.InvalidateControl("tasksCompleteImage")
processRibbon.InvalidateControl("tasksCompleteLabel")
End Select
End Sub
[ファイル] メニューで [保存] をクリックします。
Visual Basic for Applications エディターを閉じ、ブックに戻ります。
カスタム Backstage ビュー ページを表示する
定義したカスタム Backstage ビュー ページを表示するには、[ファイル] タブを選択して Backstage ビューを表示します。これは新しい Backstage ビューです。Backstage ビューを表示した後、組み込みの [情報] タブにある.[Dynamic Visibility] タブを選択します。[Dynamic Visibility] タブを選択すると、前の手順で定義したカスタム Backstage ビュー ページが表示されます。
図 1. カスタム Backstage ビュー ページ
この Office 2010 Backstage ビューを拡張してカスタム ページやカスタム コントロールを含めるには、カスタム UI XML を Office ドキュメントに追加すると共に、カスタム UI XML で指定されたコールバック用の機能を実現する VBA コードを追加する必要があります。
サンプル コードでは、Backstage ビューの他のコントロールを使用して行われたアクションに基づいて、Backstage ビュー グループ コントロールの表示または個別のコントロールの表示を動的に変更する方法が示されています。
カスタム UI を初期化する
Backstage ビュー コントロールの再表示が必要な変更が、コールバック プロシージャによって行われることがあります。Backstage ビューのコントロールを再表示するには、RibbonUI オブジェクトの Invalidate メソッドまたは InvalidateControl メソッドを呼び出します。
次のコード例では、カスタム UI が読み込まれるときに RibbonUI コントロールへの参照を保存する方法を示します。customUI エレメントには onLoad 属性が含まれます。この場合、属性では OnLoad コールバックが指定されています。OnLoad コールバックは、RibbonUI オブジェクトに対する参照を保存します。RibbonUI オブジェクトは、Backstage ビュー コントロールを再表示するためにコールバックで使用されます。onLoad コールバックはコードで使用される変数の初期化も行います。
<!-- customUI is the root tag of all Fluent UI customizations. -->
<customUI xmlns="https://schemas.microsoft.com/office/2009/07/customui"
onLoad="OnLoad">
'Reference to the ribbon for refreshing the UI.
Public processRibbon As IRibbonUI
'Variables that track the group that is displayed.
Public engineeringGroupVisible As Boolean
Public marketingGroupVisible As Boolean
'Variables that track the completed tasks.
Public taskOneComplete As Boolean
Public taskTwoComplete As Boolean
Public taskThreeComplete As Boolean
Public taskFourComplete As Boolean
'Callback for customUI.onLoad.
Sub onLoad(ribbon As IRibbonUI)
'Store a reference to the ribbon for refreshing the UI.
Set processRibbon = ribbon
'Initialize to display the Engineering Group first.
engineeringGroupVisible = True
End Sub
グループ コントロールの表示を動的に変更する
ユーザーが他のコントロールを使用して行ったアクションに基づいて、Backstage ビューの group コントロールを表示することが必要な場合があります。この記事では、[Specification Detail] の [Groups] メニューで行われた選択に基づいて、[Engineering Group] グループと [Marketing Group] グループの表示を切り替える方法を説明します。
次のカスタム UI XML の例は、2 つのグループの表示を動的に切り替えるようコールバックに指定する方法を示しています。[Groups] ボタンで指定されている onAction コールバックが、[Engineering Group] コントロールと [Marketing Group] コントロールを切り替えます。[Marketing Group] コントロールと [Engineering Group] コントロールでは、getVisibility コールバックが指定されています。これらのコールバックが、そのグループを表示するか非表示にするかを決定します。
<primaryItem>
<menu id="switchMenu" label="Groups"
imageMso="ControlLayoutStacked" >
<menuGroup id="menuGroup">
<!-- The onAction callback switches between
displaying the Marketing Group or the Engineering
Group below. -->
<button id="switchGroups"
getLabel="GetSwitchGroupsLabel"
onAction="SwitchGroups"/>
</menuGroup>
</menu>
</primaryItem>
...
<!-- The getVisible callback determines if the
Marketing Group should display based on the current
switchGroups button selection. -->
<group id="marketingGroupDetails" label="Marketing Group"
getVisible="GetMarketingGroupVisibility">
...
</group>
<!-- The getVisible callback determines if the
Engineering Group should display based on the
current switchGroups button selection. -->
<group id="engineeringGroupDetails" label="Engineering Group"
getVisible="GetEngineeringGroupVisibility" >
...
</group>
次のコード例では、[Specification Detail] の [Groups] メニューの onAction コールバック SwitchGroups が、[Engineering Group] コントロールと [Marketing Group] コントロールの表示を切り替える方法を示します。SwitchGroups コールバックは、group コントロールを表示する必要があるかどうかを決定する engineeringGroupVisible 変数と marketingGroupVisible 変数の Boolean 値を逆に設定します。変数が変更された後で、RibbonUI オブジェクトの Invalidate メソッドが呼び出されて、Backstage ビュー コントロールを再表示します。Invalidate メソッドが呼び出されると、[Engineering Group] コントロールと [Marketing Group] コントロールの getVisible コールバックが再実行されて、表示されるグループが切り替わります。
'Called when the Switch Groups button is clicked.
'The variables tracking which group is visible are swapped
' to switch the display between the two groups.
Sub SwitchGroups(control As IRibbonControl)
engineeringGroupVisible = Not engineeringGroupVisible
marketingGroupVisible = Not engineeringGroupVisible
'The Invalidate method resets the UI causing all controls
' to redisplay and executing all relevant callbacks.
processRibbon.Invalidate
End Sub
次のコード例では、[Engineering Group] コントロールの GetVisible コールバックと GetEngineeringGroupVisibility コールバック、および [Marketing Group] コントロールの getVisible コールバックと GetMarketingGroupVisibilty コールバックが、グループの表示を制御する方法を示します。どちらのコールバックも、グループを表示する必要があるかどうかを追跡する変数の Boolean 値を返すことで動作します。
'Visibility for the Engineering Group control.
Sub GetEngineeringGroupVisibility(control As IRibbonControl, _
ByRef returnedVal)
returnedVal = engineeringGroupVisible
End Sub
'Visibility for the Marketing Group control.
Sub GetMarketingGroupVisibility(control As IRibbonControl, _
ByRef returnedVal)
returnedVal = marketingGroupVisible
End Sub
個別のコントロールの表示を動的に変更する
ユーザーが他のコントロールを使用して行ったアクションに基づいて、個別の Backstage ビュー コントロールを表示することが必要な場合があります。この記事では、作業範囲を定義するためのタスクの初期セットを表示します。初期タスクが完了とマークされた後、第 2 のタスク セットがコスト計算用に表示されます。すべてのタスクが完了とマークされると、すべてのタスクが完了したことを示すイメージとラベルが表示されます。
次のカスタム UI XML の例では、他のコントロールでのユーザー アクションに基づいて個別のコントロールを動的に表示するようコールバックに指定する方法を示します。category の [Calculate Costs] タスクの getVisible コールバックは、[Define Work Scope] の category コントロール タスクが完了とマークされた後でのみタスクを表示するように指定されます。タスク完了イメージおよびタスク完了ラベルのコントロールは、getVisible コールバックを、すべてのタスクが完了した後でのみコントロールを表示するように設定します。各 task コントロールは、タスクを完了としてマークするように onAction コールバックを設定します。
<taskGroup id="bidProcessTaskGroup"
label="Contract Bid Process Checklist" >
<!-- The first task category always displays -->
<!-- The onAction callback marks tasks as
completed when the task is clicked. -->
<category id="defineWorkScopeCategory"
label="Define work and tasks - Complete tasks in order.">
<task id="defineScope" label="Define the Scope of Work."
imageMso="_1" onAction="SetTaskComplete"/>
<task id="assignTasks" label="Assign the Tasks"
imageMso="_2" onAction="SetTaskComplete"/>
</category>
<!-- The getVisible callback only displays the
second task category after the tasks in the first
category are complete. -->
<!-- The onAction callback marks tasks as
complete when the task is clicked -->
<category id="calculateCostsCategory"
label="Calculate costs - Complete tasks in order."
getVisible="GetCalculateCostsVisibility" >
<task id="calcManHours" label="Calculate Total Man-Hours"
imageMso="_3" onAction="SetTaskComplete"/>
<task id="calcOverheadCosts" label="Determine Overhead Costs"
imageMso="_4" onAction="SetTaskComplete"/>
</category>
</taskGroup>
<group id="tasksCompleteGroup" >
<topItems>
<layoutContainer id="tasksCompleteLayout"
layoutChildren="horizontal" >
<!-- The getVisible callback only displays
this set of individual controls after all tasks
are complete. -->
<imageControl id="tasksCompleteImage"
imageMso="AcceptInvitation"
getVisible="GetTasksCompleteVisibility"/>
<labelControl id="tasksCompleteLabel"
label="The proposal is ready for review."
getVisible="GetTasksCompleteVisibility" />
</layoutContainer>
</topItems>
</group> <!-- The getStyle callback and getHelperText callback
dynamically set the Open Design Issues Group style
and text based on if there are any open issues. -->
<group id="openDesignIssuesGroup" label="Open Design Issues"
getStyle="GetIssuesStyle"
getHelperText="GetIssuesHelperText">
<topItems>
<!-- The layoutChildren attribute lays out
each set of issues controls horizontally. -->
<!-- The onAction callback marks issues as resolved
when the "Click to Resolve" button is clicked. -->
<!-- The getVisible callback hides the
issues after they are marked as resolved. -->
<layoutContainer id="delayIssueContainer"
layoutChildren="horizontal">
<button id="resolveDelayIssue" label="Click to Resolve"
imageMso="AcceptInvitation" onAction="ResolveIssue"
getVisible="getIssueVisibility" />
<labelControl id="delayIssue"
label="Issue: Delay in Material Delivery"
getVisible="getIssueVisibility" />
</layoutContainer>
<layoutContainer id="equipmentIssueContainer"
layoutChildren="horizontal">
<button id="resolveEquipmentIssue" label="Click to Resolve"
imageMso="AcceptInvitation" onAction="ResolveIssue"
getVisible="getIssueVisibility" />
<labelControl id="equipmentIssue"
label="Issue: Equipment Down Time"
getVisible="getIssueVisibility" />
</layoutContainer>
<layoutContainer id="laborIssueContainer"
layoutChildren="horizontal">
<button id="resolveLaborIssue" label="Click to Resolve"
imageMso="AcceptInvitation" onAction="ResolveIssue"
getVisible="getIssueVisibility" />
<labelControl id="laborIssue"
label="Issue: Labor Dispute"
getVisible="getIssueVisibility" />
</layoutContainer>
</topItems>
</group>
次のコード例では、[Calculate Costs] タスクの category コントロールの getVisible コールバックと GetCalculateCostsVisibility コールバックが、[Calculate Costs] カテゴリの表示を制御する方法を示します。初期状態では、完了しているタスクはなく、GetCalculateCostsVisibility メソッドは False を返して、[Calculate Costs] タスクの category コントロールを非表示にします。[Define Work Scope] カテゴリのすべてのタスクが完了すると、GetCalculateCostsVisibility メソッドは True を返し、[Calculate Costs] タスク カテゴリを表示します。
'Visibility for the second task category.
'The second task category does not display until tasks in the
' first task category are marked as complete.
Sub GetCalculateCostsVisibility(control As IRibbonControl, _
ByRef returnedVal)
If (taskOneComplete And taskTwoComplete) Then
returnedVal = True
Else
returnedVal = False
End If
End Sub
次のコード例では、imageControl コントロールおよび labelControl コントロールの getVisibleコールバックである GetTasksCompleteVisibility メソッドが、すべてのタスクが完了とマークされるまでタスク完了コントロールを非表示にする方法を示します。初期状態では完了しているタスクはなく、GetTasksCompleteVisibility メソッドはタスク完了コントロールを非表示にするために False を返します。[Define Work Scope] カテゴリと [Calculate Costs] カテゴリのすべてのタスクが完了とマークされた後、GetTasksCompleteVisibility メソッドはタスク完了コントロールを表示するために True を返します。
'Visibility for the task complete controls.
'The task complete controls do not display until all tasks '
' are marked as complete.
Sub GetTasksCompleteVisibility(control As IRibbonControl, _
ByRef returnedVal)
If (taskOneComplete And taskTwoComplete _
And taskThreeComplete And taskFourComplete) Then
returnedVal = True
Else
returnedVal = False
End If
End Sub
次のコード フラグメントでは、task コントロールの onAction コールバックである SetTaskComplete が、タスクを完了としてマークする方法を示します。SetTaskComplete コールバックはクリックされたタスクを識別し、適切なタスク完了変数を True に設定します。タスクが完了とマークサレタの値、RibbonUI オブジェクトの InvalidateControl メソッドが呼び出されて、コールバックの再表示と再実行を、変更によって影響を受けた Backstage ビュー コントロールだけに制限します。[Define Work Scope] カテゴリのタスクは [Calculate Costs] カテゴリのコントロールの表示だけに影響を与えることができるので、[Calculate Costs] コントロールに対する category コントロールのコントロール ID calculateCostsCategory は、これらのタスクが完了としてマークされると InvalidateControl メソッドに渡されます。[Calculate Costs] カテゴリのタスクはタスクが完了した imageControl オブジェクトおよび labelControl オブジェクトの表示にのみ影響を与えることができるので、タスクが完了としてマークされると、InvalidateControl メソッドがコントロールごとに呼び出されます。
'Called when a task is clicked.
'Marks the task as complete and then calls the InvalidateControl method to
' redisplay only the controls impacted by the change in status.
Sub SetTaskComplete(control As IRibbonControl)
Select Case control.ID
Case "defineScope"
taskOneComplete = True
'Redisplay the second category control.
processRibbon.InvalidateControl ("calculateCostsCategory")
Case "assignTasks"
taskTwoComplete = True
'Redisplay the second category control.
processRibbon.InvalidateControl ("calculateCostsCategory")
Case "calcManHours"
taskThreeComplete = True
'Redisplay the task complete controls.
processRibbon.InvalidateControl ("tasksCompleteImage")
processRibbon.InvalidateControl ("tasksCompleteLabel")
Case "calcOverheadCosts"
taskFourComplete = True
'Redisplay the task complete controls.
processRibbon.InvalidateControl ("tasksCompleteImage")
processRibbon.InvalidateControl ("tasksCompleteLabel")
End Select
End Sub
'Called when a resolve issue button is clicked.
'Sets the button's corresponding issue as resolved.
Sub ResolveIssue(control As IRibbonControl)
Select Case control.ID
Case "resolveDelayIssue"
delayIssueResolved = True
Case "resolveEquipmentIssue"
equipmentIssueResolved = True
Case "resolveLaborIssue"
laborIssueResolved = True
End Select
'Invalidate method is called to reset the UI causing all controls
' to redisplay and executing all relevant callbacks.
processRibbon.Invalidate
End Sub
|