ZDOC_2927

LOOP AT SCREEN, работа с экраном – новая идея

Устав от простыней в стиле:

  LOOP AT SCREEN.
    IF screen-name = 'ZSS-PERID'.
      screen-input = 0.
    ENDIF.
    IF zss-pernr IS NOT INITIAL.
      IF screen-name = 'ZSS-PERNR' OR
         screen-name = 'ZSS-LNAME' OR
         screen-name = 'ZSS-FNAME'.
        screen-input = 0.
      ENDIF.
    ENDIF.

    IF screen-name = 'ZSS-STELL'.
      screen-input = 0.
    ENDIF.

...

    IF screen-name = 'ZSS-TAXNM'.
      IF ... .
        screen-required = 0. 
      ELSE.
        screen-required = 1. 
      ENDIF.
    ENDIF.
    MODIFY SCREEN.
  ENDLOOP.

...

  LOOP AT SCREEN.
    IF screen-group1 = 'M1'.
      IF ...
        screen-input = 0.
      ELSE.
        screen-input = 1.
      ENDIF.
      MODIFY SCREEN.
    ENDIF.
  ENDLOOP.


...

я решил обкатать новый подход.

Первым делом декларативное определение, например:

    mt_profile_readonly = VALUE #(
       ( mask = '*'              action = zcl_screen=>readonly )
    ).

    mt_profile_employee = VALUE #(
       ( mask = '*'              action = zcl_screen=>readonly )
       ( mask = '*QKTGR*'        action = zcl_screen=>obligatory )
       ( mask = '*POSID*'        action = zcl_screen=>input )
    ).

    mt_profile_contractor = VALUE #(
        ( mask = '*'             action = zcl_screen=>readonly )
        ( mask = '*QKTGR*'       action = zcl_screen=>input )
        ( mask = '*TAXNM*'       action = zcl_screen=>obligatory )
        ( mask = '*TDATE*'       action = zcl_screen=>input )
    ).

    mt_profile_visitor = VALUE #(
        ( mask = '*'             action = zcl_screen=>input )
        ( mask = '*PERID*'       action = zcl_screen=>invisible )
        ( mask = '*PERNR*'       action = zcl_screen=>invisible )
        ( mask = '*STELL*'       action = zcl_screen=>invisible )
    ).

Применение на практике сводится к следующему:

  MODULE screen_3000 OUTPUT.
    go_person_controller->process_screen( ).
  ENDMODULE.

...

  METHOD process_screen.

    IF m_mode = mc_display.
      zcl_screen=>apply_profile( mt_profile_readonly ).
    ELSE.
      IF m_data-pernr IS NOT INITIAL.
        IF is_employee( EXPORTING iv_pernr = m_data-perid ).
          zcl_screen=>apply_profile( mt_profile_employee ).
        ELSE.
          zcl_screen=>apply_profile( mt_profile_contractor ).
        ENDIF.
      ELSE.
        zcl_screen=>apply_profile( mt_profile_visitor ).
      ENDIF.
    ENDIF.

  ENDMETHOD.

Пробую пока покатать-проверить, насколько такой подход применим в условиях, приближенным к боевым. Нужно больше мест применения, чтобы определить какой подход даст лучшую читаемость, компактность и проверяемость. И потихотньку можно добавить мяса.

class ZCL_SCREEN definition
  public
  final
  create public .

public section.

  types:
    BEGIN OF ty_profile,
             mask   TYPE string,
             action TYPE char1,
           END OF ty_profile .
  types:
    tt_profile TYPE STANDARD TABLE OF ty_profile WITH DEFAULT KEY .

  constants INVISIBLE type CHAR1 value '-' ##NO_TEXT.
  constants READONLY type CHAR1 value 'R' ##NO_TEXT.
  constants DEFAULT type CHAR1 value ' ' ##NO_TEXT.
  constants INPUT type CHAR1 value '+' ##NO_TEXT.
  constants OBLIGATORY type CHAR1 value '!' ##NO_TEXT.

  methods CONSTRUCTOR .
  class-methods APPLY_PROFILE
    importing
      !PROFILE type TT_PROFILE .
  methods APPLY
    importing
      !PROFILE type TT_PROFILE .
  methods DONE .
protected section.

  data MT_SCREEN type ISH_T_SCREEN .
private section.
ENDCLASS.



CLASS ZCL_SCREEN IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_SCREEN->APPLY
* +-------------------------------------------------------------------------------------------------+
* | [--->] PROFILE                        TYPE        TT_PROFILE
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD apply.

    LOOP AT profile INTO DATA(ls_profile).

      LOOP AT mt_screen ASSIGNING FIELD-SYMBOL(<screen>).
        IF ls_profile-mask CA '*'.
          IF NOT ( <screen>-name CP ls_profile-mask ).
            CONTINUE.
          ENDIF.
        ELSE.
          IF NOT ( <screen>-name = ls_profile-mask ).
            CONTINUE.
          ENDIF.
        ENDIF.

        CASE ls_profile-action.
          WHEN invisible.
            <screen>-active = 0.
            <screen>-invisible = 1.
            <screen>-input = 0.
            <screen>-output = 0.
            <screen>-required = 0.
          WHEN readonly.
            <screen>-active = 1.
            <screen>-invisible = 0.
            <screen>-input = 0.
            <screen>-output = 1.
            <screen>-required = 0.
          WHEN default.

          WHEN input.
            <screen>-active = 1.
            <screen>-invisible = 0.
            <screen>-input = 1.
            <screen>-output = 1.
            <screen>-required = 0.
          WHEN obligatory.
            <screen>-active = 1.
            <screen>-invisible = 0.
            <screen>-input = 1.
            <screen>-output = 1.
            <screen>-required = 1.
        ENDCASE.

      ENDLOOP.

    ENDLOOP.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_SCREEN=>APPLY_PROFILE
* +-------------------------------------------------------------------------------------------------+
* | [--->] PROFILE                        TYPE        TT_PROFILE
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD apply_profile.

    DATA(lo_screen) = NEW zcl_screen( ).

    lo_screen->apply( profile ).

    lo_screen->done( ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_SCREEN->CONSTRUCTOR
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD constructor.

    LOOP AT SCREEN.
      APPEND screen TO mt_screen.
    ENDLOOP.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_SCREEN->DONE
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD done.

    LOOP AT SCREEN.
      READ TABLE mt_screen INTO DATA(ls_screen) WITH KEY name = screen-name.
      MOVE-CORRESPONDING ls_screen TO screen.
      MODIFY SCREEN.
    ENDLOOP.

  ENDMETHOD.
ENDCLASS.