Product Documentation

グループ化Forward Pathレポート

Jul 08, 2016

このトピックでは、アプリケーションのグループ化に使用できるForward Pathの高度な機能の概要について説明します。(特定のプラットフォームに対する展開の適切性など)スクリプトに定義するカテゴリ別、またはアプリケーションが属するAppDNAアプリケーショングループ別にアプリケーションをグループ化できます。 アプリケーションの値をグループレベルで集計できます。たとえば、各グループの小計を作成し、レポートレベルで合計を作成します。 これは、たとえば、アプリケーショングループが事業部門を表す場合、事業部門別にアプリケーションをグループ化し、各グループの小計を表示するForward Pathレポートを作成できるということを意味します。

概要

以下の図は、Windows 7およびApp-VレポートのRAG状態に基づいてアプリケーションをグループ化する、Forward Pathレポートの抜粋です。 グループごとに、そのグループ内のアプリケーション数と共に修復費用が表示されます。 各グループを展開して含まれるアプリケーションを表示できます。 最上位の合計行にはレポート全体の合計が表示されます。

このレポートを生成するForward Pathシナリオを、以下の例で構築します。 例をできるだけシンプルにするために、各アプリケーションの修復費用はハードコードしたものを使用します。 実環境では、アプリケーションの複雑度と必要な修復に基づいてこの値を計算することになるでしょう。 この方法で費用を計算する例などについては、「Forward PathシナリオでのEffort Calculator変数の使用」を参照してください。

シナリオの関数

グループ化Forward Pathレポートのシナリオでは、一般的に、以下のForward Path標準関数を実装します。

  • Initialize() – スクリプトの開始点で、AppDNAによりこの関数が自動的に1回呼び出されます。 通常、この関数は変数を初期化します。
  • ForwardPath() – これはすべてのForward Pathシナリオに実装が必要な標準関数です。 レポートの実行時に選択される各アプリケーションに対して、AppDNAによりこの関数が1回呼び出されます。 グループ化Forward Pathレポートでは、アプリケーションを分類するカテゴリ(レポートグループ)がこの関数によって作成されます。 レポートグループはコード内のロジックによって、またはアプリケーションが既に属しているアプリケーショングループに基づいて作成できます。
  • ProcessGroups()ForwardPath() 関数によって生成される各レポートグループで呼び出します。 この関数は、グループレベルのレポート列とその値を定義します。
  • GetGroupColumnSummary()ProcessGroups() 関数によって生成される各レポートグループで呼び出します。 通常、この関数はレポートレベルの合計を定義します。
  • OnProcessingComplete() OnProcessingComplete() – これはオプションの関数で、ほかの処理がすべて完了するとAppDNAにより呼び出されます。 この関数を使用して、レポートが表示される前の最終処理を実行できます。

以下の図は、レポート実行時にどのように関数が呼び出されるかを示しています。 図の後で、高度な機能それぞれの仕様と、前の「概要」に示したレポートの作成例について説明します。

注:このトピックの例の一部では、長い行を複数行に分割するためにアンダースコア(_)表記を使用します。 これにより、例のコードスニペットがPDF上で正しく表示されます。 この表記について詳しくは、MSDNライブラリを参照してください。

Initialize()

この関数をシナリオに指定すると、スクリプトの開始点で、AppDNAにより Initialize() 関数が自動的に1回呼び出されます。 デバイスが Initialize() 関数には以下のシグネチャが必要です。

Public Overrides Sub Initialize()    ' Enter your code here. End Sub

この例では Initialize() 関数を使用して、アプリケーションをグループレベルで集計するための、アプリケーション値を格納する変数を初期化します。 ただし、シナリオを通して使用する変数を初めに宣言する必要があります。 これらの変数は複数の関数で使用するため、以下のようにスクリプトの開始点で( Initialize() 関数の前に)定義します。

' Declare a Dictionary variable to store the remediation ' costs for each application in the group. Private Dim costs As Dictionary(Of String, List(Of Integer)) _    = New Dictionary(Of String, List(Of Integer))  ' Declare string variables that store the names of the  ' report groups. Private Dim win7group As String = "Windows 7" Private Dim appvgroup As String = "App-V" Private Dim othergroup As String = "Retire"

この例で は、 costsと呼ばれるDictionary変数を宣言しました。 この.NETの標準クラスのドキュメントについては、MSDNライブラリを参照してください。 ディクショナリ変数はキーと値のコレクションを格納できます。 この例で、キーは(レポートグループ名の格納に使用する)文字列で、値は(レポートグループに含まれるすべてのアプリケーションの修復費用の格納に使用する)整数の List です。 Listクラスのドキュメントについては、MSDNライブラリを参照してください。 List クラス

