グループ化されたForward Pathレポート
このトピックでは、スクリプトで定義されたカテゴリ(特定のプラットフォームへの展開への適合性など)またはアプリケーションが属するAppDNAアプリケーショングループによってアプリケーションをグループ化するために使用できる高度なForward Path機能の概要を説明します。アプリケーション値をグループ・レベルで集計できます (たとえば、各グループの小計を作成する場合)。また、レポート・レベルで合計を作成できます。つまり、たとえば、アプリケーショングループが部署を表す場合、アプリケーションを部署別にグループ化し、各部署の小計を表示するForward Pathレポートを作成できます。
概要
次の図は、Windows 7およびApp-VレポートのRAGステータスに基づいてアプリケーションをグループ化した、Forward Pathレポートのスニペットを示しています。グループごとに、修復の総コストと、グループ内のアプリケーションの数が表示されます。各グループを展開して、内部のアプリケーションを表示できます。上部の集計行には、レポート全体の合計が表示されます。
次の例で、このレポートを生成した Forward Path シナリオを構築します。例をできるだけシンプルにするために、アプリケーションごとにハードコードされた修復コストを使用します。実際の環境では、アプリケーションの複雑さと必要な修復に基づいて計算できます。このようにコストを計算する例については、「Forward PathシナリオでのEffort Calculator変数の使用」を参照してください。
シナリオ関数
グループ化されたForward Pathレポートのシナリオは、通常、次の標準Forward Path機能を実装します。
- Initialize() -スクリプトの開始時にこの関数が1回自動的に呼び出されます。通常、この関数は変数を初期化します。
- ForwardPath() — これは、すべてのForward Pathのシナリオで実装する必要がある標準関数です。AppDNAは、レポートの実行時に選択されたアプリケーションごとに、この関数を1回呼び出します。グループ化されたForward Pathレポートでは、この関数により、アプリケーションが配置されるカテゴリ(レポート・グループ)が作成されます。レポートグループは、コード内のロジックによって作成することも、アプリケーションがすでに属しているアプリケーション・グループに基づいて作成することもできます。
- ProcessGroups() -ForwardPath() 関数によって生成されたレポートグループごとに、この関数を1回呼び出します。この関数は、グループ・レベルのレポート・カラムとそれに含まれる値を定義します。
- GetGroupColumnSummary() - ProcessGroups() 関数で定義された列ごとに、この関数が1回呼び出されます。通常、この関数はレポートレベルの合計を定義します。
- OnProcessingComplete() — これはオプションの関数で、残りの処理がすべて完了した後にAppDNAが1回呼び出します。この機能を使用すると、レポートが表示される前に最終処理を実行できます。
次の図は、レポートの実行時にAppDNAがどのように関数を呼び出すかを示しています。この図の後には、各高度な機能の仕様と、上記の「概要」セクションに示したレポートを作成する例が示されています。
注:このトピックの一部の例では、長い行を 2 行以上に分割するためにアンダースコア (_) 表記を使用しています。これは、サンプルコードスニペットが 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"
この例では、コストと呼ばれる辞書変数を宣言しています。この標準.NET クラスのドキュメントについては、MSDN ライブラリを参照してください。辞書変数は、キーと値のコレクションを格納することができます。この例では、キーは文字列(レポートグループ名を格納するために使用する)で、値は整数のリストです(レポートグループ内のすべてのアプリケーションの修復コストを格納するために使用します)。List クラスのドキュメントについては、MSDN ライブラリを参照してください。
辞書だけでなく、我々は我々が作成する3つのレポートグループの名前を格納するために3つの文字列変数を宣言しました。
これで、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
この例では、3 つのレポートグループのそれぞれについて、コストディクショナリ変数に項目を追加するだけです。私たちは、レポートグループの名前を格納するために以前に宣言した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」レポートグループに追加し、残りのアプリケーションを追加します。を「除・売却」レポートグループに追加します。アプリケーションごとに、ランダムなハードコードされた番号をディクショナリに追加して、アプリケーションの修復にかかるコストを表します。
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ステータスに基づいて、アプリケーションを3つのレポートグループに分けるためのステートメントです。レポートグループは、アプリケーションが属するアプリケーショングループに基づいて作成することができます。このトピックの後の例で、その方法を説明します。
注:同じアプリケーションを複数のグループに追加することは可能です。これを行うと、レポートを実行すると、アプリケーションが追加された各グループの下にアプリケーションが表示され、その値が各グループの合計に集計されます。これにより、アプリケーションの値がレポートの合計に複数回加算される可能性があります。報告書によっては、誤解を招く恐れがあります。意図しない限り、アプリケーションが複数のグループに追加されないようにするのは、スクリプトの作成者です。
ProcessGroups()
シナリオで指定されている場合、ForwardPath() 関数によって生成された各レポートグループに対してProcessGroups() 関数が呼び出されます。通常、ProcessGroups() 関数を使用して、Forward Pathレポートのグループ・レベルで表示される列を定義します。
ProcessGroups() 関数には、次のシグネチャが必要です。
Public Overrides Sub ProcessGroup(group As _
ForwardPathReportGroup)
' Enter your code here.
End Sub
ForwardPathReportGroup オブジェクトがこの関数に渡されることに注意してください。これは、現在のレポートグループを表します。このプロパティには、グループの名前を格納する Name と、文字列のディクショナリである CustomColumns という 2 つのプロパティがあります。文字列 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 = _
"<a target=""_blank"" href=""http://www.google.com"">More information</a>"
End Sub
3つの列を定義していることに注意してください。
-
これにより、[Cost] 列が定義されます。この列には、各グループのアプリケーションの修復コストの合計が表示されます。総コストを取得するには、我々は、コスト辞書変数内のグループのために格納されているすべてのコスト値を集約するList.Sum() メソッドを使用しています。List クラスには、グループに格納されている平均、最小値、または最大値(たとえば)を取得するために使用できる他の集計関数があります。List クラスのドキュメントについては、MSDN ライブラリを参照してください。
列の Format プロパティを {0: C}(値が通貨であることを指定)に設定していることに注意してください。また、Culture プロパティを en-US の値に設定して、通貨記号が米ドル記号であることを指定します。出力のフォーマットについては、Forward Pathレポートのソートと書式設定を参照してください。
-
これにより、[Count] 列が定義され、各グループ内のアプリケーション数が表示されます。今回は、List.Count() メソッドを使用して、コストディクショナリ変数にグループのために格納されている(アプリケーションを表す)項目の数を取得します。
-
これは、ハードコードされたハイパーリンクを定義する HTML コードを含む [リンク] 列を定義します。これは、列に HTML コードを含めることができることを示す過度に単純化された例です。
注:グループ名を示す列が自動的に生成されます。これは「グループ」列と呼ばれます。
GetGroupColumnSummary()
シナリオで指定されている場合、AppDNAは、ProcessGroups() 関数で定義された各列に対してGetGroupColumnSummary() 関数と、自動生成された「グループ」列(グループ名を格納する)に対して自動的にGetGroupColumnSummary() 関数が呼び出されます。GetGroupColumnSummary() 関数には、次のシグネチャが必要です。
Public Overrides Function GetGroupColumnSummary(groupColumnName _
As String) As String
' Enter your code here.
End Function
列の名前が文字列として関数に渡され、関数が文字列を返すことに注意してください。文字列は、レポート集計行の対応する列に挿入されるテキストです。
レポートレベルの値を定義するには、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 = "<b>Total</b>"
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
AppDNAは、ProcessGroups() 関数で定義したグループ列と、自動生成された「Group」列ごとに、この関数を1回呼び出します。したがって、我々は、If… その後… Else ステートメントを使用して、どのカラムが処理されているかをテストします。各列に対して何をしているかを見てみましょう。
-
これは、自動生成された [グループ] 列です。 この列では、単に「Total」というテキストを生成します。 テキストが <b></b> タグで囲まれていることに注意してください。 これらは、テキストを太字で表示するように指定する標準の HTML タグです。 どの列でも任意の HTML コードを使用できます。
-
これは [コスト] 列です。レポートの合計を取得するには、作業変数を宣言します。次に、グローバルコストディクショナリ変数のすべての項目を反復処理し、それらの合計値を作業変数に追加し、それを返します。
戻り値は文字列です。私たちは、通貨としてコスト値をフォーマットするString.Format()メソッドを使用しており、我々は、米ドルの通貨記号を指定するためにCultureInfoクラスを使用しました。文字列のフォーマットについては、MSDN ライブラリを参照してください。
-
カウント列については、我々は、レポートの合計値を生成するために、同様の技術を使用しました。
-
「リンク」列は空白のままです。
これにより、このトピックの冒頭に示した Forward Path レポートの生成に使用されたシナリオのコードの最後に表示されます。このトピックの後半では、アプリケーションがすでに属しているAppDNAアプリケーショングループに基づいてレポートグループを作成する方法を説明します。
OnProcessingComplete()
シナリオで指定されている場合、残りの処理がすべて完了すると、AppDNAはOnProcessingComplete() を自動的に1回呼び出します。この機能を使用すると、レポートが表示される前に最終処理を実行できます。
OnProcessingComplete() 関数には、次のシグネチャが必要です。
Public Overrides Sub OnProcessingComplete()
' Enter your code here.
End Sub
AppDNAアプリケーショングループによるグループ化
このセクションでは、すでに属しているアプリケーショングループに従ってアプリケーションをグループ化するシナリオを変更します。いずれかのアプリケーションがグループのメンバーでない場合は、[グループ解除] カテゴリに表示されます。
このシナリオでは、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 = _
"<a href=""http://www.google.com"">More information</a>"
End If
End Sub
グループの表示を非表示にする
場合によっては、グループ化せずにグループ化されたレポートを表示することもできます。これを行うには、転送パスレポート設定.表示グループプロパティを使用します。シナリオにグループ処理コードを含めると、このプロパティは自動的に true に設定されます。ただし、シナリオで明示的に false に設定して、レポート内のグループの表示を非表示にすることができます。
設定オブジェクト (ForwardPathReportSettings 型の) は、シナリオ全体で使用できます。通常は、次のように Initialize() 関数でプロパティを設定します。
Settings.DisplayGroups = false
グループを再び表示するには、この行をコメントアウトします。