Aide à la recherche manuelle avec multiples champs retournés

En règle générale, les outils standard de gestion des aides à la recherche sont suffisants. Il suffit par exemple de créer une zone de saisie sur un dynpro, de bien la typer selon un élément du dictionnaire de données qui ait lui-même une aide à la recherche ou une table de référence, et le dynpro proposera cette aide à la recherche automatiquement.

La limitation arrive lorsque l’on souhaite que la liste des valeurs possibles d’une zone soit dépendante de la valeur d’une autre zone, ou encore lorsque l’on veut que l’aide à la recherche retourne une valeur pour plusieurs zones.

J’ai récemment eu à traiter cette double problématique, aussi vais-je en profiter pour détailler la solution que j’ai utilisée. Il en existe peut-être d’autres et je ne garantis pas d’utiliser celle que recommanderait SAP, mais au moins, cela fonctionne.
L’exemple concret : le dynpro permet de saisir un objet de raccordement et un lieu de consommation. Si l’utilisateur a saisi un objet de raccordement, l’aide à la recherche du lieu de consommation ne doit retourner que ceux de cet objet de raccordement. De plus, elle doit aussi retourner l’objet de raccordement, pour valoriser automatiquement cette zone si jamais l’utilisateur ne l’avait pas encore saisie.

La première étape est de créer un nouveau module dans la logique du dynpro, dans l’évènement process on-value request. Il faut associer ce module à la zone ciblée, en l’occurrence, le lieu de consommation. Ceci aura pour effet de surdéfinir la logique de chargement de l’aide à la recherche. Si le module est vide, il ne se passera donc plus rien lors du F4.

Ensuite, une petite subtilité. Si l’utilisateur a saisi un objet de raccordement puis a déclenché directement l’aide à la recherche, on ne passera pas dans le PAI avant d’arriver dans le module susmentionné, et donc la variable associé au champ de l’objet de raccordement ne sera pas valorisée. Il faut donc lire explicitement le dynpro. Ceci se fait par le module fonction standard DYNP_VALUES_READ auquel on fournira le programme et le n° de dynpro (mettre celui du sous-écran, le cas échéant) ainsi qu’une table interne contenant l’identifiant de l’élément du dynpro à lire (ceci est obligatoire : si la table est rien ne sera retourné par le module fonction).

Troisième étape : effectuer la sélection manuellement. Pour mon exemple, un select a suffi, en n’omettant pas de gérer le cas où aucun objet de raccordement n’est saisi par l’utilisateur.

Quatrième étape : appeler le module fonction F4IF_INT_TABLE_VALUE_REQUEST qui va générer lui-même la popup de l’aide à la recherche. Pour cela, il faut lui transmettre la table interne issue de la sélection (étape ci-dessus), ainsi que le champ parmi la structure de cette table interne qui doit être retourné, et la cible : programme, n° de dynpro (sous-écran si besoin) et identifiant de l’élément du dynpro.

Dernière étape, qui est en fait une sous-étape de la quatrième : si l’on veut que l’aide à la recherche puisse retourner plusieurs champs, il faut lui associer un callback. Ce sera un sous-programme ou une instance d’interface (dans ce dernier cas, l’interface est IF_F4CALLBACK_VALUE_REQUEST). Le code pourra se contenter d’ajouter une ligne (par champ supplémentaire à retourner) à la table interne d’interface de l’aide à la recherche, en renseignant l’identifiant du champ et sa cible dans le dynpro.

Exemple complet
Code du module on-value request :
" the requirements are:
" 1. a premises search help dialog that displays either all the premises or only the premises of
" the selected connection object
" 2. once a premise is selected within the search help dialog, the relevant connection object
" must also be fetched and put in the corresponding dynpro input field
"
" first point is not feasible because a standard search help can't read dynpro inputs, thus we use
" the combination of DYNP_VALUES_READ to read the connection object and the function module
" F4IF_INT_TABLE_VALUE_REQUEST to generate a 'custom' search help dialog
" and to achieve the second point, we have to use a callback method that will add a new field
" to the 'return interface' of the search help (see also LCL_CONTROLLER > F4_CALL_CALLBACK)

" read the connection object on screen, if any
data(lt_dynp_connection_object) = value dynpread_t( ).
insert value #( fieldname = 'LCL_CONTROLLER=>S_SELECTION-CONNECTION_OBJECT' )
into table lt_dynp_connection_object.
call function 'DYNP_VALUES_READ'
exporting
dyname = sy-repid
dynumb = conv d020s-dnum( '5001' )
tables
dynpfields = lt_dynp_connection_object
exceptions
invalid_abapworkarea = 1
invalid_dynprofield = 2
invalid_dynproname = 3
invalid_dynpronummer = 4
invalid_request = 5
no_fielddescription = 6
invalid_parameter = 7
undefind_error = 8
double_conversion = 9
stepl_not_found = 10.
if sy-subrc <> 0.
clear lt_dynp_connection_object[ 1 ].
endif.

data(lv_connection_object_temp) = lt_dynp_connection_object[ 1 ]-fieldvalue.
if lv_connection_object_temp is initial.
" no connection object, use the SQL joker
lv_connection_object_temp = '%'.
endif.

select evbs~haus, evbst~vstelle, evbst~lgzusatz
from evbs
inner join evbst
on evbst~vstelle = evbs~vstelle and
evbst~spras = @sy-langu
where evbs~haus like @lv_connection_object_temp
into table @data(lt_matchcode).