ディクショナリと同様に、これから作成するレポートグループの名前を格納する、3つの文字列値を宣言しました。

これで、Initialize()関数を実装する準備ができました。 Initialize() 関数によって生成される各レポートグループで呼び出します。 次のようになります。

Public Overrides Sub Initialize()           costs.Add(win7group, New List(Of Integer))    costs.Add(appvgroup, New List(Of Integer))    costs.Add(othergroup, New List(Of Integer)) End Sub

この例では、costsディクショナリ変数に対し、3つのレポートグループのそれぞれについて1つの項目を追加しました。 レポートグループの名前を格納するために前に宣言した3つの文字列変数を使用して、項目キーを指定しました。

ForwardPath()

デバイスが ForwardPath() 関数は、すべてのForward Pathシナリオに実装が必要な標準関数です。 デバイスが ForwardPath() 関数には以下のシグネチャが必要です。

Public Function ForwardPath(ByVal currentApplication _    As Application) As Output       ' Enter your code here. End Function

この例では、アプリケーションを3つのレポートグループに分類します。Windows 7のRAG状態が緑のアプリケーションは「Windows 7」レポートグループへ、App-VのRAG状態が緑のアプリケーションは「App-V」レポートグループへ、残りのアプリケーションは「Retire」レポートグループへ追加します。 各アプリケーションについて、ランダムなハードコードされた数字をディクショナリに追加します。これはアプリケーションの修復費用を表します。

Public Function ForwardPath(ByVal currentApplication _    As Application) As Output      Dim result As New Output()     ' Is the application green for Windows 7?    If (currentApplication.Modules.Windows7.RAG = RAG.Green) _      Then       result.Outcome = "Windows 7 OK"       result.RAG = RAG.Green       result.Cost = 33              ' Add the application to the "Windows 7" group.       result.ReportGroups.Add(win7group)        ' Add the remediation cost to the dictionary variable.       costs.Item(win7group).Add(33)    Else        ' Is the application green for App-V?       If (currentApplication.Modules.AppV.RAG = RAG.Green) Then          result.Outcome = "App-V OK"          result.RAG = RAG.Green          result.Cost = 170                 ' Add the application to the "App-V" group.          result.ReportGroups.Add(appvgroup)           ' Add the remediation cost to the dictionary variable.          costs.Item(appvgroup).Add(170)       Else           ' The application is not green for Windows 7 or App-V.          result.Outcome = "Not suitable for migration."          result.RAG = RAG.Red          result.Cost = 713           ' Add the application to the "Retire" group.          result.ReportGroups.Add(othergroup)           ' Add the replacement cost to the dictionary variable.          costs.Item(othergroup).Add(713)       End If     End If     result.Display.SourcePath.Visible = false     ForwardPath = result  End Function

Windows 7およびApp-VレポートのRAG状態に基づき、アプリケーションを If ... Then ... Else 文を使用して3つのレポートグループに分割したことに注目してください。 レポートグループは、アプリケーションが属するアプリケーショングループに基づいて作成することもできます。 このトピックの後の例で、その方法について説明します。

注:同じアプリケーションを複数のグループに追加することができます。 これを行うと、レポートを実行したときにアプリケーションを追加した各グループ内にそのアプリケーションが表示され、その値が各グループの合計に集計されます。 この結果、アプリケーションの値がレポートの合計に複数回追加される可能性があります。 レポートによっては、誤解を招く可能性があります。 アプリケーションを意図せずに複数のグループに追加しないようにするかどうかは、スクリプト作成者次第です。

ProcessGroups()

この関数をシナリオに指定すると、AppDNAは ProcessGroups() 関数を ForwardPath() 関数によって生成される各レポートグループで呼び出します。 通常、 ProcessGroups() 関数を使用してForward Pathレポートにグループレベルで表示される列を定義します。

デバイスが ProcessGroups() 関数には以下のシグネチャが必要です。

Public Overrides Sub ProcessGroup(group As _    ForwardPathReportGroup)       ' Enter your code here.  End Sub

ForwardPathReportGroup オブジェクトがこの関数に渡されることに注目してください。 これは現在のレポートグループを表します。 ここでは2つのプロパティがあります。 名前(グループの名前を保存する文字列)と CustomColumns(文字列のディクショナリ)です。 Citrix Web Interface管理コンソールの CustomColumns プロパティを使用して、グループレベルで表示される列の名前とその値を指定します。

