REPORT z_modify_user_parameter_id.
*---------------------------------------------------------------------*
* This program lists the user's Parameter-IDs, These Parameter-IDs    *
* can be modified and saved via Batch-Input                           *
*---------------------------------------------------------------------*
* Author : Michel PIOUD - Updated 21-Nov-07                           *
* HomePage : http://www.oocities.org/mpioud                          *
*---------------------------------------------------------------------*
CONSTANTS :
  c_x VALUE 'X',
  c_refresh TYPE syucomm VALUE '&REFRESH'.
*---------------------------------------------------------------------*
TYPE-POOLS: slis.                      " ALV Global types

TYPES :
  BEGIN OF ty_s_user,
    bname     TYPE usr04-bname,        " User name
    name_last TYPE addr3_val-name_last," Last name
    parid     TYPE usr05-parid,        " Set/Get parameter ID
    partext   TYPE tparat-partext,     " Memory ID Text
    parva     TYPE usr05-parva,        " Parameter value
  END OF ty_s_user.

*---------------------------------------------------------------------*
DATA :
  g_bname TYPE usr05-bname,
  g_parid TYPE usr05-parid,
  gt_user TYPE TABLE OF ty_s_user,
  gt_user_old TYPE SORTED TABLE OF ty_s_user
              WITH UNIQUE KEY bname parid.

FIELD-SYMBOLS <user> TYPE ty_s_user.
*---------------------------------------------------------------------*
SELECTION-SCREEN :
  BEGIN OF LINE, COMMENT 10(20) v_1 FOR FIELD s_bname.      "#EC NEEDED
SELECT-OPTIONS s_bname FOR g_bname MATCHCODE OBJECT user_addr.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN :
  BEGIN OF LINE, COMMENT 10(20) v_2 FOR FIELD s_parid.      "#EC NEEDED
SELECT-OPTIONS s_parid FOR g_parid.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN :
  SKIP, BEGIN OF LINE,COMMENT 10(20) v_3 FOR FIELD p_dsplay."#EC NEEDED
PARAMETERS p_dsplay AS CHECKBOX.
SELECTION-SCREEN END OF LINE.

*---------------------------------------------------------------------*
INITIALIZATION.

  v_1 = 'User'.
  v_2 = 'Parameter Id'.
  v_3 = 'Display only'.

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

  PERFORM f_read_data.

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

  PERFORM f_display_data.

*---------------------------------------------------------------------*
*      Form  f_read_data
*---------------------------------------------------------------------*
FORM f_read_data.

  TYPES :
    BEGIN OF ty_name,
      bname      TYPE usr21-bname,
      name_first TYPE adrp-name_first,
      name_last  TYPE adrp-name_last,
    END OF ty_name,

    BEGIN OF ty_tparat,
      paramid    TYPE tparat-paramid,
      partext    TYPE tparat-partext,
    END OF ty_tparat.

  DATA :
    ls_name TYPE ty_name,
    lt_name TYPE SORTED TABLE OF ty_name
            WITH UNIQUE KEY bname,

    ls_tparat TYPE ty_tparat,
    lt_tparat TYPE SORTED TABLE OF ty_tparat
              WITH UNIQUE KEY paramid,

    lt_user TYPE TABLE OF ty_s_user.

* Read data
  SELECT u~bname parid parva
    INTO CORRESPONDING FIELDS OF TABLE gt_user
    FROM usr05 AS u
    JOIN usr01 AS s
      ON u~bname = s~bname
   WHERE u~bname IN s_bname
     AND parid IN s_parid.

  IF gt_user[] IS NOT INITIAL.
    lt_user[] = gt_user[].
    SORT lt_user BY bname.
    DELETE ADJACENT DUPLICATES FROM lt_user COMPARING bname.
*   Read user name
    SELECT bname name_first name_last
      INTO TABLE lt_name
      FROM usr21 AS u
      JOIN adrp AS a
        ON u~persnumber = a~persnumber
       FOR ALL ENTRIES IN lt_user
     WHERE bname = lt_user-bname.

    lt_user[] = gt_user[].
    SORT lt_user BY parid.
    DELETE ADJACENT DUPLICATES FROM lt_user COMPARING parid.
*   Memory ID Texts
    SELECT paramid partext
      INTO TABLE lt_tparat
      FROM tparat
       FOR ALL ENTRIES IN lt_user
     WHERE paramid = lt_user-parid
       AND sprache = sy-langu.
  ENDIF.

  LOOP AT gt_user ASSIGNING <user>.

