Änderungsbelegobjekt

Aus SAP Wiki ツ

Mit SCDO können Änderungsbelegobjekte für Z Tabellen erstellt werden, sodass Änderungen der Customizing Tabelle in der CDHDR / CDPOS protokolliert werden.

Vorbereitung

Bevor das Änderungsobjekt erstellt wird, müssen alle Datenelemente der Z Tabelle das Logging für Änderungen aktiviert werden. Hierzu sind Z Datenelemente zu erstellen, da sonst Standard Datenelemente verändert würden.

Außerdem muss die Z Customizing Tabelle ein Pflege-View haben (SM30).

Vorgehen

Änderungsbelegobjekt erstellen

Mit Transaktion SCDO wird ein Änderungsbelegobjekt erstellt. Anschließend wird die Customizing Tabelle eingetragen für die Änderungen in der CDHDR und CDPOS aufgezeichnet werden sollen. Danach wird im Reiter "Hilfsmittel" → "Udpate Programm generieren" ausgeführt.

Pflegeview modifizieren

Bevor mit SE56 unter "Environment" → "Modification" → "Events" includes erstellt werden, muss der View zuvor für die Tabelle generiert werden.

Dann sind zwei Includes zu erstellen, die der View bei Änderungen aufruft:

Mirror: F_BEFORE_SAVE (C) by Zafer Onbaş

