0

I'm having an issue with an ABAP task which wants me to do the following:

  1. Select all the active users from the system
  2. Use bapi_user_get_detail in order to get some personal information about those users (for example: first name, last name, last logon date)
  3. Then I have to check whether users' e-mails are maintained or not; if their e-mail is not maintained (doesn't exist), then I need to use BAPI_USER_CHANGE in order to provide those users an e-mail.
  4. After all, a list should appear like so : first column is First Name of the user, second column Last Name, third column Last Logon Date, fourth column: E-mail and then the fifth column: Message (message is a component from the Return table , from Bapi)

I tried the function module 'Format_message' to get the message from the return table but it's not working. I really don't know how to do it. Please help me, if you can. Also, if you read carefully, I have a loop in loop structure and my manager doesn't want it. How can I change this so my program could be optimized?

Here's my source code:

*&---------------------------------------------------------------------*
*& TABLES
*&---------------------------------------------------------------------*
TABLES: syst.

*&---------------------------------------------------------------------*
*& TYPES
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_users,
        bname TYPE usr01-bname,
       END OF ty_users.

*&---------------------------------------------------------------------*
*& GLOBAL VARIABLES
*&---------------------------------------------------------------------*
DATA: gt_userdetail TYPE TABLE OF ty_users,
      gs_userdetail TYPE ty_users,
      gt_userstochange TYPE TABLE OF ty_users,
      gs_userstochange TYPE ty_users,
      gt_email TYPE TABLE OF bapiadsmtp,
      gs_address TYPE bapiaddr3.


*&---------------------------------------------------------------------*
*& SELECTION SCREEN
*&---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK bl1 WITH FRAME TITLE text-t01.
SELECT-OPTIONS: s_user FOR syst-uname.
SELECTION-SCREEN END OF BLOCK bl1.


*&---------------------------------------------------------------------*
*& START OF SELECTION
*&---------------------------------------------------------------------*
START-OF-SELECTION.
  PERFORM select_active_users.


*&---------------------------------------------------------------------*
*&      Form  select_active_users
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM select_active_users.
  CLEAR gt_userdetail.

  SELECT usr01~bname
    INTO CORRESPONDING FIELDS OF TABLE gt_userdetail
    FROM usr01
    WHERE usr01~bname IN s_user.

  IF sy-subrc = 0.
    PERFORM bapi_user_details.
  ELSE.
    MESSAGE i208(00) WITH 'No active users detected'.
  ENDIF.


ENDFORM.                    "select_active_users


*&---------------------------------------------------------------------*
*&      Form  bapi_user_details
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM bapi_user_details.

  DATA: ls_logon TYPE bapilogond,
        ls_address TYPE bapiaddr3,
        lt_return TYPE TABLE OF bapiret2 WITH HEADER LINE,
        ls_return TYPE bapiret2.

  WRITE: / 'FIRST NAME' COLOR COL_NEGATIVE INVERSE, 20 'LAST NAME' COLOR COL_NEGATIVE INVERSE, 55 'LAST LOGON DATE' COLOR COL_NEGATIVE INVERSE.
  SKIP 1.


  LOOP AT gt_userdetail INTO gs_userdetail.

    CLEAR: ls_logon, ls_address, lt_return[].

    CALL FUNCTION 'BAPI_USER_GET_DETAIL'
      EXPORTING
        username  = gs_userdetail-bname
      IMPORTING
        logondata = ls_logon
        address   = ls_address
      TABLES
        return    = lt_return
        addsmtp   = gt_email.

    IF lt_return IS INITIAL.
      PERFORM display_details USING ls_address ls_logon.
    ELSE.
      READ TABLE lt_return INTO ls_return WITH KEY type = 'AE'.
      IF sy-subrc = 0.
        MESSAGE e208(00) WITH 'An error has occurred'.
        EXIT.
      ENDIF.
    ENDIF.

    IF gt_email IS INITIAL.
      CONCATENATE ls_address-firstname ls_address-lastname '@example.com' INTO gs_address-e_mail.
      TRANSLATE gs_address-e_mail TO LOWER CASE.
      PERFORM append USING gs_userdetail.
      PERFORM user_change.
      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
      CLEAR gt_email[].
    ENDIF.

  ENDLOOP.

ENDFORM.                    "bapi_user_details


*&---------------------------------------------------------------------*
*&      Form  display_details
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM display_details USING ps_address TYPE bapiaddr3
                           ps_logon TYPE bapilogond.

  WRITE: / ps_address-firstname UNDER 'FIRST NAME'(t05) COLOR COL_HEADING,
         ps_address-lastname UNDER 'LAST NAME' COLOR COL_HEADING,
         ps_logon-ltime UNDER 'LAST LOGON DATE' COLOR COL_HEADING.

