메뉴 건너뛰기

SAP 한국 커뮤니티

Dynamic Table Maintenance

sapjoy 2006.12.05 06:11 조회 수 : 4106

REPORT zmtable LINE-SIZE 255
               LINE-COUNT 65.

*----------------------------------------------------------------------*
* Program written by Stan Shuralyov
* Maintain Table dynamicly (Table name is entered on Selection Screen)
* Very powerfull program. Please maintain authorisation access and
* restrict maintenance to Z-tables
* Version 6.20 and up
* (can be used in 4.6C with some modifications to block try - endtry
* and classes)
*----------------------------------------------------------------------*
* Version was revised thanks to Fran?is Henrotte comment
* (www.eponasolutions.com)
* Enhanced functionality with dynamic selection screen
*----------------------------------------------------------------------*

TABLES: sscrfields.                "Fields on selection screens

TYPE-POOLS rsds.
DATA ds_clauses TYPE rsds_where.

DATA: BEGIN OF ifield OCCURS 0,
      fieldname LIKE dd03l-fieldname,
      position  LIKE dd03l-position,
      keyflag   LIKE dd03l-keyflag,
      datatype  LIKE dd03l-datatype.
DATA: END OF ifield.

DATA: sl_step    LIKE sy-tabix,
      ss_step    LIKE sy-subrc,
      ss_act(1)  TYPE c,
      sl_lines   LIKE sy-tfill,
      sl_status  LIKE sy-subrc,
      sl_subrc   LIKE sy-subrc,
      sl_update(1) TYPE c,
      sl_mandt(1)  TYPE c,
      len(6)       TYPE n,
      f_value(255) TYPE c,
      sl_datum     LIKE sy-datum,
      sl_uzeit     LIKE sy-uzeit,
      price1(15)   TYPE c,
      price2(15)   TYPE c,
      mess(60)     TYPE c,
      d_stat   LIKE sy-subrc,
      m_stat   LIKE sy-subrc,
      slchar(6) TYPE c.

DATA: ref_ptr TYPE REF TO cx_root.      "Root class more common
DATA: text TYPE string.
DATA: sl_index LIKE sy-tabix.
DATA: zauth LIKE dd02l-tabname.

DATA: num TYPE i,
      max_len TYPE i,
      check_len TYPE i,
      sl_sel(1) TYPE c.

TYPE-POOLS: icon.


*----------------------------------------------------------------*
* SELECTION-SCREEN.
*----------------------------------------------------------------*


SELECTION-SCREEN BEGIN OF LINE.
* text-012 - 'Table Name'
SELECTION-SCREEN COMMENT 1(25) text-012.
PARAMETERS: tabname LIKE dd02l-tabname DEFAULT 'ZSCARE'.
* text-003 - 'Selection'
SELECTION-SCREEN PUSHBUTTON 75(9) text-003 USER-COMMAND sta1.
SELECTION-SCREEN END OF LINE.

* numrows(text) - 'Max Number of ROWS'
PARAMETERS: numrows LIKE sy-subrc DEFAULT '100'.


************************************************************************
*  At Selection-Screen                                                 *
************************************************************************
AT SELECTION-SCREEN.

  CASE sscrfields-ucomm.
    WHEN 'STA1'.
      CLEAR sl_sel.
      CALL FUNCTION 'ZSTAN_SELECTIONS'
        EXPORTING
          tabname         = tabname
        IMPORTING
          ds_clauses      = ds_clauses
        EXCEPTIONS
          table_not_valid = 1
          other_error     = 2
          OTHERS          = 3.

      IF sy-subrc = 0.
        sl_sel = 'X'.
      ENDIF.
  ENDCASE.


************************************************************************
*At Selection-Screen Output                                            *
************************************************************************
AT SELECTION-SCREEN OUTPUT.

  SELECT SINGLE tabname
    INTO tabname
    FROM dd02l
    WHERE tabname  = tabname
      AND as4local = 'A'
      AND ( tabclass = 'TRANSP' OR tabclass = 'POOL'
            OR tabclass = 'CLUSTER' ).
  IF sy-subrc <> 0.
    MESSAGE 'Table is not valid' TYPE 'S'.
    RETURN.
  ENDIF.