例:

Public Overrides Sub ProcessGroup(group As _    ForwardPathReportGroup)     ' 1. Define a report group column to show the total     ' cost for the applications in the group and format it    ' as currency.    group.Columns.Item("Cost").Value = _       costs.Item(group.Name).Sum()    group.Columns.Item("Cost").Format = "{0:C}"    group.Columns.Item("Cost").Culture = "en-US"      ' 2. Define a report group column to show the number of    ' applications in the group.    group.Columns.Item("Count").Value = _       costs.Item(group.Name).Count     ' 3. Define a report group column that has a link to    ' further information.    group.Columns.Item("Link").Value = _    "More information"  End Sub

3つの列を定義したことに注目してください。

  1. これによりCost列が定義されます。この列に、各グループのアプリケーションの修復費用の合計が表示されます。 費用合計を取得するために、 List.Sum() メソッドを使用して、costsディクショナリ変数に格納されているグループのすべての費用値を集計します。 デバイスが List クラスにはほかの集計関数もあり、(たとえば)格納されているグループの値の平均、最小、または最大値を取得できます。 Listクラスのドキュメントについては、MSDNライブラリを参照してください。 List クラス

    列の 形式 プロパティを {0:C} (値は通貨であることを指定)に設定したことに注目してください。 また、 Culture プロパティの値を en-US に設定して、通貨記号がアメリカドル記号であることを指定しました。 出力の書式設定について詳しくは、「Forward Pathレポートの並べ替えと形式」を参照してください。

  2. これによりCount列が定義されます。この列に、各グループのアプリケーション数が表示されます。 今回は、 List.Count() メソッドを使用して、costsディクショナリ変数に格納されているグループの(アプリケーションを表す)項目数を取得します。
  3. これによりLink列が定義されます。この列に、ハードコードされたハイパーリンクを定義するHTMLコードが含まれます。 これはHTMLコードを列に含められることを示す、極端に単純化した例です。
注:グループ名を表示する列はAppDNAにより自動的に生成されます。 これはGroup列と呼びます。

GetGroupColumnSummary()

この関数をシナリオに指定すると、ほかの処理がすべて完了するとAppDNAにより GetGroupColumnSummary() 関数が ProcessGroups() 関数で定義した各列で自動的に呼び出され、「Group」列(グループ名を保存します)が自動的に生成されます。 デバイスが GetGroupColumnSummary() 関数には以下のシグネチャが必要です。

Public Overrides Function GetGroupColumnSummary(groupColumnName _    As String) As String       ' Enter your code here. End Function

列名が関数に 文字列 として渡され、関数が文字列を戻すことに注目してください。この文字列は、レポートの合計行の対応する列に挿入されるテキストです。

Citrix Web Interface管理コンソールの GetGroupColumnSummary() 関数を使用して、レポートレベルの値を定義します。 次に例を示します。

Public Overrides Function GetGroupColumnSummary(groupColumnName _    As String) As String     If groupColumnName = "Group" Then        ' Put the text "Total" in the automatically-generated        ' "Group" column.       GetGroupColumnSummary = "Total"     Else If groupColumnName = "Cost" Then        ' Declare a variable to store the total cost.       Dim sum As Decimal = 0        ' Iterate through the costs variable to get the total cost.       For Each key As String In costs.Keys          sum += costs.Item(key).Sum()       Next        ' Format the total as currency.       GetGroupColumnSummary = _          String.Format(New _             System.Globalization.CultureInfo("en-US"), _             "{0:C}", sum)     Else If groupColumnName = "Count" Then        ' Declare a variable to store the overall count.       Dim count As Integer = 0        ' Iterate through the costs variable to get the total        ' count.       For Each key As String In costs.Keys          count += costs.Item(key).count()       Next        GetGroupColumnSummary = String.Format(count)     Else        ' Leave the "Link" column blank.       GetGroupColumnSummary = ""     End If  End Function

