Lire le contenu complet d’une variante de programme SAP

Dans SAP, une variante de programme – ou variante d’exécution – est un ensemble de valeurs pré-enregistrées pour les paramètres de l’écran de sélection du programme.

Les variantes, comment · ça · marche ?

Pour en créer une basique, rien de plus simple : il suffit d’accéder à l’écran de sélection du programme, de renseigner les valeurs comme si l’on voulait l’exécuter, puis de sauvegarder : un nouvel écran s’affiche permettant alors de donner un nom et une description à la variante à enregistrer.

Tout programme ayant au moins une variante affichera, sur la barre d’outils de son écran de sélection, une nouvelle icone permettant de choisir une variante d’exécution. Une fois le choix validé, les paramètres de sélection sont automatiquement valorisés avec les données de la variante.

Lire une variante classique

Il peut arriver que l’on ait besoin, depuis du code ABAP quelconque, de connaitre les valeurs enregistrées dans une variante. Par exemple si un programme veut en exécuter un autre avec une variante donnée, mais en effectuant des pré-contrôles sur le contenu de cette variante afin d’éviter un message d’erreur impossible à intercepter autrement.

SAP fournit des outils pour cela ; pas besoin d’aller requêter la base de données, il y a des modules fonctions tout prêts. Par exemple, RS_VARIANT_CONTENTS (ne pas hésiter à jeter un œil à son groupe de fonctions SVAR qui fournit d’autres fonctions intéressantes).

Avec ce module fonction, on récupère facilement les paramètres (y compris les select-options) de l’écran de sélection. Fin de l’article… ou presque.

Et la sélection libre, dans tout ça ?

Eh oui, rien n’est simple avec SAP !

En effet, j’ai eu à faire récemment à la notion de sélection(s) libre(s) – et c’est d’ailleurs ce qui a entraîné l’écriture de cet article, le monde est bien fait.

La ou les sélections libres, c’est un module qui permet de sélectionner librement (comme le nom l’indique !) des filtres supplémentaires sans avoir à les coder un à un dans l’écran de sélection. Cela se présente sous la forme d’une pop-up qui affichera d’un côté une hiérarchie d’objets filtrables et de l’autre la liste des select-options correspondant au objets sélectionnés (voir capture d’écran ci-dessous). Une fois la saisie validée, tout est enregistré dynamiquement sans avoir à déclarer un select-options par critère, ce qui est tout l’intérêt du module.

Exemple de sélections libres

Là où ça se gâte, c’est que cette sélection libre peut aussi être enregistrée dans une variante, mais qu’aucun module fonction standard SAP ne permet d’en récupérer le contenu !

En effet, si le programme utilise le concept de sélection libre, alors le module fonction susmentionné ne retournera pas tous les éléments de la variante, car ceux relatifs à cette sélection libre sont dynamiques et gérés par des sous-programmes à priori générés directement dans le programme cible… mais qui n’existent pas !

Il y a pourtant une solution !

Heureusement, SAP étant globalement open-source il est presque toujours possible de trouver une solution en debuguant ce que fait le standard. C’est de cette façon qu’une technique de sioux a pu être identifiée.

La méthode est la suivante : dans un premier temps, on appelle le module fonction RS_VARIANT_CONTENTS comme indiqué précédemment. Ensuite, on va charger le programme et la variante ciblés en mémoire puis lire « à distance » le contenu des variables globales dudit programme (dont font partie les éléments de l’écran de sélection).

Pour cela donc, on commencera par :

perform import_var_selc
  in program saplsvar if found
  tables
    selctab
    variant_desc
  using
    nom_du_programme_cible
    report_key
  changing
    imp_subrc
    ssc_subrc.
  • Les paramètres SELCTAB, VARIANT_DESC et SSC_SUBRC sont à transmettre vides ; ils sont inutiles dans notre cas, mais sont obligatoires pour l’appel.
  • REPORT_KEY est une structure contenant simplement le nom du programme ciblé et sa variante.
  • IMP_SUBRC nous indiquera si une erreur est survenue.

On adjoint à cet appel le suivant :

perform %_import_vari_clnt
  in program nom_du programme_cible if found
  using
    report_key
    imp_subrc
    sy-mandt
  changing
    imp_subrc.

Ce sous-programme fait partie de ceux dont je parlais plus haut : il n’existe pas et pourtant cela fonctionne. Je n’ai pas encore compris le mécanisme derrière ; je ne sais pas comment il est possible de faire cela.

À noter également que je n’ai testé que sur un seul programme cible. Peut-être que cela ne fonctionnerait pas sur un autre programme ?

Une fois ceci fait, l’ensemble des variables de l’écran de sélection, y compris donc celles relatives à la sélection libre, devraient être chargées en mémoire (et bien sûr valorisées selon les données de la variante choisie).

Il ne reste alors plus qu’à lire ces valeurs en utilisant la technique – certes pas très propre – du field-symbol pour lire l’espace mémoire du programme. Par exemple :

data(var_name_where) = |({ report_key-report })P_WHERE.
assign (var_name_where) to field-symbol(<mem>).

Ici <mem> pointera sur la valeur de la variable (*programme_ciblé*)P_WHERE.

Les variables à cibler sont P_WHERE et P_RANGES.

À priori il s’agira toujours des mêmes noms de variables, dans le cadre de la sélection libre. Mais ce serait à confirmer avec un autre programme utilisant cette notion.

Et voilà !

Je pense avoir fait le tour de la solution que je suis parvenu à trouver après moult debug. J’ai passé pas mal de temps à comprendre qu’il y avait cette sélection libre sur le programme sur lequel je devais travailler ; je ne connaissais pas du tout ce concept jusqu’ici.

Dans la foulée, j’ai aussi pris du temps à essayer de trouver un outil standard qui permette de lire cette sélection libre, mais en vain.

Il m’a fallu debuguer ce que fait le standard lorsque l’on charge une variante pour en arriver à découvrir des sous-programmes inexistants ! Ils sont appelés, il n’y pas d’erreur de compilation, mais impossible d’aller dans leur code, que ce soit directement depuis SE80 ou en debug.

Si par hasard quelqu’un passait par ici avec une méthode plus standard pour résoudre cette problématique, qu’il n’hésite pas à laisser un commentaire !


Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.