Как лучше всего обновить таблицу MARA?

Сегодня я столкнулся с проблемой: как обновить таблицу MARA с настраиваемыми и не настраиваемыми полями?

Я нашел несколько решений, но хотел бы знать, какое решение лучше.

Я пришел из модуля HCM. По этому модулю у нас есть журналы изменений. Поэтому я хотел бы обновить таблицу MARA, добавив, если возможно, изменения журнала.

Контекст:

  1. Выберите одну запись MARA из таблицы (ОК)
  2. Редактировать поля (ОК)
  3. Проверьте для каждого поля, если новое значение уже находится в доступных значениях
  4. Обновить таблицу

Логика:

DATA:
  lt_mara TYPE TABLE OF mara,
  ls_mara TYPE mara.

lv_matnr = '000000000024856';

* Seelct data
"" matnr from CONVERSION_EXIT_MATN1_INPUT
SELECT SINGLE * INTO ls_mara FROM mara WHERE matnr = lv_matnr.

* Modification
ls_mara-vlumn = '999.9'. 
"ls_mara-z* = '...'.   

* Checks : volumn is numeric, ...
" [...]

* Update
" [...]

У меня есть только информация о MARA, никаких данных о связанных таблицах.

Решение 1 - MATERIAL_MAINTAIN_DARK

Используйте функциональный модуль MATERIAL_MAINTAIN_DARK.

CALL FUNCTION 'MATERIAL_MAINTAIN_DARK'
    EXPORTING
        kz_activ_cad = blank
        flag_muss_pruefen = fest_x
        sperrmodus = fest_e
        max_errors = 0
        p_kz_no_warn = fest_x " 'N' ?
        kz_prf = blank " 's' ?
        kz_verw = fest_x
        kz_aend = fest_x
        kz_dispo = fest_x
        kz_test = blank
        kz_mdip = blank
        kz_mprp = blank
        kz_ale = blank
        kz_actv = blank
    TABLES
        AMARA_UEB = TMARA_UEB
        AMERRDAT = lt_amerrdat
    EXCEPTIONS
        OTHERS = 7.

" Loop lt_amerrdat.
"   CALL FUNCTION 'RPY_MESSAGE_COMPOSE' [...]
"     WRITE:/ lv_errmsg.

" ROLLBACK WORK.
" or
" CALL FUNCTION 'DB_COMMIT'.

(Я использовал эту логику кода https://archive.sap.com/discussions/thread/169786)

Проблема: я успешно выполнил код, но теперь обнаружил несколько функциональных ошибок. Если я правильно понимаю функциональность этого FM, модификация будет выполнена через tcode (например: MM01 / 02/03). Но я не знаю, каков был начальный tcode для каждой строки, и у меня есть функциональные проблемы (например: неверная категория статьи, ...) в зависимости от используемого tcode.

Вы знаете, как я могу пропустить эти проверки? Или известен исходный tcode?

Решение 2 - BAPI_MATERIAL_SAVEDATA

Используйте функциональный модуль BAPI_MATERIAL_SAVEDATA. Этот FM позволяет обновлять таблицу MARA стандартными полями + настраиваемыми (через EXTENSION (X))

Для информации мой BAPI_TE_MARA & BAPI_TE_MARAX выглядит так:

  • МАТЕРИАЛ (MATNR, char, 18)
  • .APPEND (ZBAPI_TE_MARAX)
  • НОЧАНЖ (BAPIUPDATE; символьный; 1)

Я думаю, мне нужно добавить к нему все поля Z *, прежде чем использовать этот FM? Более того, я не нашел решения обновить поля таблицы. Если я проверяю FM, у меня есть некоторые объекты, но имена столбцов не совпадают. Как мне найти соответствие между полями этого FM и полями в таблице MARA?

Решение 3

Проверяю ли я целостность своего кода? Думаю, я могу использовать простую ВСТАВКУ / ОБНОВЛЕНИЕ (ИЗМЕНИТЬ)? Это должно быть самое простое решение.

CONCATENATE sy-mandt lv_matnr INTO lv_mara_key.

" Lock object
CALL FUNCTION 'ENQUEUE_E_TABLE'
    EXPORTING
        MODE_RSTABLE   = 'E'
        tabname        = 'MARA'
        varkey         = lv_mara_key
    EXCEPTIONS
        foreign_lock   = 1      system_failure = 2      OTHERS = 3.

ls_mara-ernam = sy-uname.
" ...
" std & custo

MODIFY mara FROM ls_mara.

" Unlock object
CALL FUNCTION 'DEQUEUE_E_TABLE'
    EXPORTING
        MODE_RSTABLE   = 'E'
        tabname        = 'MARA'
        varkey         = lv_mara_key
    EXCEPTIONS
        foreign_lock   = 1      system_failure = 2      OTHERS = 3.

Меня интересуют все рекомендации, уроки или советы :)


