*&---------------------------------------------------------------------* *& Report ZGP_STORNO_CREATE *& *&---------------------------------------------------------------------* *& *& *&---------------------------------------------------------------------* REPORT zgp_storno_create. TYPES: BEGIN OF t_keyfields, fieldname TYPE fieldname, inttype TYPE inttype, END OF t_keyfields. DATA: lv_tabname_active TYPE tabname, lv_tabname_new TYPE tabname, lv_where TYPE string, lv_character TYPE string, lt_keyfields TYPE TABLE OF t_keyfields, ls_keyfields LIKE LINE OF lt_keyfields, ldt_tabname_active TYPE REF TO data, lds_tabname_new TYPE REF TO data, ldt_tabname_new TYPE REF TO data. FIELD-SYMBOLS: TYPE STANDARD TABLE, TYPE STANDARD TABLE, TYPE ANY, TYPE ANY, TYPE ANY, TYPE ANY, TYPE ANY, TYPE ANY, TYPE ANY. PARAMETERS: p_dso TYPE rsdodsobject. CLEAR lv_tabname_active. CLEAR lv_tabname_new. * Erstelle Tabellennamen für aktive Daten und Akt.queue IF p_dso IS NOT INITIAL. CONCATENATE '/BIC/A' p_dso '00' INTO lv_tabname_active. CONDENSE lv_tabname_active NO-GAPS. CONCATENATE '/BIC/A' p_dso '40' INTO lv_tabname_new. CONDENSE lv_tabname_new NO-GAPS. ELSE. RAISE dso_name_initial. ENDIF. * Erstelle interne Tabellen und Arbeitsbereiche (Feldsymbole) CREATE DATA ldt_tabname_active TYPE TABLE OF (lv_tabname_active). ASSIGN ldt_tabname_active->* TO . CREATE DATA ldt_tabname_new TYPE TABLE OF (lv_tabname_new). ASSIGN ldt_tabname_new->* TO . CREATE DATA lds_tabname_new LIKE LINE OF . ASSIGN lds_tabname_new->* TO . * Hole alle Daten aus der Aktive-Daten-Tabelle SELECT * FROM (lv_tabname_active) INTO TABLE . * Hole alle Daten aus der Neue-Daten-Tabelle SELECT * FROM (lv_tabname_new) INTO TABLE . * Ein Beleg wurde storniert, wenn er in den aktiven Daten existiert, * in den neuen aber nicht mehr geliefert wird * --> Loop über aktive Daten * Dynamisierung: Hole Schlüsselfelder für Aktive Daten FREE lt_keyfields. SELECT fieldname inttype FROM dd03l INTO TABLE lt_keyfields WHERE tabname = lv_tabname_active AND keyflag = 'X'. * Für jeden Datensatz in den aktiven Daten LOOP AT ASSIGNING . * Erstelle where-Klausel zur Selektion des schlüsselgleichen Satzes * aus Neue-Daten-Tabelle CLEAR lv_where. LOOP AT lt_keyfields INTO ls_keyfields. ASSIGN COMPONENT ls_keyfields-fieldname OF STRUCTURE TO . * Die erste Anweisung benötigt noch kein 'AND' IF sy-tabix = 1. * Im Falle von Character-Feldern sind Anführungszeichen notwendig IF ls_keyfields-inttype <> 'C'. CONCATENATE ls_keyfields-fieldname '=' INTO lv_where SEPARATED BY space. ELSE. CLEAR lv_character. CONCATENATE '''' '''' INTO lv_character. CONDENSE lv_character NO-GAPS. CONCATENATE ls_keyfields-fieldname '=' lv_character INTO lv_where SEPARATED BY space. ENDIF. * Ab dem zweiten Durchlauf ist 'AND' zur Verknüpfung notwendig ELSE. * Im Falle von Character-Feldern sind Anführungszeichen notwendig IF ls_keyfields-inttype <> 'C'. CONCATENATE lv_where 'AND' ls_keyfields-fieldname '=' INTO lv_where SEPARATED BY space. ELSE. CLEAR lv_character. CONCATENATE '''' '''' INTO lv_character. CONDENSE lv_character NO-GAPS. CONCATENATE lv_where 'AND' ls_keyfields-fieldname '=' lv_character INTO lv_where SEPARATED BY space. ENDIF. ENDIF. ENDLOOP. " AT lt_keyfields INTO ls_keyfields * Prüfe ob Datensatz in Neue-Daten vorhanden ist SELECT SINGLE * FROM (lv_tabname_new) INTO WHERE (lv_where). * Satz gefunden --> kein Problem, Satz wurde nicht storniert * in allen anderen Fällen: Satz muss hinzugefügt werden mit Satztyp "D" IF sy-subrc <> 0. MOVE-CORRESPONDING TO . ASSIGN COMPONENT 'RECORDMODE' OF STRUCTURE TO . = 'D'. * Um den Satz einfügen zu können, sind die drei Schlüsselfelder * SID, DATAPAKID und RECORD korrekt zu befüllen * Absteigende Sortierung für RECORD-Nummer erforderlich SORT DESCENDING. READ TABLE INDEX 1 ASSIGNING . * Feldsymbole besitzen aus Dynamisierungsgründen keine Feldstruktur, * daher sind weitere Feldsymbole erforderlich * Die drei Felder SID, DATAPAKID, RECORD werden der Reihe nach in * und geschrieben ASSIGN COMPONENT 'SID' OF STRUCTURE TO . ASSIGN COMPONENT 'SID' OF STRUCTURE TO . = . ASSIGN COMPONENT 'DATAPAKID' OF STRUCTURE TO . ASSIGN COMPONENT 'DATAPAKID' OF STRUCTURE TO . = . ASSIGN COMPONENT 'RECORD' OF STRUCTURE TO . ASSIGN COMPONENT 'RECORD' OF STRUCTURE TO . * Nächste freie Recordnummer = alt + 1 (alt war Max wegen Sortierung!) = + 1. * Füge den Satz zur internen Tabelle hinzu, um im späteren Verlauf * die korrekte RECORD-Nummer ermitteln zu können APPEND TO . * Füge den Satz in die Neue-Daten-Tabelle ein INSERT into (lv_tabname_new) values . ENDIF. ENDLOOP. " AT ASSIGNING