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

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

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • 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 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • 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 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • 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), то на выходе вы получите странные обновления данных, для полей которые не заказывали и не обновления данных для полей, которые вы передавали. Вопрос почему не воспользоваться универсальным обращением по именам полей, остается за кадром.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Как НЕ НАДО писать на ABAP
« Ответ #3 : Октябрь 31, 2018, 01:47:47 pm »
Так сказать привет из центров разработки сапа российских просторов. При печати документа с какого-то бодуна суммы прописью в копейках обрезаются до 6 знаков. По началу было думали, что проблема в функции SPELL_AMOUNT, сап как-то хронически там затирает таблицы конвертации причем с версии 4.6 кажется у них такие проблемы и в текущей S/4HANA 1709 те же самые яйца. Но как оказалось не показалось. Боец просто с какого-то бодуна обрезает слово до 6 букв. т.е. вместо "восемьдесят", просто выводится "восемь"... почему шесть? Кто же скажет... ну віводишь ты копейки без прописи, ну так выводи их всегда или выводит прописью, но резать то зачем? Как обычно вопрос риторический и отчета не жду.


Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Как НЕ НАДО писать на ABAP
« Ответ #4 : Июнь 28, 2022, 07:40:49 pm »
Давно как-то не писалось, но тут одну программу попросили посмотреть. Ну что могу сказать, вот так там написано:
Код: You are not allowed to view links. Register or Login
  IF so_dat-low IS INITIAL.
    so_dat-low = sy-datum.
  ENDIF.

  IF so_dat-low IS NOT INITIAL.
    <Какой-то еще код> 
  ENDIF.
Вопрос в студию, как во втором условии so_dat-low может быть не пустым? Не я понимаю, компилятор, даже в байт-код, для многих вещь в себе, но не до такой же степени  8)

Sapforum.Biz

Re: Как НЕ НАДО писать на ABAP
« Ответ #4 : Июнь 28, 2022, 07:40:49 pm »