Rapports Forward Path groupés

Cette rubrique fournit une vue d’ensemble de la fonctionnalité avancée Forward Path que vous pouvez utiliser pour regrouper des applications par catégories définies dans le script (par exemple, aptitude à un déploiement sur une plate-forme particulière) ou par le groupe d’applications AppDNA auquel les applications appartiennent. Vous pouvez agréger des valeurs d’application au niveau du groupe (par exemple, pour créer des sous-totaux pour chaque groupe) et créer des totaux au niveau du rapport. Cela signifie, par exemple, que si les groupes d’applications représentent des unités commerciales, vous pouvez créer un rapport Forward Path qui regroupe les applications par unité opérationnelle et affiche les sous-totaux pour chacune d’elles.

Généralités

L’image suivante montre un extrait d’un rapport Forward Path dans lequel les applications ont été regroupées en fonction de leur état RAG pour les rapports Windows 7 et App-V. Pour chaque groupe, le coût total de la correction est indiqué, ainsi qu’un dénombrement des applications du groupe. Vous pouvez développer chaque groupe pour afficher les applications à l’intérieur. La ligne de total en haut indique les totaux pour l’ensemble du rapport.

Image du rapport Forward Path avant

Nous allons construire le scénario Forward Path qui a généré ce rapport dans les exemples qui suivent. Afin de rendre les exemples aussi simples que possible, nous utiliserons un coût de correction codé en dur pour chaque application. Dans la vie réelle, vous le calculeriez probablement en fonction de la complexité de l’application et de la correction requise. Pour obtenir un exemple qui calcule les coûts de cette manière, reportez-vous à la section Utiliser les variables de Effort Calculator dans un scénario Forward Path.

Les fonctions de scénario

Le scénario d’un rapport Forward Path groupé implémente généralement les fonctions Forward Path standard suivantes :

  • Initialize () — AppDNA appelle automatiquement cette fonction une fois au début du script. Généralement, cette fonction initialise les variables.
  • ForwardPath () - Il s’agit de la fonction standard que tous les scénarios Forward Path doivent implémenter. AppDNA appelle cette fonction une fois pour chaque application sélectionnée lorsque vous exécutez le rapport. Dans un rapport Forward Path groupé, cette fonction crée des catégories (appelées groupes de rapports) dans lesquelles les applications sont placées. Les groupes de rapports peuvent être créés par la logique du code ou ils peuvent être basés sur laquellegroupes d’applicationsles applications appartiennent déjà.
  • processGroups() — AppDNA appelle cette fonction une fois pour chaque groupe de rapports généré par la fonction ForwardPath(). Cette fonction définit les colonnes de rapport au niveau du groupe et les valeurs qu’elles contiennent.
  • getGroupColumnSummary() — AppDNA appelle cette fonction une fois pour chaque colonne définie dans la fonction processGroups(). Généralement, cette fonction définit les totaux au niveau du rapport.
  • onProcessingComplete() - Ceci est une fonction optionnelle que AppDNA appelle une fois que tout le reste du traitement est terminé. Vous pouvez utiliser cette fonction pour effectuer tout traitement final avant l’affichage du rapport.

Le diagramme suivant montre comment AppDNA appelle les fonctions lorsque vous exécutez le rapport. Le diagramme est suivi de la spécification de chacune des fonctions avancées, ainsi qu’un exemple qui crée ensemble le rapport présenté dans la section Vue d’ensemble ci-dessus.

Fonctions avancées

Remarque : Certains des exemples de cette rubrique utilisent la notation de trait de soulignement (_) pour diviser les longues lignes en deux lignes ou plus. Ainsi, les extraits de code d’exemple s’affichent correctement lorsqu’ils sont inclus dans un PDF. Voir la Bibliothèque MSDN pour plus d’informations sur cette notation.

Initialize()

Si cela est spécifié dans le scénario, AppDNA appelle automatiquement la fonction Initialize() une fois au début du script. La fonction Initialize() doit avoir la signature suivante :

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

Dans cet exemple, nous utiliserons la fonction Initialize () pour initialiser les variables que nous utiliserons pour stocker les valeurs d’application afin qu’elles puissent être agrégées au niveau du groupe. Cependant, nous devons d’abord déclarer les variables que nous voulons utiliser tout au long du scénario. Parce que nous utiliserons ces variables dans plus d’une fonction, nous les définirons au début du script (avant la fonction Initialize ()), comme ceci :

' 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"