ProcessGroups() 関数で定義した各グループ列および自動生成のGroup列に対して、AppDNAによりこの関数が1回呼び出されます。 したがって、 If ... Then ... Else 文を使用して処理中の列がどれかをテストします。 各列に対して実行する処理を以下に示します。

  1. これは自動生成のGroup列です。 この列については、単に「Total」というテキストを生成します。 テキストを タグで囲んだことに注目してください。 これは標準のHTMLタグで、テキストが太字でレンダリングされるべきであることを指定します。 どの列でもHTMLコードを使用できます。
  2. これはCost列です。 レポートの合計を取得するために、作業変数を宣言します。 次に、グローバルなcostsディクショナリ変数のすべての項目を反復処理し、その合計値を作業変数に追加して、その値を戻します。

    戻り値は文字列です。 費用の値を通貨として書式設定するために String.Format() メソッドを使用し、アメリカドルの通貨記号を指定するために CultureInfo クラスを使用しました。 文字列のフォーマットについて詳しくは、MSDNライブラリを参照してください。

  3. Count列については、同様のテクニックを使用してレポートの合計値を生成しました。
  4. Link列は空白のまま残しました。

これで、このトピックの冒頭のForward Pathレポートを生成するために使用したシナリオの、コードの最終部分に到達しました。 このトピックの後で、アプリケーションが属しているAppDNAアプリケーショングループに基づいて、レポートグループを作成する方法について説明します。

OnProcessingComplete()

この関数をシナリオに指定すると、ほかの処理がすべて完了するとAppDNAにより OnProcessingComplete() が自動的に呼び出されます。 この関数を使用して、レポートが表示される前の最終処理を実行できます。

デバイスが OnProcessingComplete() 関数には以下のシグネチャが必要です。

Public Overrides Sub OnProcessingComplete()    ' Enter your code here. End Sub

AppDNAアプリケーショングループによるグループ化

ここでは、アプリケーションが既に属しているアプリケーショングループに従ってアプリケーションをグループ化するように、シナリオを変更します。 グループのメンバーではないアプリケーションがある場合は、「Ungrouped」のカテゴリに表示されます。

シナリオ内では Application.Groups プロパティを使用します。 アプリケーションは複数のグループに属することができます。 前に説明したように、すべてのグループをレポートに追加すると、アプリケーションがその属している各グループの下に表示されます。 したがって、スクリプトの作成方法によっては、アプリケーションの修復費用がレポートの合計に複数回追加される可能性があります。

以下の関数にはそのしくみを説明する詳しいコメントがつけられています。

Public Function ForwardPath(ByVal currentApplication _     As Application) As Output     Dim result As New Output()     If (currentApplication.Modules.Windows7.RAG = RAG.Green) Then       result.Outcome = "Windows 7 OK"       result.RAG = RAG.Green    Else       ' If the RAG for Windows 7 is not green,       ' check if it's green for App-V       If (currentApplication.Modules.AppV.RAG = RAG.Green) Then          result.Outcome = "App-V OK"          result.RAG = RAG.Green       Else          result.Outcome = "Not suitable for migration."          result.RAG = RAG.Red       End If     End If     ' We're temporarily using a hard-coded cost.    result.Cost = 713     ' Iterate through the groups to which the application     ' belongs.    For Each group As String In currentApplication.Groups        ' Add the application to the corresponding report group.       result.ReportGroups.Add(group)        ' Check whether the group has already been added to our       ' global dictionary variable.       If costs.ContainsKey(group) Then           ' Add the application's cost to the global variable.          costs.Item(group).Add(713)       Else           ' Add the group to the global variable and then          ' add the application's cost.          costs.Add(group, New List(Of Integer))          costs.Item(group).Add(713)        End If    Next     ForwardPath = result  End Function  Public Overrides Sub ProcessGroup(group As ForwardPathReportGroup)     If costs.ContainsKey(group.Name) Then       group.Columns.Item("Count").Value = _          costs.Item(group.Name).Count       group.Columns.Item("Cost").Value = _          costs.Item(group.Name).Sum()       group.Columns.Item("Cost").Format = "{0,-10:C}"       group.Columns.Item("Cost").Culture = "en-US"       group.Columns.Item("Link").Value = _       "More information"    End If  End Sub

グループを非表示にする

グループ化レポートを、グループ化なしで表示したい場合があります。 これを行うには、オペレータコンソールの ForwardPathReportSettings.DisplayGroups プロパティを使用します。 このプロパティは、グループ制御のコードをシナリオに追加すると自動的にTrueに設定されます。 ただし、レポート内のグループ表示を隠すように、シナリオ内で明示的にFalseに設定することができます。

デバイスが 設定 オブジェクト( ForwardPathReportSettingsタイプ)は、このシナリオ全体で使用できます。 通常、このプロパティは以下のように Initialize() 関数で設定します。

Settings.DisplayGroups = false

グループ化なしで再表示するには、この行をコメントアウトするだけで済みます。