Устав от простыней в стиле:
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.