Dans cet exemple, nous avons déclaré une variable de dictionnaire appelée coûts. Reportez-vousBibliothèque MSDNà la pour la documentation de cette classe .NET standard. La variable de dictionnaire peut stocker une collection de clés et de valeurs. Dans cet exemple, la clé est une chaîne (que nous utiliserons pour stocker le nom du groupe de rapports) et la valeur est une liste d’entiers (que nous utiliserons pour stocker les coûts de correction pour toutes les applications du groupe de rapports). Reportez-vous à Bibliothèque MSDN pour la documentation sur la classe List.

En plus du dictionnaire, nous avons déclaré trois variables de chaîne pour stocker les noms des trois groupes de rapports que nous allons créer.

Maintenant, nous sommes prêts à implémenter la fonction Initialize (). Ici, c’est :

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

Dans cet exemple, nous avons simplement ajouté un élément à notre variable de dictionnaire des coûts pour chacun de nos trois groupes de rapports. Nous avons spécifié les clés d’élément en utilisant les trois variables de chaîne que nous avons déclarées précédemment pour stocker les noms des groupes de rapports.

ForwardPath()

La fonction ForwardPath () est la fonction standard que tous les scénarios Forward Path doivent implémenter. La fonction ForwardPath () doit avoir la signature suivante :

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

Dans cet exemple, nous allons séparer les applications en trois groupes de rapports — nous ajoutons des applications qui ont un statut vert Windows 7 RAG au groupe de rapports « Windows 7 », nous ajoutons des applications qui ont un statut vert App-V RAG au groupe de rapports « App-V », et nous ajoutons le reste des applications à un groupe de rapports « Retraite ». Pour chaque application, nous allons ajouter un nombre aléatoire codé en dur au dictionnaire pour représenter le coût de la correction de l’application :

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

Notez que nous avons utilisé If… Alors… Else pour diviser les applications en trois groupes de rapports en fonction de l’état RAG pour les rapports Windows 7 et App-V. Nous aurions pu baser les groupes de rapports sur le groupe d’applications auquel appartiennent les applications. Un exemple ultérieur de cette rubrique vous montrera comment faire cela.

Remarque : Il est possible d’ajouter la même application à plusieurs groupes. Dans ce cas, lorsque vous exécutez le rapport, l’application apparaîtra sous chaque groupe auquel elle a été ajoutée et ses valeurs seront agrégées dans les totaux de chaque groupe. Cela peut entraîner l’ajout des valeurs de l’application au total de l’état plus d’une fois. Selon le rapport, cela pourrait être trompeur. C’est à vous, en tant qu’auteur du script, de vous assurer que les applications ne sont pas ajoutées à plus d’un groupe, sauf si cela est votre intention.

ProcessGroups()

Si elle est spécifiée dans le scénario, AppDNA appelle la fonction ProcessGroups() pour chaque groupe de rapports généré par la fonction ForwardPath(). En règle générale, vous utilisez la fonction processGroups() pour définir les colonnes qui apparaissent au niveau du groupe dans le rapport Forward Path.

La fonction ProcessGroups() doit avoir la signature suivante :

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

Notez que l’objet ForwardPawrePortGroup est passé dans cette fonction. Cela représente le groupe de rapports en cours. Il possède deux propriétés : Name, qui est unChaînequi stocke le nom du groupe, et CustomColumns, qui est un dictionnaire de chaînes. Vous utilisez la propriété CustomColumns pour spécifier les noms des colonnes affichées au niveau du groupe et ce qu’elles contiennent.

Voici un exemple :

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

Notez que nous avons défini trois colonnes :

  1. Cela définit la colonne Coût, qui indique le coût total de correction des applications de chaque groupe. Pour obtenir le coût total, nous utilisons la méthode List.Sum () pour agréger toutes les valeurs de coût stockées pour le groupe dans la variable de dictionnaire des coûts. La classe List possède d’autres fonctions d’agrégation que vous pouvez utiliser pour obtenir la valeur moyenne, minimale ou maximale (par exemple) stockée pour le groupe. Reportez-vous à Bibliothèque MSDN pour la documentation sur la classe List.

    Notez que nous avons défini la propriété Format de la colonne sur {0:C} (qui spécifie que la valeur est une devise). Et nous avons défini la propriété Culture sur une valeur de en-US pour spécifier que le symbole de devise est le symbole du dollar américain. Pour en savoir plus sur le formatage de la sortie, reportez-vous à la section Trier et formater les rapports Forward Path.

  2. Cela définit la colonne Nombre, qui indique le nombre d’applications dans chaque groupe. Cette fois, nous utilisons la méthode List.Count () pour obtenir le nombre d’éléments (qui représentent des applications) stockés pour le groupe dans la variable de dictionnaire de coûts.

  3. Cela définit la colonne Lien, qui inclut du code HTML qui définit un lien hypertexte codé en dur. Ceci est un exemple trop simpliste qui montre que vous pouvez inclure du code HTML dans la colonne.

