SELECT mit dynamischen RANGES

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.
     DATAobj_range TYPE REF TO data.
     DATAlt_comp_table TYPE cl_abap_structdescr=>component_table.
     DATAlv_fieldname       TYPE string,
           lv_condition       TYPE string.
     DATAlv_count TYPE i.
 
     FIELD-SYMBOLS<wa_sel_parameters> TYPE wdr_so_s_range_ref,
                    <wa_comp_table>     TYPE abap_componentdescr.
 
     CONSTANTSco_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_datadescrcl_abap_elemdescr=>describe_by_data_ref<wa_sel_parameters>-range ).
       UNASSIGN<wa_comp_table>.
     ENDLOOP.
 
     IF lt_comp_table[] IS NOT INITIAL.
       DATA(obj_structcl_abap_structdescr=>createlt_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>.
 
         CLEARlv_fieldnamelv_count.
       ENDLOOP.
 
       FREEobj_struct.
     ENDIF.
 
     CONDENSE lv_condition.
 
 * Select data
     SELECT *
     INTO CORRESPONDING FIELDS OF TABLE @rt_bpartner
     FROM but000
     WHERE (lv_condition).
 
     CLEARlv_fieldnamelv_countlv_condition.
     FREEobj_range.
     FREElt_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.

Posted on 21. März 2015 in ABAP, Blog

Back to Top