Dans certains cas, il est impossible de consommer directement le résultat d’une « Calculation View » dans la couche reporting (Webi, Analysis for office …). Pour des raisons de licence par exemple on se retrouve obligé de transiter par l’intermédiaire de BW et d’une requête BEx.
En respectant les « best practices » on devrait tomber sur une architecture de ce type :
Inconvénient majeur : le mode de lecture d’aide à la saisie « D » n’est pas supporté.
Pour plus de précision sur le comportement du mode D dans le composite provider, se référer à la note 2094816.
Pour rappel, voici les modes existants pour lister les valeurs possibles d’une invite de requête Bex lors de son exécution :
- Mode M: les valeurs présentes dans les tables de master data (tables P, Q) sont récupérées
- Mode D: les valeurs des caractéristiques dans les dimensions de l’infoprovider sont récupérées
Remarque : Le mode Q (« Valeurs postées pour navigation ») n’est pas valide pour l’écran de sélection des invites utilisateurs. Il l’est uniquement pour le parcours des filtres une fois le résultat de la requête calculé.
Sur l’architecture présentée plus haut, si le mode M n’est pas sélectionné par défaut pour une caractéristique, il le remplace automatiquement lors de l’exécution de la requête.
Pour contourner cette situation, nous pouvons implémenter la BAdI standard RSR_VARIABLE_F4_RESTRICT_BADI du point d’extension RSR_VARIABLE_F4_RESTRICT (se19).
En quelques mots, cette BAdI permet de personnaliser la liste des valeurs d’aide à la saisie, elle est composée d’une interface possédant les trois méthodes suivantes :
- GET_RESTRICTION_FLAT: restreint les valeurs des variables sur valeur de caractéristique
- GET_RESTRICTION_NODE: restreint les valeurs des variables sur nœud de hiérarchie
- GET_RESTRICTION_HIER: restreint les valeurs des variables sur hiérarchie
- Attention, il n’est pas possible de restreindre l’affichage des hiérarchies en fonction de leur nom/ID mais seulement de leurs dates de validité et version.
Remarque : Afin de déclencher l’exécution de ces méthodes, il faut que « l’InfoObjet » ou le « field » 4XXX sur laquelle porte la variable BEx soit présent dans la liste de valeurs de filtre.
Le principe est ensuite globalement le même pour chaque méthode. Le développeur doit remplir différentes tables avec la liste des valeurs qu’il souhaite proposer à l’utilisateur :
- Table C_T_RANGE pour FLAT
- Table C_T_NODE pour NODE
- Tables C_T_DATE & C_T_VERSION pour HIER.
L’avantage à présent de se trouver sur une architecture hybride est que l’on peut utiliser la rapidité de calcul de la BDD HANA pour constituer ces ensembles de données. Pour cela, les « best practices » nous recommandent deux méthodes :
- Les vues ABAP CDS. Leur utilisation dépend des choix adoptés en termes de modélisation de l’existant. En effet, les vues CDS sont conçues pour produire des modèles de données à part entière, et il serait contre intuitif de mélanger plusieurs méthodologies de modélisation (CDS view vs HANA informations view). Pour plus d’informations sur le CDS cf. https://www.bilinksolutions.com/blog-sap-hana/sap-hana-core-data-services/
- Les classes AMDP. Celles-ci ne sont pas conçues pour modéliser mais pour offrir au monde ABAP la puissance de calcul HANA en permettant l’exécution de fonctions et procédures de base de données. Les objets du dictionnaire de données ABAP (tables ou vues) ainsi que les informations view HANA lui sont accessibles. Cela en fait l’objet tout indiqué pour notre cas de figure, quel que soit la technologie de modélisation.
Ces deux objets présentent l’avantage de pouvoir être manipulés facilement via des instructions ABAP et parallèlement de bénéficier du code « push down ». C’est-à-dire de pouvoir déléguer les lourds traitements (select etc.) à la base de données.
Remarque : Une troisième technique consiste à utiliser des « external views ». A l’image des vues ABAP CDS, celles-ci permettent de créer des vues dans le dictionnaire de données ABAP mais dont l’exécution passe par une « information view » et non par du code CDS.
Sur le papier la fonctionnalité a l’air intéressante mais néanmoins déconseillée par SAP étant donné qu’elle est spécifique aux objets HANA XSC (développements sur SAP HANA Studio), et sera obsolète lors d’une migration HANA XSA (développements sur SAP Web IDE).
Qui plus est, les « external views » ne sont pas capables de gérer les « input parameters » des « information views » dont elles dérivent. Cela en fait des candidates moins performantes qu’une vue CDS ou une AMDP si l’on souhaite développer des filtres en cascade par exemple.
Le concept des filtres en cascade est parfaitement détaillé sur ce blog : https://sapinsider.wispubs.com/Assets/Articles/2017/September/SPJ-Cascading-Prompts-The-Next-Generation-of-F4-Value-Help-Filtering
Mise en pratique
Coté BAdI
Nous proposons ci-dessous une façon d’appréhender l’utilisation de la BAdI RSR_VARIABLE_F4_RESTRICT_BADI avec de l’AMDP pour le requêtage de la base de données.
Notre architecture est conçue autour d’une classe abstraite maître. A chaque nouvelle variable (devant restreindre son aide à la saisie) devra correspondre une sous-classe qui héritera de ses propriétés.
L’avantage est que l’on peut déclarer un objet en référence à la classe maître et l’instancier dynamiquement en fonction du nom de la variable.
Exemple pour la méthode FLAT :
METHOD IF_RSR_VARIABLE_F4_RESTRICT~GET_RESTRICTION_FLAT.
data lv_classname type c length 30.
*Déclaration d’un objet en référence à la classe master
data lr_instance type ref to ZCL_RESTRICT_VAR_MASTER.
*Construction du typage dynamique de l’instanciation
concatenate ‘ZCL_‘ i_vnam into lv_classname.
translate lv_classname to upper case.
try.
*Instanciation en tant que classe (ZCL_Nom_variable)
create object lr_instance type (lv_classname)
exporting » Appel du constructeur
i_src = ‘FLAT’ » Identifie type de variable
i_vnam = i_vnam » Nom de la variable
i_iobjnm = i_iobjnm » Nom de l’infoObjet
i_t_var_range = i_t_var_range » Valeurs des invites saisies
i_t_compid = i_t_compid. » Requête à l’origine de l’appel
call method lr_instance->process_subclass
importing e_result_flat = c_t_range.
* Dans le cas où la classe n’existerait pas, l’exception « CX_SY_CREATE_OBJECT_ERROR » est émise.
* La gestion de cette exception est indispensable pour éviter les erreurs système.
catch CX_SY_CREATE_OBJECT_ERROR.
endtry.
free lr_instance.
ENDMETHOD.
Coté Framework spécifique
Concernant notre classe maître, elle est définie comme abstraite (seuls ses fils doivent être instanciés) et implémente l’interface « if_amdp_marker_hdb » (permettant l’utilisation de méthode AMDP à elle et ses enfants).
Pour chaque nouvelle variable à restreindre, le but est de simplifier au maximum les tâches à accomplir. Pour cela, toutes les méthodes à appeler sont définies dans la classe master, et chaque sous-classe redéfinira uniquement le strict minimum.
Seules les méthodes « SET_QUERYLIST » et « GET_LISTF4 » doivent être traitées spécifiquement pour chaque variable.
Conclusion
Une fois ce mini Framework mis en place, cette solution permet une utilisation simple et efficace des fonctionnalités de restriction d’aide à la saisie. Dupliquer une sous-classe existante rend la prise en compte d’une nouvelle variable très rapide et ne nécessite quasiment aucune connaissance ABAP.
Ci-dessous un exemple de sous-classe à compléter par un développeur :
class ZCL_NOM_VARIABLE definition public
inheriting from zcl_restrict_var_master
create public.
protected section.
methods get_list_f4 redefinition.
methods set_querylist redefinition.
ENDCLASS.
CLASS ZCL_NOM_VARIABLE IMPLEMENTATION.
method set_querylist.
» Liste des requêtes éligibles pour la restriction de valeur
data: ls_compid type ts_compid.
ls_compid = ‘NOM_TECH_REQUÊTE_1’.
append ls_compid to e_t_compid.
ls_compid = ‘NOM_TECH_REQUÊTE_N’.
append ls_compid to e_t_compid.
endmethod.
method get_list_f4 by database procedure for hdb language sqlscript.
/* A renseigner uniquement si la variable est de type « characteristic value » */
e_result_flat = select » as iobjnm,
» as sign,
» as option,
» as low,
» as high
from dummy;
/* A renseigner uniquement si la variable est de type « Hierarchy node » */
e_result_node = select » as NODENAME,
» as NIOBJNM
from dummy;
endmethod.
ENDCLASS.
Guillaume Régnier
Derniers articles parGuillaume Régnier (voir tous)
- Aide à la saisie (F4 values) pour requêtes Bex sur Calculation Views - 17 janvier 2020
- Core Data Services en quelques mots - 6 décembre 2018