Je veux créer une fonction / méthode de classe personnalisée qui prend en 2 paramètres:
1) IM_ITAB type ANY TABLE
2) IM_COMPONENT type STRING
et renvoie 1 paramètre:
1) EX_RANGE type PIQ_SELOPT_T
Donc, l'algorithme est comme ceci:
append corresponding fields of im_itab into new_line_type_internal_table.
Mais je veux encore améliorer la méthode. Si la table interne importée a, disons, 255 colonnes, il faudra plus de temps pour parcourir cette table. Mais je n'ai besoin que d'une seule colonne pour composer la plage.
Je veux donc obtenir les composants de la table interne, puis choisir un seul composant, créer un nouveau type de ligne contenant uniquement ce composant, puis créer une table interne avec cela type de ligne et copie.
Voici le pseudo code correspondant à ce que je veux réaliser:
METHODS compose_range_from_itab IMPORTING IM_ITAB type ANY TABLE IM_COMPONENT type STRING EXPORTING EX_RANGE type PIQ_SELOPT_T. ... METHOD compose_range_from_itab. DATA: lo_obj TYPE REF TO cl_abap_tabledescr, wa_range TYPE selopt, lt_range TYPE piq_selopt_t. FIELD-SYMBOLS: <fs_line> TYPE ANY, <fs_component> TYPE ANY. lo_obj ?= cl_abap_typedescr=>describe_by_data( p_data = im_itab ). READ TABLE lo_obj->key TRANSPORTING NO FIELDS WITH KEY name = im_component. IF sy-subrc IS INITIAL. IF LINES( im_itab ) GT 0. LOOP AT im_itab ASSIGNING <fs_line>. ASSIGN COMPONENT im_component OF STRUCTURE <fs_line> TO <fs_component>. wa_range-sign = 'I'. wa_range-option = 'EQ'. wa_range-low = <fs_component>. APPEND wa_range TO lt_range. ENDLOOP. SORT lt_range BY low. DELETE ADJACENT DUPLICATES FROM lt_range COMPARING low. ex_range[] = lt_range[]. ENDIF. ENDIF. ENDMETHOD.
Comment puis-je "découper" un composant et créer un nouveau type de ligne en utilisant RTTS?
3 Réponses :
Vous êtes en train de tout compliquer, vous n'avez pas besoin de RTTS pour cela.
DEFINE make_range. ex_range = VALUE #( BASE ex_range ( sign = 'I' option = 'EQ' low = &1 ) ). END-OF-DEFINITION. LOOP AT im_itab ASSIGNING FIELD-SYMBOL(<fs_line>). ASSIGN COMPONENT im_component OF STRUCTURE <fs_line> TO FIELD-SYMBOL(<fs_field>). CHECK sy-subrc = 0 AND <fs_field> IS NOT INITIAL. make_range <fs_field>. ENDLOOP.
Et oui, comme l'a dit Sandra, vous ne gagnerez aucune performance avec RTTS, bien au contraire.
/ p>
Je ne ferais pas le CHECK sy-subrc
encore et encore. Il suffit de le faire une fois pour toute la table, et non de le répéter pour chaque ligne. Le composant est soit là dans toutes les lignes ou non. Assurez-vous également que AND
est vraiment prévu - avoir une option I EQ
pourrait en fait être le comportement souhaité.
Pour être sûr, je suppose que la vérification de l'affectation des symboles de champ à chaque fois n'est pas mauvaise, mais je conviens que c'est redondant. Ajouté pour la concision du code, car la vérification avant la boucle nécessite plus de lignes de code. Et je ne pouvais pas convenir que l'ajout de plusieurs espaces à la table de plage est une bonne idée, cela pourrait impliquer des ballonnements de plage sur les ensembles de données d'enchères, ce qui n'est pas bon. OP peut ajouter un espace unique à la plage si nécessaire.
Étonnamment, cette variante s'est avérée plus rapide:
CLASS-METHODS make_range_variant_2 IMPORTING sample TYPE table_type column TYPE string RETURNING VALUE(result) TYPE range_type. METHOD make_range_variant_2. TYPES: BEGIN OF narrow_structure_type, content TYPE char32, END OF narrow_structure_type. TYPES narrow_table_type TYPE STANDARD TABLE OF narrow_structure_type WITH EMPTY KEY. DATA narrow_table TYPE narrow_table_type. DATA(mapping) = VALUE cl_abap_corresponding=>mapping_table_value( ( kind = cl_abap_corresponding=>mapping_component srcname = column dstname = 'CONTENT' ) ). DATA(mover) = cl_abap_corresponding=>create_with_value( source = sample destination = narrow_table mapping = mapping ). mover->execute( EXPORTING source = sample CHANGING destination = narrow_table ). LOOP AT narrow_table ASSIGNING FIELD-SYMBOL(<row>). INSERT VALUE #( sign = 'I' option = 'EQ' low = <row>-content ) INTO TABLE result. ENDLOOP. ENDMETHOD.
CL_ABAP_CORRESPONDING
délègue à une fonction du noyau pour le déplacement de structure à structure, qui est apparemment plus rapide que le ASSIGN COMPONENT OF STRUCTURE [...] TO FIELD-SYMBOL [...]
natif d'ABAP. La boucle réelle semble alors être plus rapide car elle utilise des attributions de noms fixes.
Peut-être que quelqu'un pourrait vérifier.
vous supposez que le type du composant est char32?
malheureusement cl_abap_corresponding ne prend pas en charge table_line.
Pour l'exemple de code, j'ai simplement supposé un type, oui. Si le type n'est pas connu, cela n'est pas possible car la narrow_table
ne peut pas être déclarée de manière statique.
cette variante s'est avérée plus rapide
quelles sont vos preuves? Avez-vous effectué une analyse comparative?
Voici les variantes que j'ai utilisées: github.com/HrFlorianHoffmann/AbapSammaster/AbapSammaster /…
Je n'irais pas pour un Macro
.
Data: lr_data type ref to data. FIELD-SYMBOLS: <lv_component> TYPE any, <ls_data> TYPE any. CREATE DATA lr_data LIKE LINE OF im_itab. ASSIGN lr_data->* TO <ls_data>. "Check whether im_component exists ASSIGN COMPONENT im_component OF STRUCTURE <ls_data> TO <lv_component>. CHECK sy-subrc EQ 0. LOOP AT im_itab INTO <ls_data>. APPEND VALUE #( sign = 'I' option = 'EQ' low = <lv_component> ) TO ex_range. ENDLOOP.
Marco Polo?)) Mais j'apprécie votre code, c'est logique
@Suncatcher J'espère que vous avez compris ce que je voulais dire. Il est déconseillé d'utiliser Macro dans la plupart des langages de programmation modernes. Bien sûr, vous pouvez en discuter. Juste FYI .
D'accord, c'est déconseillé. Mais cela rend le code plus concis et plus lisible et est autorisé dans les one-liners primitifs (remplissage de cellules, structures, etc.) où le débogage n'est pas indispensable
Avoir 255 colonnes ou même 1000 colonnes n'aura aucun impact sur votre algorithme car vous utilisez
LOOP AT ... ASSIGNING
(seule l'utilisation de INTO aurait un impact). RTTS peut améliorer les performances, mais uniquement lorsque vous utilisez le tableau des plages, mais le gain est probablement très très faible. Alors, votre question concerne-t-elle vraiment l'utilisation de RTTS, ou avez-vous un problème de performances ou un autre problème?Même question posée sur SCN (pas encore de réponse pour l'instant)
@Sandra, "Avoir 255 colonnes ou même 1000 colonnes n'aura aucun impact sur votre algorithme" ne semble pas tout à fait correct. Je suppose que le
ASSIGN COMPONENT [...] OF STRUCTURE [...]
varie avec le nombre de colonnes dans le tableau. Au moins ma variante ci-dessous suggère qu'il y a une différence.@Florian il n'y a pas de différence car il n'y a pas de boucle sur les composants, un seul composant est vérifié pour chaque ligne.