FORM f_before_save ##CALLED.
 TYPES: BEGIN OF ty_tcdrp,
          object     TYPE cdobjectcl,
          reportname TYPE cdreport,
        END OF   ty_tcdrp,
        BEGIN OF ty_view_tab,
          object  TYPE cdobjectcl,
          tabname TYPE cdtabname,
        END OF   ty_view_tab.
 DATA: lt_ptab      TYPE STANDARD TABLE OF string,
       lv_prog      TYPE string,
       lv_mess      TYPE string,
       lv_sid       TYPE string,
       lt_obj       TYPE STANDARD TABLE OF ty_view_tab,
       lt_tcdrp     TYPE STANDARD TABLE OF ty_tcdrp,
       lv_fugn      TYPE funct_pool,
       lv_table     TYPE cdtabname,
       lv_namesfunc TYPE namespace,
       lv_funcgroup TYPE progname,
       lv_namesprog TYPE namespace,
       lv_program   TYPE progname,
       lrt_tabname  TYPE RANGE OF tabname,
       lt_dd26v     TYPE TABLE OF dd26v,
       lv_object    TYPE cdobjectcl.
 " Get tabnames
 " DD: Interface for reading a view from the ABAP/4 Dictionary
 CALL FUNCTION 'DDIF_VIEW_GET'
   EXPORTING
     name          = vim_view_name
   TABLES
     dd26v_tab     = lt_dd26v
   EXCEPTIONS
     illegal_input = 1
     OTHERS        = 2.
 IF sy-subrc IS NOT INITIAL.
   MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
           WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
 ENDIF.
 IF lt_dd26v IS INITIAL.
   APPEND INITIAL LINE TO lrt_tabname ASSIGNING FIELD-SYMBOL(<lrs_tabname>).
   <lrs_tabname>-sign   = 'I'.
   <lrs_tabname>-option = 'EQ'.
   <lrs_tabname>-low    = vim_view_name.
 ELSE.
   SORT lt_dd26v BY tabname.
   DELETE ADJACENT DUPLICATES FROM lt_dd26v COMPARING tabname.
   "*-
   LOOP AT lt_dd26v INTO DATA(ls_dd26v).
     APPEND INITIAL LINE TO lrt_tabname ASSIGNING <lrs_tabname>.
     <lrs_tabname>-sign   = 'I'.
     <lrs_tabname>-option = 'EQ'.
     <lrs_tabname>-low    = ls_dd26v-tabname.
   ENDLOOP.
 ENDIF.
 " Objects for change document creation
 SELECT object tabname
   FROM tcdob
   INTO TABLE lt_obj
   WHERE tabname IN lrt_tabname
   ##WARN_OK.
 IF sy-subrc IS NOT INITIAL.
   " No change document objects found
   MESSAGE i899(cd).
   RETURN.
 ENDIF.
 " Information on Include Reports Generated by RSSCD000
 SELECT object reportname
   FROM tcdrp
   INTO TABLE lt_tcdrp
   FOR ALL ENTRIES IN lt_obj
   WHERE object EQ lt_obj-object
   ##WARN_OK.
 IF sy-subrc IS NOT INITIAL.
   " Update program does not yet exist
   MESSAGE i446(m2).
   RETURN.
 ENDIF.
 " View Directory
 SELECT SINGLE area
   FROM tvdir
   INTO lv_fugn
   WHERE tabname EQ vim_view_name.
 "*-
 LOOP AT lt_obj ASSIGNING FIELD-SYMBOL(<ls_obj>).
   READ TABLE lt_tcdrp ASSIGNING FIELD-SYMBOL(<ls_tcdrp>)
                       WITH KEY object = <ls_obj>-object.
   IF sy-subrc IS NOT INITIAL.
     CONTINUE.
   ENDIF.
   " Split namespace
   CLEAR: lv_namesprog, lv_program.
   lv_program = <ls_tcdrp>-reportname.
   CALL FUNCTION 'RS_NAME_SPLIT_NAMESPACE'
     EXPORTING
       name_with_namespace    = lv_program
     IMPORTING
       namespace              = lv_namesprog
       name_without_namespace = lv_program
     EXCEPTIONS
       delimiter_error        = 1
       OTHERS                 = 2.
   IF sy-subrc <> 0.
     lv_program = <ls_tcdrp>-reportname.
   ENDIF.
   CLEAR: lv_namesfunc, lv_funcgroup.
   lv_funcgroup = lv_fugn.
   CALL FUNCTION 'RS_NAME_SPLIT_NAMESPACE'
     EXPORTING
       name_with_namespace    = lv_funcgroup
     IMPORTING
       namespace              = lv_namesfunc
       name_without_namespace = lv_funcgroup
     EXCEPTIONS
       delimiter_error        = 1
       OTHERS                 = 2.
   IF sy-subrc <> 0.
     lv_funcgroup = lv_fugn.
   ENDIF.
   " Namespace conversion
   lv_object = <ls_obj>-object.
   IF lv_object(1) = '/'.
     SHIFT lv_object LEFT DELETING LEADING '/'.
     REPLACE FIRST OCCURRENCE OF '/' IN lv_object WITH '_'.
   ENDIF.
   lv_table = <ls_obj>-tabname.
   IF lv_table(1) = '/'.
     SHIFT lv_table LEFT DELETING LEADING '/'.
     REPLACE FIRST OCCURRENCE OF '/' IN lv_table WITH '_'.
   ENDIF.
   " Subroutine pool
   APPEND ##NO_TEXT:
          `PROGRAM SUBPOOL.` TO lt_ptab,
          `  INCLUDE ` && lv_namesprog  && `F` && lv_program && `CDT.` TO lt_ptab,
          `  INCLUDE ` && lv_namesprog  && `F` && lv_program && `CDC.` TO lt_ptab,
          `  FORM f_process.` TO lt_ptab,
          `    TYPES:  BEGIN OF total.` TO lt_ptab,
          `            INCLUDE STRUCTURE ` && vim_view_name && `.` TO lt_ptab,
          `            INCLUDE STRUCTURE vimflagtab.` TO lt_ptab,
          `    TYPES:  END OF total.` TO lt_ptab,
          `    FIELD-SYMBOLS: <fs_total>       TYPE ANY TABLE,` TO lt_ptab,
          `                   <fs_total_wa>    TYPE total,` TO lt_ptab,
          `                   <fs_x_namtab>    TYPE ANY TABLE,` TO lt_ptab,
          `                   <fs_x_namtab_wa> TYPE vimnamtab,` TO lt_ptab,
          `                   <fs_field>       TYPE any.` TO lt_ptab,
          `    DATA: lv_tabname(40) TYPE c VALUE '(` && lv_namesfunc && `SAPL` && lv_funcgroup && `)TOTAL[]',` TO lt_ptab,
          `          lv_cond_line  TYPE string,` TO lt_ptab,
          `          lv_cond_line2 TYPE string.` TO lt_ptab,
          `    ASSIGN (lv_tabname) TO <fs_total>.` TO lt_ptab,
          `    LOOP AT <fs_total> ASSIGNING <fs_total_wa> CASTING.` TO lt_ptab,
          `      CASE <fs_total_wa>-action.` TO lt_ptab,
          `        WHEN 'U'. " Update` TO lt_ptab,
          `          lv_tabname = '(` && lv_namesfunc && `SAPL` && lv_funcgroup && `)X_NAMTAB[]'.` TO lt_ptab,
          `          ASSIGN (lv_tabname) TO <fs_x_namtab>.` TO lt_ptab,
          `          lv_cond_line2 = |keyflag EQ 'X' AND viewfield NE 'MANDT'|.` TO lt_ptab,
          `          LOOP AT <fs_x_namtab> ASSIGNING <fs_x_namtab_wa> WHERE (lv_cond_line2).` TO lt_ptab,
          `            ASSIGN COMPONENT <fs_x_namtab_wa>-viewfield OF STRUCTURE <fs_total_wa> TO <fs_field>.` TO lt_ptab,
          `            IF sy-subrc IS INITIAL.` TO lt_ptab,
          `              lv_cond_line = lv_cond_line && |AND | && ` TO lt_ptab,
          `                             <fs_x_namtab_wa>-viewfield && | EQ '| && <fs_field> && |' |.` TO lt_ptab,
          `              objectid = objectid && <fs_field>.` TO lt_ptab,
          `              UNASSIGN <fs_field>.` TO lt_ptab,
          `            ENDIF.` TO lt_ptab,
          `          ENDLOOP.` TO lt_ptab,
          `          IF sy-subrc IS INITIAL.` TO lt_ptab,
          `            SHIFT lv_cond_line LEFT BY 3 PLACES.` TO lt_ptab,
          `            SELECT SINGLE *` TO lt_ptab,
          `              FROM ` && <ls_obj>-tabname TO lt_ptab,
          `              INTO *` && <ls_obj>-tabname TO lt_ptab,
          `              WHERE (lv_cond_line).` TO lt_ptab,
          `            MOVE-CORRESPONDING <fs_total_wa> TO ` && <ls_obj>-tabname && `.` TO lt_ptab,
          `            objectid        = objectid.` TO lt_ptab,
          `            tcode           = sy-tcode.` TO lt_ptab,
          `            udate           = sy-datum.` TO lt_ptab,
          `            utime           = sy-uzeit.` TO lt_ptab,
          `            username        = sy-uname.` TO lt_ptab,
          `            cdoc_upd_object = 'U'.` TO lt_ptab,
          `            upd_` && lv_table && ` = 'U'.` TO lt_ptab,
          `            PERFORM cd_call_` && lv_object && `.` TO lt_ptab,
          `          ENDIF.` TO lt_ptab,
          `        WHEN 'N'. " New` TO lt_ptab,
          `          lv_tabname = '(` && lv_namesfunc && `SAPL` && lv_funcgroup && `)X_NAMTAB[]'.` TO lt_ptab,
          `          ASSIGN (lv_tabname) TO <fs_x_namtab>.` TO lt_ptab,
          `          lv_cond_line2 = |keyflag EQ 'X' AND viewfield NE 'MANDT'|.` TO lt_ptab,
          `          LOOP AT <fs_x_namtab> ASSIGNING <fs_x_namtab_wa> WHERE (lv_cond_line2).` TO lt_ptab,
          `            ASSIGN COMPONENT <fs_x_namtab_wa>-viewfield OF STRUCTURE <fs_total_wa> TO <fs_field>.` TO lt_ptab,
          `            IF sy-subrc IS INITIAL.` TO lt_ptab,
          `              objectid = objectid && <fs_field>.` TO lt_ptab,
          `              UNASSIGN <fs_field>.` TO lt_ptab,
          `            ENDIF.` TO lt_ptab,
          `          ENDLOOP.` TO lt_ptab,
          `          IF sy-subrc IS INITIAL.` TO lt_ptab,
          `            MOVE-CORRESPONDING <fs_total_wa> TO ` && <ls_obj>-tabname && `.` TO lt_ptab,
          `            objectid        = objectid.` TO lt_ptab,
          `            tcode           = sy-tcode.` TO lt_ptab,
          `            udate           = sy-datum.` TO lt_ptab,
          `            utime           = sy-uzeit.` TO lt_ptab,
          `            username        = sy-uname.` TO lt_ptab,
          `            cdoc_upd_object = 'I'.` TO lt_ptab,
          `            upd_` && lv_table && ` = 'I'.` TO lt_ptab,
          `            PERFORM cd_call_` && lv_object && `.` TO lt_ptab,
          `          ENDIF.` TO lt_ptab,
          `        WHEN 'D'. " Delete` TO lt_ptab,
          `          lv_tabname = '(` && lv_namesfunc && `SAPL` && lv_funcgroup && `)X_NAMTAB[]'.` TO lt_ptab,
          `          ASSIGN (lv_tabname) TO <fs_x_namtab>.` TO lt_ptab,
          `          lv_cond_line2 = |keyflag EQ 'X' AND viewfield NE 'MANDT'|.` TO lt_ptab,
          `          LOOP AT <fs_x_namtab> ASSIGNING <fs_x_namtab_wa> WHERE (lv_cond_line2).` TO lt_ptab,
          `            ASSIGN COMPONENT <fs_x_namtab_wa>-viewfield OF STRUCTURE <fs_total_wa> TO <fs_field>.` TO lt_ptab,
          `            IF sy-subrc IS INITIAL.` TO lt_ptab,
          `              objectid = objectid && <fs_field>.` TO lt_ptab,
          `              UNASSIGN <fs_field>.` TO lt_ptab,
          `            ENDIF.` TO lt_ptab,
          `          ENDLOOP.` TO lt_ptab,
          `          IF sy-subrc IS INITIAL.` TO lt_ptab,
          `            MOVE-CORRESPONDING <fs_total_wa> TO *` && <ls_obj>-tabname && `.` TO lt_ptab,
          `            objectid        = objectid.` TO lt_ptab,
          `            tcode           = sy-tcode.` TO lt_ptab,
          `            udate           = sy-datum.` TO lt_ptab,
          `            utime           = sy-uzeit.` TO lt_ptab,
          `            username        = sy-uname.` TO lt_ptab,
          `            cdoc_upd_object = 'D'.` TO lt_ptab,
          `            upd_` && lv_table && ` = 'D'.` TO lt_ptab,
          `            PERFORM cd_call_` && lv_object && `.` TO lt_ptab,
          `          ENDIF.` TO lt_ptab,
          `      ENDCASE.` TO lt_ptab,
          `      CLEAR: lv_cond_line, lv_cond_line2, objectid, ` && <ls_obj>-tabname && `, *` && <ls_obj>-tabname && `.` TO lt_ptab,
          `    ENDLOOP.` TO lt_ptab,
          `  ENDFORM.` TO lt_ptab.
   "*-
   GENERATE SUBROUTINE POOL lt_ptab NAME lv_prog
            MESSAGE lv_mess
            SHORTDUMP-ID lv_sid.
   IF sy-subrc = 0.
     PERFORM ('F_PROCESS') IN PROGRAM (lv_prog) IF FOUND.
   ELSEIF sy-subrc = 4.
     MESSAGE lv_mess TYPE 'I'.
   ELSEIF sy-subrc = 8.
     MESSAGE lv_sid TYPE 'I'.
   ENDIF.
   CLEAR: lt_ptab.
 ENDLOOP.
ENDFORM.

Mirror: F_AFTER_SAVE (C) by Zafer Onbaş

FORM f_after_save ##CALLED.
 COMMIT WORK AND WAIT.
ENDFORM.

Step-by-Step

  1. Änderungsbelegobjekt mit SCDO erstellen
  2. Customizing-Tabelle als neuen Eintrag hinzufügen
  3. Hilfsmittel -> Verbucher generieren
  4. PopUp öffnet sich: Funktionsgruppe angeben und anschließend aktivieren
  5. Z Customizing Tabelle im Änderungsmodus öffnen
  6. Hilfsmittel -> Tabellenpflegegenerator öffnen
  7. Umfeld -> Modifikation -> Zeitpunkte
  8. Nun müssen zwei Forms angelegt werden, die von der Viewpflege heraus ausgerufen werden:
    • 01 F_BEFORE_SAVE
    • 02 F_AFTER_SAVE
    • Mit den Button Editor ist jeweils der o.g. Code einzufügen
    • Hinweis: Hier ist es wichtig die Forms in ein Z Include zu erstellen

Quellen / Credits / Copyrights