*----------------------------------------------------------------*
* START-OF-SELECTION.
*----------------------------------------------------------------*
START-OF-SELECTION.

  DEFINE: acheck.
    zauth = 'ZTABAUTH'.

    select single statu
      into sl_update
      from (zauth)
      where tabname = tabname
        and bname   = sy-uname.
    if sy-subrc <> 0.
      message 'You are not authorized to view this table' type 'S'.
      return.
    endif.
  END-OF-DEFINITION.

  SELECT SINGLE tabname
    INTO tabname
    FROM dd02l
    WHERE tabname  = tabname
      AND as4local = 'A'
      AND ( tabclass = 'TRANSP' OR tabclass = 'POOL'
            OR tabclass = 'CLUSTER' ).
  IF sy-subrc <> 0.
    MESSAGE 'Table is not valid' TYPE 'S'.
    RETURN.
  ENDIF.

  DATA: ptr_itab TYPE REF TO data.
  FIELD-SYMBOLS: <fs_itab> TYPE STANDARD TABLE. "ANY TABLE.
  CREATE DATA ptr_itab TYPE STANDARD TABLE OF (tabname).
  ASSIGN ptr_itab->* TO <fs_itab>.

* For DELETION
  DATA: ptr_itd TYPE REF TO data.
  FIELD-SYMBOLS: <fs_itd> TYPE STANDARD TABLE.
  CREATE DATA ptr_itd TYPE STANDARD TABLE OF (tabname).
  ASSIGN ptr_itd->* TO <fs_itd>.

* For MODIFICATION
  DATA: ptr_itm TYPE REF TO data.
  FIELD-SYMBOLS: <fs_itm> TYPE STANDARD TABLE.
  CREATE DATA ptr_itm TYPE STANDARD TABLE OF (tabname).
  ASSIGN ptr_itm->* TO <fs_itm>.

  DATA: ptr_wtab TYPE REF TO data.
  FIELD-SYMBOLS: <fs_wtab> TYPE ANY.
  CREATE DATA ptr_wtab TYPE (tabname).
  ASSIGN ptr_wtab->* TO <fs_wtab>.

  DATA: itabname(15) TYPE c.
  itabname = '<fs_wtab>'.

* Standard list status with 'SAVE' button
  SET PF-STATUS 'STLI'.
  CLEAR sl_update.

* Maintain authorisation access in table ZTABAUTH
* Key fields:  tabname - Table name
*              bname   = sy-uname - User name
*              statu   = 'X' - maintain
*                        ' ' - view
* Check authorisation access
  acheck.

  SELECT fieldname position keyflag datatype
    INTO TABLE ifield
    FROM dd03l
    WHERE tabname = tabname
      AND fieldname NOT LIKE '.INCLU%'
    ORDER BY position.

  FIELD-SYMBOLS: <f1> TYPE ANY.

  DATA: tab_field(60) TYPE c,
        sline LIKE sy-lisel.

  DATA: field_attr LIKE dfies.
  DATA: BEGIN OF tfield_attr OCCURS 0.
          INCLUDE STRUCTURE field_attr.
  DATA: END OF tfield_attr.

  LOOP AT ifield.
    CALL FUNCTION 'G_FIELD_READ'
      EXPORTING
        table      = tabname
        fieldname  = ifield-fieldname
        text_flag  = 'X'
      IMPORTING
        field_attr = field_attr.

    tfield_attr = field_attr.
    APPEND tfield_attr.
  ENDLOOP.

  IF sl_sel = 'X'.
    SELECT *
      FROM (tabname)
      INTO TABLE <fs_itab> UP TO numrows ROWS
      WHERE (ds_clauses-where_tab).
  ELSE.
    SELECT *
      FROM (tabname)
      INTO TABLE <fs_itab> UP TO numrows ROWS.
  ENDIF.

  DESCRIBE TABLE <fs_itab> LINES sl_lines.