*   Get the parameter-id texts.
    READ TABLE lt_tparat WITH KEY paramid = <user>-parid
                             INTO ls_tparat.
    IF sy-subrc IS INITIAL.
      <user>-partext = ls_tparat-partext.
    ELSEIF sy-langu <> 'E'.
*     Not found, try in English
      SELECT SINGLE partext INTO <user>-partext
                            FROM tparat
                           WHERE paramid = <user>-parid
                             AND sprache = 'E'.
      IF sy-subrc IS INITIAL.
        CLEAR ls_tparat.
        ls_tparat-paramid = <user>-parid.
        ls_tparat-partext = <user>-partext.
        INSERT ls_tparat INTO TABLE lt_tparat.
      ELSEIF sy-langu <> 'D'.
*       Not found, try in German
        SELECT SINGLE partext INTO <user>-partext
                              FROM tparat
                             WHERE paramid = <user>-parid
                               AND sprache = 'D'.
        IF sy-subrc IS INITIAL.
          CLEAR ls_tparat.
          ls_tparat-paramid = <user>-parid.
          ls_tparat-partext = <user>-partext.
          INSERT ls_tparat INTO TABLE lt_tparat.
        ENDIF.
      ENDIF.
    ENDIF.

*   Get user name
    READ TABLE lt_name WITH KEY bname = <user>-bname
                           INTO ls_name.
    IF sy-subrc IS INITIAL.
      CONCATENATE ls_name-name_last ls_name-name_first
             INTO <user>-name_last SEPARATED BY space.
    ELSE.
      <user>-name_last = <user>-bname.
    ENDIF.

  ENDLOOP.

* Save data
  gt_user_old[] = gt_user[].

ENDFORM.                               " F_READ_DATA
*---------------------------------------------------------------------*
*      Form  f_display_data
*---------------------------------------------------------------------*
FORM f_display_data.

* Macro definition
  DEFINE m_fieldcat.
    add 1 to ls_fieldcat-col_pos.
    ls_fieldcat-fieldname   = &1.
    ls_fieldcat-ref_tabname = &2.
    ls_fieldcat-edit        = &3.
    append ls_fieldcat to lt_fieldcat.
  END-OF-DEFINITION.

  DEFINE m_sort.
    add 1 to ls_sort-spos.
    ls_sort-fieldname = &1.
    ls_sort-up        = c_x.
    ls_sort-group     = &2.
    append ls_sort to lt_sort.
  END-OF-DEFINITION.

  DATA:
    ls_fieldcat   TYPE slis_fieldcat_alv,
    lt_fieldcat   TYPE slis_t_fieldcat_alv, " Field catalog
    lt_sort       TYPE slis_t_sortinfo_alv,
    ls_sort       TYPE slis_sortinfo_alv,
    lt_event_exit TYPE slis_t_event_exit,
    ls_event_exit TYPE slis_event_exit,
    ls_layout     TYPE slis_layout_alv.

* Build field catalog and sort table
  m_fieldcat 'BNAME'     'USR05'     ''.
  m_fieldcat 'NAME_LAST' 'ADDR3_VAL' ''.
  m_fieldcat 'PARID'     'USR05'     ''.
  m_fieldcat 'PARTEXT'   'TPARAT'    ''.
  IF p_dsplay IS INITIAL.
    m_fieldcat 'PARVA'   'USR05'     c_x.  " Column alterable
  ELSE.
    m_fieldcat 'PARVA'   'USR05'     ''.
  ENDIF.

  m_sort 'BNAME'     'UL'.             " Line break
  m_sort 'NAME_LAST' ''.
  m_sort 'PARID'     ''.

  ls_layout-group_change_edit = c_x.
  ls_layout-colwidth_optimize = c_x.
  ls_layout-cell_merge        = c_x.
  ls_layout-detail_popup      = c_x.
  ls_layout-get_selinfos      = c_x.

  CLEAR ls_event_exit.
  ls_event_exit-ucomm = c_refresh.    " Refresh
  ls_event_exit-after = c_x.
  APPEND ls_event_exit TO lt_event_exit.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program      = sy-cprog
      i_callback_user_command = 'USER_COMMAND'
      is_layout               = ls_layout
      it_fieldcat             = lt_fieldcat
      it_sort                 = lt_sort
      it_event_exit           = lt_event_exit
    TABLES
      t_outtab                = gt_user.

