+ Sapforum.Biz » Инструменты » ABAP - Инструментальные средстваТема:
|- Как НЕ НАДО писать на ABAP




Автор Тема: Как НЕ НАДО писать на ABAP  (Прочитано 9076 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 674
  • Reputation Power: 2
  • Uukrul barely matters.Uukrul barely matters.
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Как НЕ НАДО писать на ABAP
« : Май 18, 2012, 11:38:04 am »
В общем в данной теме предлагается выкладывать перлы из гнезда. Вообще-то когда я вижу код написанный консультантом ООО "АBAP и партнеры", я понимаю, что данного консультанта, ну например назовем его Петя, на курсы никто не отправлял, программирование он в институте не учил, поэтому пишем как можем и тут я еще могу войти в положение Пети, но когда я вижу код написанный лучшими собако-абапо-водами из гнезда, такое ощущение набегает, что какая там нафиг оптимизация, какие там... короче это надо видеть и так, по крайней мере в своих программах не делать. Жаль часто автор остается где-то далеко за вывеской SAP и нельзя посмотреть в его честные и не замутненные глаза.

И так первый перл объявление внутренней таблицы неизвестным штирлицем в модуле J_3RF_SBK_INC_DATA:
Код: You are not allowed to view links. Register or Login
data: p_book_cl like standard table of p_book
      with non-unique key
       bukrs gjahr_inv belnr_inv xblnr_inv budat_inv bldat_inv
       dmbtr_wrs_inv   wrbtr_wrs_inv gjahr_pay  dmbtr_inv
       belnr_pay       xblnr_pay budat_pay bldat_pay dmbtr_wrs_pay
       wrbtr_wrs_pay   gjahr_trn belnr_trn bldat_trn budat_trn
       dmbtr_wrs_trn   wrbtr_wrs_trn
       hwbas_wrs_trn   fwbas_wrs_trn
       hwbas2_wrs_trn  fwbas2_wrs_trn
       hwbas3_wrs_trn  fwbas3_wrs_trn
       hwbas4_wrs_trn  fwbas4_wrs_trn
       hwbas5_wrs_trn  fwbas5_wrs_trn basgruno

       hwste_wrs_trn   hwste2_wrs_trn
       hwste3_wrs_trn  hwste4_wrs_trn
       hwste5_wrs_trn
       fwste_wrs_trn   fwste2_wrs_trn
       fwste3_wrs_trn  fwste4_wrs_trn
       fwste5_wrs_trn

       stegruno gjahr_test buzei_test xblnr_test lifnr_cred

       name1_cred name2_cred name3_cred name4_cred
       name1_cred_r name2_cred_r name3_cred_r name4_cred_r
       stcd1_cred stcd3_cred
       flg_belnr_trn bktxt_trn mwskz
       flg_belnr_pay flg_belnr_inv flg_xragl_pay flg_belnr_all
       gjahr buzei linenumb  belnr_buy gjahrbuy buzeibuy flg_barter
       bktxt_pay bktxt_inv gsber part_paym ebeln ebelj zuonr sgtxt
       xref1_inv xref1_dat hkont_inv hkont_trn hkont_cln
       belnr_origpay gjahr_origpay bktxt_origpay xblnr_origpay
       budat_origpay bldat_origpay usnam_inv usnam_pay usnam_pay_fct
       one_time_acc
* LC283 ----------------------------- *
       bukrs_add belnr_add gjahr_add monat_add buzei_add flag_add
* LC283 ----------------------------- *
       ext_number fullname

       with header line.
И рука же не устала перечислять все эти ключи... и главное зачем они им нужны в таком количестве ну явно же со структурами что-то не так, раз надо все поля для внутренней таблицы так объявить?! В общем что-то в этой сказке не правильно, как сказал Колобок, выплевывая косточки лисы...

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 674
  • Reputation Power: 2
  • Uukrul barely matters.Uukrul barely matters.
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Как НЕ НАДО писать на ABAP
« Ответ #1 : Июнь 06, 2012, 10:23:15 pm »
Еще немного занятного ABAP-кода, авторство SAP & KNOZDRIN из последних отметившихся в данной программе. И так отчет, где как-то вычисляются даты работы от года, который задается пользователем на первом экране в поле zgjahr, программа J_1UF_MAJOR_REPAIR:
Код: You are not allowed to view links. Register or Login
133: start-of-selection.
134: concatenate  zgjahr '0101' into date_ybeg.
135: concatenate  zgjahr '1231' into date_yend.
136:  date_yend = date_ybeg - 1 . 
В общем не ясно зачем строка 135, если в следующей строке тупо конечное значение даты вычисляется путем расчета, дата начала минус один день и это не где-то там далеко, это следующая строка программы.

А далее еще интереснее, данный кусок кода, судя по именам переменных должен определить начальную дату работы и конечную и тут интересный феномен, если год задан 2012, то начальная дата по строке 134 будет равна 20120101, а вот конечная в строке 135 станет 20121231, но в строке 136 она  будет изменена на 20111231, т.е. дата конца меньше даты начала на один день. Короче загадочные зверьки, тем более что дальше по коду есть интересный SELECT, модуль J_1UF_MJR_FORMS, со строки 514:
Код: You are not allowed to view links. Register or Login
select  belnr gjahr bktxt budat
*SELECT  BELNR GJAHR BUDAT INTO  (V_BELNR, V_GJAHR,          "n.846437
from bkpf
into  (v_belnr, v_gjahr, p_bktxt, post_date)
where bukrs = p_bukrs and
      bstat = ' ' and
      xblnr = p_xblnr and
      stblg = ' '  and
*      BKTXT = P_BKTXT AND                                  "n.846437
      budat between date_ybeg and date_yend.
Короче при таком раскладе дат, этот запрос всегда будет возвращать sy-subrc = 4 из-за строки budat between date_ybeg and date_yend, где у нас даты ранее выставлены не совсем правильно.
« Последнее редактирование: Июнь 06, 2012, 10:25:08 pm от Uukrul »

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 674
  • Reputation Power: 2
  • Uukrul barely matters.Uukrul barely matters.
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Как НЕ НАДО писать на ABAP (BAPI: BAPI_SERVICE_CHANGE)
« Ответ #2 : Октябрь 14, 2016, 02:17:23 pm »
Есть один занятный BAPI по работе с услугами и работами, а именно BAPI_SERVICE_CHANGE. Тараканов в его реализации хватает с головой (использование данного BAPI, как нибудь опишу отдельно), но меня позабавил такой момент как заполнение структур расширений пользовательских полей, это касается таблицы параметров: EXTENSION_IN STRUCTURE  BAPIPAREX. Принципы заполнения стандартные, но вот то как написана обработка передаваемых данных это та вещь, которую не надо так писать, если вы пишете, что-то универсальное.

В общем суть заполнения это передать значения пользовательских полей, которые мы добавляем в таблицу ASMD - Основная запись работы/услуги: основные данные, и вторая структура которую мы заполняем это скажем так стандартная для BAPI техника структура типа <Имя структуры>X, где для каждого поля мы записываем флаг = "Х", если нужно выполнить обновление поля. В данном случае SAP предлагает следующее, вы должны добавить в структуру BAPISRV_ASMD расширение CI_ASMDDB, а в структуру BAPISRV_ASMDX соответственно расширение CI_ASMDDBX. При этом, в первом расширении вы перечисляете поля которые добавили в таблицу ASMD, а во вторую структуру добавляете такие по имени поля, но с типом BAPIUPDATE, соответственно если вам нужно вызвать обновление данных в этом расширении, напротив нужного поля, будет стоять флажок "X" и, как обычно, мы думаем, что SAP, корректно перенесет пользовательские данные из BAPISRV_ASMD в таблицу ASMD при изменении основной записи работы/услуги в данном BAPI.

А теперь, как не надо писать. Ну тут как бы частично кривые руки локального абапера, выполнившего расширение объекта пользовательскими полями, процентов на 20, остальное 80, на совести писавшего реализацию BAPI. В общем в классе CL_SERVICE_MASTER_MMSRV метод MERGE_DATA написан чудный обработчик определения того, какие поля нужно перенести из переданной структуры и в конечном итоге обновить в базе данных:
Код: You are not allowed to view links. Register or Login
* Merge the service data: Overwrite the interface values (my_) by
* the data base values (ls_) if the corresponding change parameter
* is set to 'X'.
  WHILE sy-subrc EQ 0.
    ASSIGN COMPONENT sy-index OF STRUCTURE my_service_data TO <comp_my>.
    ASSIGN COMPONENT sy-index OF STRUCTURE ls_service_data TO <comp_ls>.
    ASSIGN COMPONENT sy-index OF STRUCTURE my_service_datax TO <comp_x>.
*-- Check if update flag in my_service_datax is set for this field
    IF <comp_x> NE 'X'.
*---- No update, use DB data instead of interface data
      <comp_my> = <comp_ls>.
    ENDIF.
  ENDWHILE.
Как видим писавшему глубоко фиолетово какие там поля, кто, куда и как добавил, боец просто обращается к полям структур по индексу и как следствие, если порядок полей в структурах несколько нарушен (ну переставили два поля местами в с дополнении CI_ASMDDBX), то на выходе вы получите странные обновления данных, для полей которые не заказывали и не обновления данных для полей, которые вы передавали. Вопрос почему не воспользоваться универсальным обращением по именам полей, остается за кадром.