* Show two extra lines to allow addition up to 2 new lines
  IF sl_update = 'X'.
    DO 2 TIMES.
      APPEND INITIAL LINE TO <fs_itab>.
    ENDDO.
  ENDIF.

  DATA: info(22) VALUE 'D - Delete, M - Modify'.
  WRITE: / icon_information AS ICON QUICKINFO info.
  WRITE ' '.

  CLEAR check_len.
  LOOP AT tfield_attr.
    IF tfield_attr-datatype = 'CLNT'.
      CONTINUE.
    ENDIF.
    len = tfield_attr-outputlen.
    IF tfield_attr-keyflag = 'X'.
      check_len = check_len + len + 1.
    ENDIF.
    IF tfield_attr-scrtext_m IS NOT INITIAL.
      WRITE: AT (len) tfield_attr-scrtext_m COLOR 1.
    ELSE.
      WRITE: AT (len) tfield_attr-fieldtext COLOR 1.
    ENDIF.
  ENDLOOP.

  CLEAR ss_step.
  CLEAR ss_act.
  LOOP AT <fs_itab> INTO <fs_wtab>.
    IF sy-tabix LE sl_lines.
      ss_step = 1.
    ELSE.
      CLEAR ss_step.
    ENDIF.

* In field SS_STEP put D -  to delete record
*                      M -  to modify/add new record
    IF sl_update = 'X'.
      WRITE:/ icon_change AS ICON.
      IF ss_step = 1.
        WRITE:  ss_act INPUT ON.
      ELSE.
        ss_act = 'M'.
        WRITE:  ss_act.
        CLEAR ss_act.
      ENDIF.
    ELSE.
      WRITE:/ icon_display AS ICON.
      WRITE:  ss_act COLOR 2.
    ENDIF.

    LOOP AT ifield.
* Maintain client dependant tables in the same client
      IF ifield-datatype = 'CLNT'.
        sl_mandt = 'X'.
        CONTINUE.
      ENDIF.
      CONCATENATE itabname '-' ifield-fieldname INTO tab_field.
      ASSIGN (tab_field) TO <f1>.
      IF sl_update = 'X'.
        IF ifield-keyflag = 'X' AND ss_step IS NOT INITIAL.
          WRITE: <f1> COLOR 4.
        ELSE.
          WRITE: <f1> INPUT ON.
        ENDIF.
      ELSE.
        IF ifield-keyflag = 'X' AND ss_step IS NOT INITIAL.
          WRITE: <f1> COLOR 4.
        ELSE.
          WRITE: <f1> COLOR 2.
        ENDIF.
      ENDIF.
      UNASSIGN <f1>.
    ENDLOOP.
  ENDLOOP.

*----------------------------------------------------------------*
* END-OF-SELECTION.
*----------------------------------------------------------------*
END-OF-SELECTION.