data(lo_callback) = get_callback_interface( ).
call function 'F4IF_INT_TABLE_VALUE_REQUEST'
exporting
retfield = 'VSTELLE'
dynpprog = 'SAPLZWM_ORDER_UIS'
dynpnr = '5001'
dynprofield = 'LCL_CONTROLLER=>S_SELECTION-PREMISE'
value_org = 'S'
callback_program = 'SAPLZWM_ORDER_UIS'
callback_method = lo_callback
tables
value_tab = lt_matchcode.

Code de la méthode d’interface de callback :
method if_f4callback_value_request~f4_call_callback.
" we want our search help to retrieve also the connection object
" (by default, it will only return the selected premise)

" F0001 is the name of the connection object in the search help display list
" (probably because it is the first column displayed)
insert value #( shlpfield = 'F0001'
valfield = 'LCL_CONTROLLER=>S_SELECTION-CONNECTION_OBJECT'
) into table cs_shlp-interface.
endmethod.

Gérer le double-clic dans un Dynpro ABAP

  1. Visuellement, il est possible de souligner un champ par la case à cocher « resp. to double-click » mais c’est facultatif (c’est-à-dire que cela n’impactera pas le comportement du système lors d’un double-clic sur cette zone).
  2. Dans le PF-STATUS, assigner une commande utilisateur sur la touche F2 – ceci est par contre obligatoire !
    Cela va rendre la plupart des champs réactifs au double-clic.
  3. Dans un PAI, créer un module qui va contrôler la commande utilisateur (rappel : F2 !) ;
  4. utiliser l’instructure ABAP get cursor field pour obtenir le nom du champ qui a été double-cliqué.

Ajouter un nouvel onglet dans un TABSTRIP existant d’un DYNPRO ABAP

  1. Copier le push button (i.e. titre de l’onglet) d’un onglet existant et le copier dans la « ligne de titre des onglets » ;
  2. ne pas oublier d’affecter une commande utilisateur (UCOMM) au push button ;
  3. le type de la fonction doit être « P » (local GUI func) ;
  4. Assigner également un nom de sous-écran dans le champ Référence ;
  5. Enfin, créer une zone de sous-écran dans l’onglet ;
  6. Son nom doit être celui renseigné dans la configuration du push button.

Ajuster un table control

Je mets ici un copier-coller rapide et moche de la procédure à suivre pour ajuster un table control (j’en ai eu récemment besoin pour ajouter une colonne et la position au bon endroit).
Ne faisant que rarement des table controls (au profit des ALV), je ne connaissais pas par coeur cette marche à suivre.

Source : https://help.sap.com/saphelp_nw74/helpdata/en/fb/ac5f4261ae11d295b10000e82de14a/content.htm

Adjusting Table Controls
Functions:

Description:

Restrictions:

Transaction variants and screen variants

You can:

Change the column sequence
Change the column width
Hide columns
Revoke the ready for input status of individual columns
Preassign values to table control fields
Completely hide the table control
You cannot change column headings.

GuiXT

The following commands are available:

ColumnHeader [Old] « New » ColumnWidth [Heading] Number ColumnOrder [Heading] Number NoInput [Table, Column name]

ColumnWidth [Heading] 0 hides an entire column.

You can also reposition or hide the table control.

None

Administrator Function for Table Control Settings

(see below)

Adjusting tables at client level. You can:

Change the column sequence
Change the column width
Hide columns
Configure the number of fixed columns
Hide or show gridlines in the table control
You cannot revoke the ready for input status of individual columns.

You cannot change column headings.

You can adjust the layout of a table control at two levels:

User level, and
Client level
User Level

The Table controls function in the upper right corner of the table control allows you to personalize the basic table settings delivered with the system.

Table control adjustments made at user level take priority over adjustments made at client level. Note the following exceptions:

Hidden columns remain invisible
Columns not ready for input remain locked
Screen variant default values are adopted
The first two points are important, otherwise columns could be seen or changed by user groups that they should not be available to.

Client Level

There are two ways of how you can adjust the layout of a table control on a client-wide basis:

Using the administrator function for table control settings, or
Using a transaction or screen variant
You use the administrator functions for table control settings if you want to make the following changes in one client only:

Change the column sequence
Change the column width
Hide columns
If you want to revoke the ready for input status of individual columns or preassign values to table control fields, you must create a screen variant since the administrator function for table controls does not support this. You should also use a screen variant for adjusting table controls if you want to copy the table control settings to other clients. Since screen variants can be transported, their corresponding table control layouts can be transported as well.

Administrator Function for Table Control Settings

Users with authorization ‘TCTR’ in authorization object ‘S_ADMI_FCD’ can define a layout variant of a table control as a standard setting. This setting (variant) then becomes the table control’s global setting for all users whenever they start the transaction. If you do not define a system-wide variant, the system interprets the screen definition as the global setting.

In order to define a table control for the entire system, proceed as follows:

Start the transaction in question and navigate to the appropriate table control.
Use the Table controls icon to activate the Global settings variant (if this is not already the case).
Adjust the table control to your specifications (column width and column position can be adjusted; all columns you do not need can be hidden by setting their width to zero).
One column of the table control must remain visible.

Choose Administrator from the dialog box that appears when you activate the Table settings icon.

The table control attributes are displayed in the table Current settings. No value appears in the field Length for those columns whose width has been set to zero; you can deactivate them by selecting the setting Invisible.
You can also change other attributes of the current table control configuration. You can:
Hide additional columns using the Invisible checkbox

Configure the number of fixed columns

Hide or display the gridlines in the table control

Choose Activate to transfer your settings to the rest of the system. The settings activated are the basic settings for each user.
If you close the dialog box without choosing Activate, the settings remain unchanged.

Call the transaction a second time and check your new settings.
Repeat the steps listed above if you want to alter the table control settings yet again. Each time you activate new settings, this variant overwrites the existing one.