Immer wieder gibt es Anwendungen mit dynamischen Suchmasken. Solche Suchen erfordern auch eine dynamische Lesefunktion im Backend um die gewünschten Daten aus der Datenbank zu lesen.
In diesem Posting möchte ich anhand eines kompakten Beispieles zeigen wie man eine Methode erstellt, welcher man eine Tabelle mit Ranges übergeben kann, welche dann direkt in einem SQL SELECT verwendet werden können. Meine fiktive Methode liest Daten aus der CRM Tabelle BUT000 und wird aus einer Web Dynpro Komponente aufgerufen, welche die SELECT-OPTIONS 2.0 Komponente eingebunden hat. Aus diesem Grund ist der Import Parameter auch vom Typ WDR_SO_T_RANGE_REF. Dies ermöglicht den Aufruf der Suchmethode direkt mit der Ranges Struktur der Select-Options Komponente.
Meine Beispiel Methode hört auf den klingenden Namen READ_DATA und besitzt einen Importing und einen Returning Parameter:
Importing: IT_SEL_PARAMETERS Type WDR_SO_T_RANGE_REF
Returning: RT_BPARTNER type BUP_BUT000_T
Das Coding dieser Methode sieht wie folgt aus:
METHOD read_data. DATA: obj_range TYPE REF TO data. DATA: lt_comp_table TYPE cl_abap_structdescr=>component_table. DATA: lv_fieldname TYPE string, lv_condition TYPE string. DATA: lv_count TYPE i. FIELD-SYMBOLS: <wa_sel_parameters> TYPE wdr_so_s_range_ref, <wa_comp_table> TYPE abap_componentdescr. CONSTANTS: co_range_prefix TYPE string VALUE '<lt_range>'. * Create component table with selection parameters LOOP AT it_sel_parameters ASSIGNING <wa_sel_parameters>. APPEND INITIAL LINE TO lt_comp_table ASSIGNING <wa_comp_table>. <wa_comp_table>-name = <wa_sel_parameters>-attribute. <wa_comp_table>-type = CAST cl_abap_datadescr( cl_abap_elemdescr=>describe_by_data_ref( <wa_sel_parameters>-range ) ). UNASSIGN: <wa_comp_table>. ENDLOOP. IF lt_comp_table[] IS NOT INITIAL. DATA(obj_struct) = cl_abap_structdescr=>create( lt_comp_table ). CREATE DATA obj_range TYPE HANDLE obj_struct. ASSIGN obj_range->* TO FIELD-SYMBOL(<lt_range>). LOOP AT it_sel_parameters ASSIGNING <wa_sel_parameters>. ASSIGN <wa_sel_parameters>-range->* TO FIELD-SYMBOL(<lt_sel_option>). * Get comp table entry ASSIGN lt_comp_table[ sy-tabix ] TO <wa_comp_table>. * Build fieldname CONCATENATE '@' co_range_prefix '-' <wa_comp_table>-name INTO lv_fieldname. * Build where condition IF lv_condition IS NOT INITIAL. CONCATENATE lv_condition 'and' INTO lv_condition SEPARATED BY space. ENDIF. CONCATENATE lv_condition <wa_sel_parameters>-attribute 'in' lv_fieldname INTO lv_condition SEPARATED BY space. * Move selection values ASSIGN COMPONENT <wa_comp_table>-name OF STRUCTURE <lt_range> TO FIELD-SYMBOL(<lt_option>). <lt_option> = <lt_sel_option>. CLEAR: lv_fieldname, lv_count. ENDLOOP. FREE: obj_struct. ENDIF. CONDENSE lv_condition. * Select data SELECT * INTO CORRESPONDING FIELDS OF TABLE @rt_bpartner FROM but000 WHERE (lv_condition). CLEAR: lv_fieldname, lv_count, lv_condition. FREE: obj_range. FREE: lt_comp_table. ENDMETHOD.
Was passiert in dieser Methode nun genau?
Aus den Einträgen der Import Tabelle IT_SEL_PARAMETERS wird eine ABAP Komponenten Tabelle erzeugt. Aus dieser Komponenten Tabelle wird dann ein CL_ABAP_STRUCTDESCR Objekt erzeugt, welches die Basis für eine Struktur ist, welche die Referenzen auf die jeweiligen Ranges halten wird.
Im darauf folgenden Loop wird einerseits der String für die dynamische WHERE Bedingung erstellt und andererseits der jeweilige RANGE in in der zuvor erzeugten RANGE Struktur abgelegt.
Als letztes wird der Datenbank SELECT ausgeführt und das Ergebnis direkt in die Returning Tabelle geschrieben.
Am besten sieht man sich die einzelnen Schritte und deren Ergebnis im Debugger an. So sollte recht schnell klar sein was da passiert.
Comments are closed.