*----------------------------------------------------------------*
* AT USER-COMMAND.
*----------------------------------------------------------------*
AT USER-COMMAND.
  CASE sy-ucomm.
    WHEN 'SAVE'.
      IF sl_update = 'X'.
        CLEAR: sl_step,
               sl_status,
               sl_subrc,
               <fs_wtab>,
               d_stat,
               m_stat,
               max_len.
        REFRESH <fs_itd>.
        REFRESH <fs_itm>.
        DO.
          IF sl_status <> 0.
            EXIT.
          ENDIF.
          ADD 1 TO sl_step.
          IF sl_subrc <> 0.
            EXIT.
          ENDIF.
          CLEAR ss_step.
          CLEAR ss_act.
          READ LINE sl_step
               FIELD VALUE ss_act INTO f_value.
          sl_subrc = sy-subrc.
          IF f_value(1) EQ 'D' OR f_value(1) = 'd'.
            ss_step = 1.  "Delete
          ELSEIF f_value(1) EQ 'M' OR f_value(1) = 'm'.
            ss_step = 2.  "Modify
          ELSE.
            CLEAR ss_step.
          ENDIF.
          CHECK sy-lisel(3) = '0Z '.
          IF ss_step GT 0.
            CLEAR sline.
            sline = sy-lisel+5(250).
            max_len = 250.
            CHECK sline(check_len) <> ' '.
            LOOP AT tfield_attr.
              CONCATENATE itabname '-' tfield_attr-fieldname
                                              INTO tab_field.
              ASSIGN (tab_field) TO <f1>.
              IF tfield_attr-fieldname = 'MANDT'.
                <f1> = sy-mandt.
              ELSE.
                CLEAR f_value.

                IF max_len LT tfield_attr-outputlen.
                  max_len = 255.
                  ADD 1 TO sl_step.
                  READ LINE sl_step.
                  sline = sy-lisel.
                ENDIF.

                f_value = sline(tfield_attr-outputlen).
                max_len = max_len - tfield_attr-outputlen - 1.
                IF tfield_attr-inttype = 'D'.
                  IF f_value CO ' 0./-'.
                    CLEAR sl_datum.
                    <f1> = sl_datum.
                  ELSE.
                    CALL FUNCTION 'CONVERT_DATE_INPUT'
                      EXPORTING
                        input                     = f_value
                        plausibility_check        = 'X'
                      IMPORTING
                        output                    = sl_datum
                      EXCEPTIONS
                        plausibility_check_failed = 1
                        wrong_format_in_input     = 2
                        OTHERS                    = 3.

                    IF sy-subrc = 0.
                      <f1> = sl_datum.
                    ELSE.
                      text = 'Invalid Date'.
                      sl_status = 1.
                      EXIT.
                    ENDIF.
                  ENDIF.
                ELSEIF tfield_attr-inttype = 'T'.
                  IF f_value CO ' 0:'.
                    CLEAR sl_uzeit.
                    <f1> = sl_uzeit.
                  ELSE.
                    CALL FUNCTION 'CONVERT_TIME_INPUT'
                      EXPORTING
                        input                     = f_value
                        plausibility_check        = 'X'
                      IMPORTING
                        output                    = sl_uzeit
                      EXCEPTIONS
                        plausibility_check_failed = 1
                        wrong_format_in_input     = 2
                        OTHERS                    = 3.

                    IF sy-subrc = 0.
                      <f1> = sl_uzeit.
                    ELSE.
                      text = 'Invalid Time'.
                      sl_status = 1.
                      EXIT.
                    ENDIF.
                  ENDIF.
                ELSEIF tfield_attr-inttype = 'C'.
                  TRANSLATE f_value TO UPPER CASE.
                  <f1> = f_value.
                ELSE.
                  TRANSLATE f_value USING ', '.
                  CONDENSE f_value NO-GAPS.
                  TRY.
                      <f1> = f_value.
                    CATCH cx_root INTO ref_ptr.
                      text = ref_ptr->get_text( ).
                      sl_status = 1.
                      EXIT.
                  ENDTRY.
                ENDIF.
                SHIFT sline BY tfield_attr-outputlen PLACES.
                SHIFT sline LEFT.
              ENDIF.
              UNASSIGN <f1>.
            ENDLOOP.
            IF sl_status = 0.
              CASE ss_step.
                WHEN 1.  "Delete
                  ADD 1 TO d_stat.
                  APPEND <fs_wtab> TO <fs_itd>.
                WHEN 2.  "Modify
                  ADD 1 TO m_stat.
                  APPEND <fs_wtab> TO <fs_itm>.
              ENDCASE.
            ENDIF.
          ENDIF.
        ENDDO.

        IF sl_status = 0.
          IF d_stat IS NOT INITIAL.
            slchar = d_stat.
            CONCATENATE 'Deleted -' slchar 'record.' INTO text
              SEPARATED BY space.
            DELETE (tabname) FROM TABLE <fs_itd>.
          ENDIF.
          IF m_stat IS NOT INITIAL.
            slchar = m_stat.
            CONCATENATE text 'Modified -' slchar 'record.' INTO text
              SEPARATED BY space.
            MODIFY (tabname) FROM TABLE <fs_itm>.
          ENDIF.
          IF d_stat IS INITIAL AND m_stat IS INITIAL.
            MESSAGE 'No changes were done' TYPE 'S'.
          ELSE.
            MESSAGE text TYPE 'S'.
          ENDIF.
          LEAVE.
        ELSE.
          MESSAGE text TYPE 'I'.
          EXIT.
        ENDIF.
      ELSE.
        LEAVE.
      ENDIF.
  ENDCASE.

*---------------END---------------