Remarque : AppDNA génère automatiquement une colonne qui affiche le nom du groupe. C’est ce qu’on appelle la colonne « Groupe ».

GetGroupColumnSummary()

Si elle est spécifiée dans le scénario, AppDNA appelle automatiquement la fonction GetGroupColumnSummary() pour chaque colonne définie dans la fonction ProcessGroups(), plus la colonne « Group » générée automatiquement (qui stocke le nom du groupe). La fonction GetGroupColumnSummary() doit avoir la signature suivante :

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

Notez que le nom de la colonne est passé dans la fonction sous la forme d’une chaîne et que la fonction renvoie une chaîne, qui est le texte qui est inséré dans la colonne correspondante dans la ligne totale du rapport.

Vous utilisez la fonction getGroupColumnSummary () pour définir les valeurs au niveau du rapport. Par exemple :

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 appelle cette fonction une fois pour chaque colonne de groupe que nous avons définie dans la fonction processGroups (), plus la colonne « Groupe » générée automatiquement. Nous utilisons donc un If… Alors… Else pour tester quelle colonne est en cours de traitement. Regardons ce que nous faisons pour chaque colonne :

  1. Il s’agit de la colonne Groupe générée automatiquement. Pour cette colonne, nous générons simplement le texte « Total ». Notez que nous avons joint le texte dans les balises <b></b>. Ce sont des balises HTML standard qui spécifient que le texte doit être affiché en gras. Vous pouvez utiliser n’importe quel code HTML dans l’une des colonnes.

  2. Il s’agit de la colonne Coût. Pour obtenir le total du rapport, nous déclarons une variable de travail. Ensuite, nous itérons tous les éléments de la variable de dictionnaire des coûts globaux et ajoutons leurs valeurs totales à la variable de travail, que nous retournons ensuite.

    La valeur renvoyée est une chaîne. Nous avons utilisé la méthode String.Format () pour formater la valeur de coût en tant que devise et nous avons utilisé la classe CultureInfo pour spécifier le symbole de devise dollar américain. Reportez-vous à Bibliothèque MSDN pour la documentation sur la mise en forme des chaînes.

  3. Pour la colonne Nombre, nous avons utilisé une technique similaire pour générer une valeur totale pour le rapport.

  4. Nous avons laissé la colonne Lien vide.

Cela nous amène à la fin du code dans le scénario qui a été utilisé pour générer le rapport Forward Path affiché au début de cette rubrique. Plus loin dans cette rubrique, nous allons apprendre à créer des groupes de rapports basés sur le groupe d’applications AppDNA auquel les applications appartiennent déjà.

OnProcessingComplete()

S’il est spécifié dans le scénario, AppDNA appelle automatiquement OnProcessingComplete() une fois que tout le reste du traitement est terminé. Vous pouvez utiliser cette fonction pour effectuer tout traitement final avant l’affichage du rapport.

La fonction OnProcessingComplete() doit avoir la signature suivante :

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

Regrouper par le groupe d’applications AppDNA

Dans cette section, nous allons modifier le scénario pour regrouper les applications en fonction de cellesgroupe d’applicationsauxquelles elles appartiennent déjà. Si une application n’est pas membre d’un groupe, elle apparaîtra dans une catégorie Non groupée.

Dans le scénario, vous pouvez déterminer à quel groupe une application appartient, via la propriété Application.Groups. Les applications peuvent appartenir à plusieurs groupes. Comme indiqué ci-dessus, si vous ajoutez tous les groupes au rapport, l’application apparaîtra sous chaque groupe auquel elle appartient. Par conséquent, selon la façon dont vous créez le script, il est possible que les coûts de correction de l’application puissent être ajoutés plus d’une fois au total du rapport.

Ces fonctions contiennent des commentaires détaillés qui expliquent comment elles fonctionnent.

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

Masquer l’affichage des groupes

Parfois, vous pouvez souhaiter afficher un rapport groupé sans le regroupement. Pour ce faire, utilisez la propriété ForwardPathReportSettings.DisplayGroups. Cette propriété est automatiquement définie sur true lorsque vous incluez le code de gestion de groupe dans votre scénario. Toutefois, vous pouvez explicitement le définir sur false dans votre scénario pour masquer l’affichage des groupes dans le rapport.

L’objet Settings (qui est de type ForwardPathReportSettings) est disponible tout au long du scénario. Généralement, vous définissez la propriété dans la fonction Initialize(), comme ceci :

Settings.DisplayGroups = false

Pour montrer à nouveau le groupe, il suffit de commenter cette ligne.