ENDFORM.                               " F_DISPLAY_DATA
*---------------------------------------------------------------------*
*       FORM USER_COMMAND                                             *
*---------------------------------------------------------------------*
FORM user_command USING u_ucomm     TYPE sy-ucomm
                        us_selfield TYPE slis_selfield.     "#EC CALLED

* Macro definition
  DEFINE m_bdc_dynpro.
    clear ls_bdcdata.
    ls_bdcdata-program  = &1.
    ls_bdcdata-dynpro   = &2.
    ls_bdcdata-dynbegin = c_x.
    ls_bdcdata-fnam     = 'BDC_OKCODE'.
    ls_bdcdata-fval     = &3.
    append ls_bdcdata to lt_bdcdata.
  END-OF-DEFINITION.

  DEFINE m_bdc_field.
    clear ls_bdcdata.
    ls_bdcdata-fnam = &1.
    ls_bdcdata-fval = &2.
    append ls_bdcdata to lt_bdcdata.
  END-OF-DEFINITION.

  DATA :
    l_modif TYPE flag,
    ls_user TYPE ty_s_user,
    ls_message TYPE bdcmsgcoll,
    lt_message TYPE TABLE OF bdcmsgcoll,
    ls_bdcdata TYPE bdcdata,
    lt_bdcdata TYPE TABLE OF bdcdata.

  CASE u_ucomm.
    WHEN '&IC1'.
      READ TABLE gt_user INDEX us_selfield-tabindex INTO ls_user.
      CHECK sy-subrc EQ 0.
      m_bdc_dynpro 'SAPLSUU5' '0050' '=SHOW'.
      m_bdc_field  'USR02-BNAME' ls_user-bname.

*     Tabstrip Parameter-Id
      m_bdc_dynpro 'SAPLSUU5' '0100' '=PARAM'.

*     Show user
      CALL TRANSACTION 'SU01' USING lt_bdcdata MODE 'E'
                      MESSAGES INTO lt_message.
      READ TABLE lt_message WITH KEY msgid = '01'
                                     msgnr = '495'
                       TRANSPORTING NO FIELDS.
      CHECK sy-subrc EQ 0.
*     You are not authorized to display users
      MESSAGE i495(01).
    WHEN '&DATA_SAVE'.
*     Update User's Parameter-IDs
      LOOP AT gt_user INTO ls_user.
        READ TABLE gt_user_old ASSIGNING <user>
          WITH KEY bname = ls_user-bname
                   parid = ls_user-parid.

        CHECK ls_user-parva <> <user>-parva.
        l_modif = c_x.
        m_bdc_dynpro 'SAPLSUU5' '0050' '=CHAN'.
        m_bdc_field  'USR02-BNAME' ls_user-bname.

*       Tabstrip Parameter-Id
        m_bdc_dynpro 'SAPLSUU5' '0100' '=PARAM'.

*       Last page
        m_bdc_dynpro 'SAPLSUU5' '0100' '=P++'.

*       Previous page
        m_bdc_dynpro 'SAPLSUU5' '0100' '=P+'.

        m_bdc_dynpro 'SAPLSUU5' '0100' '=CHECK'.
        m_bdc_field  'USPARAM-PARID(10)' ls_user-parid.
        m_bdc_field  'USPARAM-PARVA(10)' ls_user-parva.

*       Save
        m_bdc_dynpro 'SAPLSUU5' '0100' '=UPD'.

        CALL TRANSACTION 'SU01' USING lt_bdcdata MODE 'E'
                        MESSAGES INTO lt_message.
        READ TABLE lt_message WITH KEY msgid = '01'
                                       msgnr = '492'
                                  INTO ls_message.
        IF sy-subrc EQ 0.
*         You are not authorized to change users in group &
          MESSAGE i492(01) WITH ls_message-msgv1.
          EXIT.
        ENDIF.
        REFRESH lt_bdcdata.
      ENDLOOP.

      IF l_modif IS INITIAL.
        MESSAGE i208(00) WITH 'Nothing to do ...'.
      ELSE.
        gt_user_old[] = gt_user[].
      ENDIF.

    WHEN '&REFRESH'.
      PERFORM f_read_data.             " Refresh data
      us_selfield-refresh = c_x.
  ENDCASE.

ENDFORM.                               " USER_COMMAND
************ END OF PROGRAM Z_MODIFY_USER_PARAMETER_ID ****************