* Below is Function for a Dynamic Selection Screen
FUNCTION zstan_selections.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     VALUE(TABNAME) LIKE  DD02L-TABNAME DEFAULT 'ZSCARE'
*"  EXPORTING
*"     VALUE(DS_CLAUSES) TYPE  RSDS_WHERE
*"  EXCEPTIONS
*"      TABLE_NOT_VALID
*"      OTHER_ERROR
*"----------------------------------------------------------------------


  DATA texpr TYPE rsds_texpr.
  DATA twhere TYPE rsds_twhere.
  DATA trange TYPE rsds_trange.

  DATA BEGIN OF qcat.                    "Selections View for
          INCLUDE STRUCTURE rsdsqcat.    "Free Selectoptions
  DATA END OF qcat.

  DATA BEGIN OF tabs OCCURS 10.
          INCLUDE STRUCTURE rsdstabs.
  DATA END   OF tabs.

  DATA BEGIN OF fields OCCURS 10.
          INCLUDE STRUCTURE rsdsfields.
  DATA END   OF fields.

  DATA BEGIN OF efields OCCURS 10.
          INCLUDE STRUCTURE rsdsfields.
  DATA END   OF efields.

  DATA selid LIKE rsdynsel-selid.
  DATA actnum LIKE sy-tfill.
  DATA title LIKE sy-title VALUE 'Selection Screen'.

  DATA: maxnum LIKE sy-subrc VALUE '69'.

  CLEAR    tabs.
  tabs-prim_tab = tabname.
  COLLECT  tabs.

  DATA: position LIKE dd03l-position.
  DATA: keyflag  LIKE dd03l-keyflag.

  CLEAR fields.

  fields-tablename = tabname.
  fields-sign      = 'I'.

  DATA: step LIKE sy-subrc.

  SELECT fieldname keyflag position
    INTO (fields-fieldname, keyflag, position)
    FROM dd03l
    WHERE tabname = tabname
      AND fieldname NOT LIKE '.INCLU%'
      AND datatype NE 'CLNT'
    ORDER BY position.
    ADD 1 TO step.
    CHECK step LE maxnum.
    IF keyflag <> 'X'.
      efields = fields.
      APPEND efields.
    ENDIF.
    APPEND fields.
  ENDSELECT.

  IF sy-subrc <> 0.
    RAISE table_not_valid.
  ENDIF.

  CALL FUNCTION 'FREE_SELECTIONS_INIT'
    EXPORTING
      expressions              = texpr
      kind                     = 'F'
    IMPORTING
      selection_id             = selid
      expressions              = texpr
      where_clauses            = twhere
      field_ranges             = trange
      number_of_active_fields  = actnum
    TABLES
      tables_tab               = tabs
      fields_tab               = fields
      fields_not_selected      = efields
    EXCEPTIONS
      fields_incomplete        = 01
      fields_no_join           = 02
      field_not_found          = 03
      no_tables                = 04
      table_not_found          = 05
      expression_not_supported = 06
      incorrect_expression     = 07
      illegal_kind             = 08
      area_not_found           = 09
      inconsistent_area        = 10
      kind_f_no_fields_left    = 11
      kind_f_no_fields         = 12
      too_many_fields          = 13.

  IF sy-subrc = 0.
    CALL FUNCTION 'FREE_SELECTIONS_DIALOG'
      EXPORTING
        selection_id            = selid
        title                   = title
      IMPORTING
        where_clauses           = twhere
        expressions             = texpr
        field_ranges            = trange
        number_of_active_fields = actnum
      TABLES
        fields_tab              = fields
      EXCEPTIONS
        internal_error          = 01
        no_action               = 02
        no_fields_selected      = 03
        no_tables_selected      = 04
        selid_not_found         = 05.

    IF sy-subrc = 0.
      CLEAR ds_clauses.
      MOVE tabname TO ds_clauses-tablename.
      READ TABLE twhere WITH KEY ds_clauses-tablename INTO ds_clauses.
      IF sy-subrc <> 0.
        RAISE other_error.
      ENDIF.
    ELSE.
      RAISE other_error.
    ENDIF.
  ELSE.
    RAISE other_error.
  ENDIF.

ENDFUNCTION.
번호 제목 글쓴이 날짜 조회 수
11 REPORT Z07_013 sapjoy 2006.12.08 2546
10 REPORT Z07_011 [1] sapjoy 2006.12.07 2185
9 REPORT Z07_010. sapjoy 2006.12.07 2529
8 REPORT Z07_007 sapjoy 2006.12.07 2701
» Dynamic Table Maintenance [1] sapjoy 2006.12.05 4106
6 Z02_003 [2] sapjoy 2006.12.03 3054
5 Z01_021 [1] sapjoy 2006.12.03 2773
4 Z01_020 [2] sapjoy 2006.12.03 3014
3 Z01_019 [2] sapjoy 2006.12.03 2694
2 Z01_018 [2] sapjoy 2006.12.03 3051
1 Z01_012 [9] sapjoy 2006.12.03 4586