ENDFORM.                    "display_details


*&---------------------------------------------------------------------*
*&      Form  append
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_TEXT     text
*----------------------------------------------------------------------*
FORM append USING p_user TYPE ty_users.
  gs_userdetail = p_user.
  APPEND gs_userdetail TO gt_userstochange.
  CLEAR gs_userdetail.
ENDFORM.                    "append


*&---------------------------------------------------------------------*
*&      Form  user_change
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM user_change.

  DATA: lt_return TYPE TABLE OF bapiret2 WITH HEADER LINE,
        ls_return TYPE bapiret2,
        ls_addressx TYPE bapiaddr3x,
        lv_msg_str(100).

  IF gt_userstochange IS NOT INITIAL.
    LOOP AT gt_userstochange INTO gs_userstochange.

      CLEAR: lt_return[].

      ls_addressx-e_mail = 'X'.

      CALL FUNCTION 'BAPI_USER_CHANGE'
        EXPORTING
          username = gs_userstochange-bname
          address  = gs_address
          addressx = ls_addressx
        TABLES
          return   = lt_return
          addsmtp  = gt_email.

      IF lt_return IS NOT INITIAL.
        LOOP AT lt_return INTO ls_return.
          CALL FUNCTION 'FORMAT_MESSAGE'
            EXPORTING
              id        = ls_return-id
              lang      = sy-langu
              no        = ls_return-number
              v1        = ls_return-message_v1
              v2        = ls_return-message_v2
              v3        = ls_return-message_v3
              v4        = ls_return-message_v4
            IMPORTING
              msg       = lv_msg_str "Message text
            EXCEPTIONS
              not_found = 1
              OTHERS    = 2.
        ENDLOOP.
      ENDIF.
    ENDLOOP.

  ENDIF.

ENDFORM.                    "user_change
Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
Rebecca
  • 3
  • 1
  • 3
  • what means `Also, if you read carefully, I have a loop in loop structure and my manager doesn't want it`? you manager doesn't want nested loops? there are tasks where no other choice and it is one of them. Give all the restrictions you have for implementation and give expected output for for list you wanna construct – Suncatcher Jul 23 '20 at 11:49

2 Answers2

2

You use a table with header line (actually you are not supposed to do that, the compiler only let you do that because you are not in the OO context)

DATA: lt_return TYPE TABLE OF bapiret2 WITH HEADER LINE,

so this piece of code

IF lt_return IS NOT INITIAL.

checks whether the header of your table is initial and not the table itself.

Either do not use a table with header line (preferred)

DATA: lt_return TYPE bapiret2_t,

or change your code to (discouraged)

IF lt_return[] IS NOT INITIAL.

It is not that the FORMAT_MESSAGE does not work. It has no chance even to be called, because of the incorrect condition.

Jagger
  • 10,350
  • 9
  • 51
  • 93
  • 1
    There is another mistake in the question you might want to correct: `READ TABLE lt_return INTO ls_return WITH KEY type = 'AE'`. The type might be either `A` or `E` but won't be `AE`, because `BAPIRET2-TYPE` is only one character. – Philipp Jul 23 '20 at 13:51
  • You're totally right, missed that one. Should be probably `CA` if possible in this context. – Jagger Jul 23 '20 at 15:41
0

If you want to avoid the nested loops, in this case is quite simple. In each iteration of the main LOOP:

LOOP AT gt_userdetail INTO gs_userdetail.

You can make the changes with the BAPI BAPI_USER_CHANGE. The mistake in the code is that you are buffering the details of the user in this routine:

 FORM append USING p_user TYPE ty_users.
  gs_userdetail = p_user.
  APPEND gs_userdetail TO gt_userstochange.
  CLEAR gs_userdetail.
ENDFORM.                    "append

And the table GT_USERSTOCHANGE is not beeing refresh.

I would recommend to do as follow:

  • Iterate table with data selection (GT_USERDETAIL)
  • Get the detail with the BAPI BAPI_USER_GET_DETAIL
  • Check the result, if there are no errors, process the changes with BAPI BAPI_USER_CHANGE

In every iteration you should always do the correct exception handling, this means that you should check the SY-SUBRC, or the BAPIRET2 table, taking this in consideration the result of process can be buffer and display in a ALV List or with WRITE statements.

Also if you want to FORMAT the BAPIRET2 message structure into a message, you can just simple use the stament:

MESSAGE TNNN(ID) WITH v1 v2 v3 v4 INTO lv_message.

Being T the type of message, NNN the number, ID the ID, and V1... the parameters of the message.

Pablo A.
  • 1
  • 1