person Georges O.    schedule 31.10.2016    source источник
comment
Я бы выбрал Решение 2. Решение 3 не рекомендуется, если вы не знаете, что никакие другие связанные таблицы тоже не следует обновлять.   -  person Christian    schedule 31.10.2016
comment
Привет. Спасибо. Действительно, никакие другие столы не будут задействованы. У меня нет другой информации, кроме таблицы MARA. Способ: массовая загрузка данных mara. Для другого будет использоваться другая программа или ручной процесс. Я не нашел хорошей документации по Sol 2. А у вас есть?   -  person Georges O.    schedule 31.10.2016
comment
Решение 2 будет лучшим из трех. BAPI - это официальный интерфейс от SAP, поэтому у вас есть надежное соединение, которое, скорее всего, не изменится после обновлений или обновлений, в то время как внутренние функциональные модули могут измениться. Имена полей в BAPI различаются, но если вы посмотрите на объявление функционального модуля, вы увидите, что они используют одни и те же типы данных. В большинстве случаев этого уже достаточно для сопоставления внутреннего имени поля с именем поля BAPI. Обычно в BAPI используются стандартные имена полей на английском языке, тогда как в таблицах часто используются имена полей длиной 5 или 6 символов, часто на немецком языке.   -  person Dirk Trilsbeek    schedule 31.10.2016


Ответы (5)


Решение 2. Период. Подробности смотрите в замечательных комментариях от @chrisian и @ dirk-trilsbeek.

Что касается вашего следующего вопроса о картировании полей. Более удобные для пользователя имена отлично подходят для людей, использующих BAPI вне SAP, но они затрудняют сопоставление с полями, которые мы знаем внутри SAP. К счастью, в этих случаях SAP большую часть времени использовала одни и те же элементы данных, так что это один из способов их сопоставления. В противном случае различные BAPI часто имеют функциональные модули преобразования для преобразования из полей BAPI в поля базы данных. Для материала BAPI, который вы упомянули, вы можете проверить подпрограммы ‹TABLE› _UEBERGEBEN (это переводится как ‹TABLE› _TRANSFER), где ‹TABLE› - это MARA, MARC и т. Д. Обратите внимание, что, например, процедура MARA_UEBERGEBEN вызывает FM MAP2I_BAPI_MARA_TO_MARA_UEB, и этот FM имеет перевод из структуры BAPI в MARA, например NET_WEIGHT соответствует NTGEW.

person Gert Beukema    schedule 31.10.2016

Используйте Решение 1, НО эти настраиваемые поля следует назначить группе заранее! Это нужно сделать в настройке по пути:

Общая логистика-> Основные записи материалов-> Выбор поля-> Назначьте поля группе выбора полей

Вам следует создать новую группу, если групп еще нет. Эта группа определяет, когда поля будут включены / отключены / активны / неактивны и т. Д. Код должен выглядеть так:

CALL FUNCTION 'MATERIAL_MAINTAIN_DARK'
 EXPORTING
  sperrmodus = ' '
  kz_prf = 'W'
  max_errors = ' '
  p_kz_no_warn = 'X'
  kz_verw = 'X'
  kz_aend = 'X'
  kz_dispo = 'X'
  kz_test = ' '
  flag_muss_pruefen = ' '
  call_mode = 'ACT'
 IMPORTING
  matnr_last = w_matnr_last
  number_errors_transaction = w_nb_errors
 TABLES
  amara_ueb = t_amara_ueb
  amarm_ueb = t_amarm_ueb
 EXCEPTIONS
  kstatus_empty = 1
  tkstatus_empty = 2
  t130m_error = 3
  internal_error = 4
  too_many_errors = 5
  update_error = 6
 OTHERS = 7.

 IF sy-subrc <> 0.
  MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO.
 ELSE.
  COMMIT WORK.
 ENDIF.
person Suncatcher    schedule 31.10.2016

Наконец, это решение выбрано. Мы использовали BAPI_MATERIAL_SAVEDATA с расширением. Я прокомментировал код, чтобы помочь вам, если вы хотите его использовать :)

FORM update_mara
  USING
    us_result TYPE mara. "Input entry of mara with masterdata to update in the system

  DATA :  ls_mara           TYPE bapi_te_mara,
          ls_head           TYPE bapimathead,
          lt_extensionin    TYPE TABLE OF bapiparex,
          ls_extensionin    TYPE bapiparex,
          lt_extensioninx   TYPE TABLE OF bapiparexx,
          ls_extensioninx   TYPE bapiparexx,
          ls_return         TYPE bapiret2,
          lv_x              TYPE char41,
          lv_mara           TYPE string. "Container for all data of ls_mara

  " MASTERDATA PART
  MOVE-CORRESPONDING us_result TO ls_mara.
  ls_mara-material = ls_head-material = us_result-matnr.
  "At least the mendatory key field: 'material'

  " DATA PART
  " Use extension BAPI_TE_MARA
  ls_extensionin-structure = 'BAPI_TE_MARA'.
  lv_mara = ls_mara.
  " Fill data into the extension
  ls_extensionin+30(960) = lv_mara.
  APPEND ls_extensionin TO lt_extensionin.

  " FLAG PART
  CLEAR lv_x.
  DO 41 TIMES. "Don't forget to change 'lv_x TYPE char41' if needed
    CONCATENATE lv_x 'X' INTO lv_x.
    "Add an 'X' where you want to activate the update
    "Here, it's for all fields
  ENDDO. " End of the do loop for all fields of the mara

  " Use extension BAPI_TE_MARAX
  ls_extensioninx-structure  = 'BAPI_TE_MARAX'.
  ls_extensioninx-valuepart1(18)  = us_result-matnr.
  ls_extensioninx-valuepart1+19   = lv_x.
  " The first part (18) of the extensioninx is the matnr and the next ones some 'X' flags to activate the update or not.
  APPEND ls_extensioninx TO lt_extensioninx.

  " PROCESS PART
  CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA'
    EXPORTING
      headdata     = ls_head
    IMPORTING
      return       = ls_return
    TABLES
      extensionin  = lt_extensionin
      extensioninx = lt_extensioninx
  .

  IF ls_return-type = 'E'.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
  ELSE.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        wait = 'X'.
  ENDIF.  " End if of check of BAPI result

ENDFORM.                    " UPDATE_MARA
person Georges O.    schedule 03.02.2017
comment
Вместо жесткого кодирования количества полей (в данном случае 41) в структуре флага обновления вы можете использовать DESCRIBE FIELD TYPE DATA(lv_type) COMPONENTS DATA(lv_number_of_fields)., а затем DO lv_number_of_fields TIMES.. Таким образом, ваш код получает возможность повторного использования и избегает возможного DUMP в будущем. - person cape_bsas; 14.12.2020

Решение № 3 просто НЕ ДЕЙСТВИТЕЛЬНО в системах SAP.

person cape_bsas    schedule 14.12.2020

Оба решения 1 и 2 хороши. Вы можете напрямую заполнить поля custo-field, как вы это делали в решении 3, после того, как вы изменили стандартные поля с помощью одного из FM.

person Alexey Nikitin    schedule 31.10.2016