Как получить все сообщения из таблицы возврата после вызова BAPI_USER_CHANGE?

У меня возникла проблема с задачей ABAP, которая требует, чтобы я сделал следующее:

  1. Выбрать всех активных пользователей из системы
  2. Используйте bapi_user_get_detail для получения личной информации об этих пользователях (например: имя, фамилия, дата последнего входа в систему).
  3. Затем я должен проверить, поддерживается ли электронная почта пользователей; если их электронная почта не поддерживается (не существует), мне нужно использовать BAPI_USER_CHANGE, чтобы предоставить этим пользователям электронную почту.
  4. В конце концов, список должен выглядеть так: первый столбец — Имя пользователя, второй столбец — Фамилия, третий столбец — Дата последнего входа в систему, четвертый столбец: Электронная почта, а затем пятый столбец: Сообщение (сообщение — это компонент из Таблица возврата, от Bapi)

Я попробовал функциональный модуль «Format_message», чтобы получить сообщение из таблицы возврата, но он не работает. Я действительно не знаю, как это сделать. Пожалуйста, помогите мне, если можете. Кроме того, если вы внимательно прочитаете, у меня есть структура цикла в цикле, и моему менеджеру это не нужно. Как я могу изменить это, чтобы мою программу можно было оптимизировать?

Вот мой исходный код:

*&---------------------------------------------------------------------*
*& 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

person Rebecca    schedule 22.07.2020    source источник
comment
что означает Also, if you read carefully, I have a loop in loop structure and my manager doesn't want it? ваш менеджер не хочет вложенных циклов? есть задачи где нет другого выбора и это одна из них. Дайте все ограничения, которые у вас есть для реализации, и дайте ожидаемый результат для списка, который вы хотите построить.   -  person Suncatcher    schedule 23.07.2020


Ответы (2)


Вы используете таблицу со строкой заголовка (на самом деле вы не должны этого делать, компилятор позволяет вам это делать только потому, что вы не находитесь в контексте OO)

DATA: lt_return TYPE TABLE OF bapiret2 WITH HEADER LINE,

так что этот кусок кода

IF lt_return IS NOT INITIAL.

проверяет, является ли заголовок вашей таблицы начальным, а не сама таблица.

Либо не используйте таблицу с заголовком (предпочтительно)

DATA: lt_return TYPE bapiret2_t,

или измените свой код на (не рекомендуется)

IF lt_return[] IS NOT INITIAL.

Дело не в том, что FORMAT_MESSAGE не работает. У него нет шансов даже быть вызванным из-за неправильного условия.

person Jagger    schedule 23.07.2020
comment
В вопросе есть еще одна ошибка, которую вы, возможно, захотите исправить: READ TABLE lt_return INTO ls_return WITH KEY type = 'AE'. Тип может быть A или E, но не AE, потому что BAPIRET2-TYPE — это только один символ. - person Philipp; 23.07.2020
comment
Вы совершенно правы, пропустил это. Вероятно, должно быть CA, если это возможно в данном контексте. - person Jagger; 23.07.2020

Если вы хотите избежать вложенных циклов, в этом случае все достаточно просто. В каждой итерации основного LOOP:

LOOP AT gt_userdetail INTO gs_userdetail.

Вы можете внести изменения с помощью BAPI BAPI_USER_CHANGE. Ошибка в коде заключается в том, что вы буферизуете данные пользователя в этой процедуре:

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

И таблица GT_USERSTOCHANGE не обновляется.

Я бы рекомендовал поступить следующим образом:

  • Перебор таблицы с выбором данных (GT_USERDETAIL)
  • Получите подробную информацию с помощью BAPI BAPI_USER_GET_DETAIL
  • Проверить результат, если ошибок нет, обработать изменения с помощью BAPI BAPI_USER_CHANGE

В каждой итерации вы всегда должны выполнять правильную обработку исключений, это означает, что вы должны проверять таблицу SY-SUBRC или BAPIRET2, принимая во внимание, что результат процесса может быть буферизован и отображаться в списке ALV или с операторами WRITE.

Также, если вы хотите ФОРМАТИРОВАТЬ структуру сообщения BAPIRET2 в сообщение, вы можете просто использовать стамент:

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

Это T тип сообщения, NNN номер, ID идентификатор и V1... параметры сообщения.

person Pablo A.    schedule 23.07.2020