Текущее время: Вс, июл 21 2019, 16:36

Часовой пояс: UTC + 4 часа


Правила форума


ВНИМАНИЕ!

Вопросы по SAP Query и Quick View - сюда



Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
 Заголовок сообщения: Оптимизация кода заполнения BAPI
СообщениеДобавлено: Вт, фев 12 2019, 18:52 
Начинающий
Начинающий

Зарегистрирован:
Вт, фев 12 2019, 18:37
Сообщения: 5
Всем доброго времени суток!
Помогите новичку реализовать идею, если это возможно.
Оригинальная структура выглядит так :
Code:
i_poheaderx-po_number = 'X'.
i_poheaderx-comp_code = 'X'.
i_poheaderx-doc_type = 'X'.
i_poheaderx-creat_date = 'X'.
i_poheaderx-created_by = 'X'.
i_poheaderx-item_intvl = 'X'.
i_poheaderx-vendor = 'X'.
i_poheaderx-langu = 'X'.
i_poheaderx-pmnttrms = 'X'.
i_poheaderx-dscnt1_to = 'X'.
i_poheaderx-purch_org = 'X'.
i_poheaderx-pur_group = 'X'.
i_poheaderx-currency = 'X'.
i_poheaderx-doc_date = 'X'.
i_poheaderx-incoterms1 = 'X'.
i_poheaderx-incoterms2 = 'X'.
i_poheaderx-logsystem = 'X'.
i_poheaderx-subitemint = 'X'.
i_poheaderx-vat_cntry = 'X'.
i_poheaderx-suppl_vend ='X'.
i_poheaderx-currency_iso = 'X'.


Я хочу сделать тоже самое, но только через loop и инкремент - но я не понимаю как я могу "достать" все поля и к каждому следующему присвоить значение.
Если loop - то мне нужно это делать через таблицу. Ради примера можно добавить таблицу. Подразумеваю, что это должен быть динамичный Abap, но не совсем понимаю как это реализовать.
По мне это выглядело БЫ так:

Code:
loop lt_poheaderx into i_poheaderx.
i_poheaderx(доступ ко всем полям) + 1  = 'X'.
endloop.


Могу изъясняться не очень корректно, но идея должна быть ясна.


Пометить тему как нерешенную
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Оптимизация кода
СообщениеДобавлено: Вт, фев 12 2019, 18:58 
Гуру-эксперт
Гуру-эксперт
Аватара пользователя

Зарегистрирован:
Чт, ноя 11 2004, 17:25
Сообщения: 3093
Пол: Мужской
ASSIGN COMPONENT, жмете f1, читаете, обращаете внимание на RTTI (CL_ABAP_STRUCTDESCR)


Пометить тему как нерешенную
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация кода  Тема решена
СообщениеДобавлено: Вт, фев 12 2019, 19:02 
Гуру-эксперт
Гуру-эксперт
Аватара пользователя

Зарегистрирован:
Чт, ноя 11 2004, 17:25
Сообщения: 3093
Пол: Мужской
Конкретно по Вашей задаче, лучше не делать динамику, но Вам решать...
Вы похоже заполняете X структуру от BAPI, я бы оставил прозрачным флажки, какие поля будут использоваться. Единственное вместо 'X', лучше использовать константу abap_true.

ps
И зачем Вам проставлять флажки для ВСЕХ полей BAPI?


Пометить тему как нерешенную
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация кода
СообщениеДобавлено: Вт, фев 12 2019, 19:04 
Начинающий
Начинающий

Зарегистрирован:
Вт, фев 12 2019, 18:37
Сообщения: 5
Отлично!
Большое спасибо за совет.


Пометить тему как нерешенную
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Оптимизация кода
СообщениеДобавлено: Вт, фев 12 2019, 19:09 
Начинающий
Начинающий

Зарегистрирован:
Вт, фев 12 2019, 18:37
Сообщения: 5
Besa написал:
Конкретно по Вашей задаче, лучше не делать динамику, но Вам решать...
Вы похоже заполняете X структуру от BAPI, я бы оставил прозрачным флажки, какие поля будут использоваться. Единственное вместо 'X', лучше использовать константу abap_true.

ps
И зачем Вам проставлять флажки для ВСЕХ полей BAPI?



Да, я понимаю, что нужно проставлять только для тех полей, которые я изменил, но хотелось просто попробовать все это написать в 3 строки. Я учусь и потому перебираю все варианты))


Пометить тему как нерешенную
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Оптимизация кода
СообщениеДобавлено: Вт, фев 12 2019, 19:33 
Старший специалист
Старший специалист

Зарегистрирован:
Чт, май 12 2011, 17:06
Сообщения: 269
Если нужно все поля зачекбоксить, можно так:
i_poheaderx = 'XXX...X'. " число X равно числу полей в i_poheaderx


Пометить тему как нерешенную
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация кода
СообщениеДобавлено: Вт, фев 12 2019, 22:13 
Гуру-эксперт
Гуру-эксперт
Аватара пользователя

Зарегистрирован:
Чт, ноя 11 2004, 17:25
Сообщения: 3093
Пол: Мужской
LAT написал(а):
Если нужно все поля зачекбоксить, можно так:
i_poheaderx = 'XXX...X'. " число X равно числу полей в i_poheaderx

да, как вариант, но тут надо учесть что при изменении структуры данных, все "сползет".
ну и, не повезет тому, кто будет сопровождать такой кейс, потому как в случае с BAPI, надо понимать какие поля задействованы, при таком раскладе это крайне не удобно.


Пометить тему как нерешенную
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация кода
СообщениеДобавлено: Ср, фев 13 2019, 08:45 
Специалист
Специалист

Зарегистрирован:
Пт, июл 27 2007, 14:06
Сообщения: 128
Code:
while sy-subrc = 0.
  data(index) = sy-index.
  assign component index of structure i_poheader to field-symbol(<field>).
  check sy-subrc = 0.
  if <field> is not initial.
    assign component index of structure i_poheaderx to field-symbol(<fieldx>).
    if cl_abap_typedescr=>describe_by_data( <fieldx> )->get_relative_name( ) = 'BAPIUPDATE'.
      <fieldx> = 'X'.
    else.
      <fieldx> = <field>.
  endif.
endwhile.

Если поле непустое и является флагом обновления, то туда запишется Х, иначе значение аналогичного поля в структуре (например ключ в случае табличных строк).


Пометить тему как нерешенную
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация кода
СообщениеДобавлено: Ср, фев 13 2019, 10:00 
Гуру-эксперт
Гуру-эксперт
Аватара пользователя

Зарегистрирован:
Чт, ноя 11 2004, 17:25
Сообщения: 3093
Пол: Мужской
Sam Stone написал(а):
Code:
while sy-subrc = 0.
  data(index) = sy-index.
  assign component index of structure i_poheader to field-symbol(<field>).
  check sy-subrc = 0.
  if <field> is not initial.
    assign component index of structure i_poheaderx to field-symbol(<fieldx>).
    if cl_abap_typedescr=>describe_by_data( <fieldx> )->get_relative_name( ) = 'BAPIUPDATE'.
      <fieldx> = 'X'.
    else.
      <fieldx> = <field>.
  endif.
endwhile.


Если на то пошло, то рекомендую "заходить" не по индексу, а по имени поля. Имена можно получить через CL_ABAP_STRUCTDESCR.


Пометить тему как нерешенную
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация кода
СообщениеДобавлено: Ср, фев 13 2019, 13:31 
Гуру-модератор
Гуру-модератор
Аватара пользователя

Зарегистрирован:
Вт, май 17 2005, 14:35
Сообщения: 4497
Откуда: Москва
Поля для бапи удобно примерно так заполнять
Code:
DEFINE set_x.
  &1-&2 = &3.
  &1X-&2 = 'X'.
END-OF-DEFINITION.

set_x i_poheader comp_code '1000'.
set_x i_poheader purch_org 'PO01'.

В два раза меньше строк кода и гарантировано не забудете проставить X.

_________________
Удача - результат нашего желания (© А. Нортон)


Пометить тему как нерешенную
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация кода заполнения BAPI
СообщениеДобавлено: Ср, фев 13 2019, 19:13 
Начинающий
Начинающий

Зарегистрирован:
Вт, фев 12 2019, 18:37
Сообщения: 5
Большое всем спасибо за предложенные варианты!
Но мне пока оно все не по плечу, так что я пока руками все пронабираю ))


Я не знаю в тему ли, но я не понимаю, как мне загрузить таблицу с данными в BAPI?
По идее я должен считать Purchase Order (PO) из системы, но система временно в ремонте. Я заранее сохранил все данные в excel и теперь хочу подать все это на 'BAPI_PO_GETDETAIL'.

Какия я вижу варианты:
1. В дебаггере каждый раз вручную загружать данные из экселя в таблицу/структуру. Но это очень муторно и скучно.
2. Загрузить эксель через знакомые всем 'ALSM_EXCEL_TO_INTERNAL_TABLE' или 'TEXT_CONVERT_XLS_TO_SAP', но там он на выходе выдает мне свою структуру и снова проблема в том, что я не могу это подогнать под нужную мне BAPIEKPO. Плюс сюда же вылазит ошибка с просьбой указать актуальную дату (FK888). И это я пытаюсь подстроить через
Code:
wa_datatab-CHANGED_ON = sy-datum.   " если это вообще правильное поле
append wa_datatab to it_datatab

- но все тщетно и получаю снова ту же ошибку.

Где не смотрю примеры - везде просто базовый вариант этиx fm и не понятно как это имплементировать в свой код.

Понимаю, что я далеко не первый с этими проблемами - отправьте, пожалуйста, по адресу где читать.

Полурабочий код для наглядности:
Code:
REPORT z_convert_excel_sap.

PARAMETERS: p_file TYPE  rlgrap-filename.
PARAMETERS: p_head TYPE char01 DEFAULT 'X'.


DATA: it_datatab2 TYPE STANDARD TABLE OF bapiekpo,
      wa_datatab2  TYPE bapiekpo.

DATA: it_raw TYPE truxs_t_text_data.

* At selection screen
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
  CALL FUNCTION 'F4_FILENAME'
    EXPORTING
      field_name = 'P_FILE'
    IMPORTING
      file_name  = p_file.

START-OF-SELECTION.
  " Convert Excel Data to SAP internal Table Data

" Datum!!
wa_datatab2-CHANGED_ON = sy-datum.
append wa_datatab2 to it_datatab2.

  CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP'
    EXPORTING
*     I_FIELD_SEPERATOR    =
      i_line_header        = p_head
      i_tab_raw_data       = it_raw       " WORK TABLE
      i_filename           = p_file
    TABLES
      i_tab_converted_data = it_datatab2[]  "ACTUAL DATA
    EXCEPTIONS
      conversion_failed    = 1
      OTHERS               = 2.

  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.


***********************************************************************
* END-OF-SELECTION.
END-OF-SELECTION.
  " For sample, Excel Data transfered to internal table is displayed with write
  LOOP AT it_datatab2 INTO wa_datatab2.
    WRITE:/ wa_datatab2-po_number,
                  wa_datatab2-po_item,
                  wa_datatab2-material,
                  wa_datatab2-co_code,
                  wa_datatab2-plant,
                  wa_datatab2-store_loc,
                  wa_datatab2-net_price,
                  wa_datatab2-price_unit,
                  wa_datatab2-net_value,
                  wa_datatab2-tax_code,
                  wa_datatab2-funds_ctr.
    ENDLOOP.


Пометить тему как нерешенную
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Оптимизация кода заполнения BAPI
СообщениеДобавлено: Чт, фев 14 2019, 11:48 
Гуру-эксперт
Гуру-эксперт
Аватара пользователя

Зарегистрирован:
Чт, ноя 11 2004, 17:25
Сообщения: 3093
Пол: Мужской
Сумбур у Вас какой то...

Цитата:
Я не знаю в тему ли, но я не понимаю, как мне загрузить таблицу с данными в BAPI?
По идее я должен считать Purchase Order (PO) из системы, но система временно в ремонте. Я заранее сохранил все данные в excel и теперь хочу подать все это на 'BAPI_PO_GETDETAIL'.


В заключается задача?

Почитайте про cl_gui_frontend_services=>gui_upload, примеров куча, самое простое через тхт, но он и excel может загрузить.


Пометить тему как нерешенную
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация кода заполнения BAPI
СообщениеДобавлено: Чт, фев 14 2019, 13:29 
Старший специалист
Старший специалист

Зарегистрирован:
Чт, май 12 2011, 17:06
Сообщения: 269
KG написал(а):
...не понимаю, как мне загрузить таблицу с данными в BAPI?
Если имеется в виду передать параметры (в т.ч. таблицы) какой-то БАПИ для тестирования:
1) se37, заполнить параметры, сохранить вариант (Ctrl+S), выбирать его через "Test data directory", вносить нужные изменения и запускать. Годится, если параметров или изменений для варианта не много.
2) писать отдельную программу (или подпрограмму/ФМ/метод). Загружать данные из файла - универсально, но для отдельной БАПИ - немножко очень трудоемко. Это разве что тестирование будет происходить на регулярной основе. Или если создать какой-нибудь универсальный инструмент для каких угодно БАПИшек. Имхо, для ограниченного количества тестов проще бОльшую часть (или даже все) захардкодить. Т.е. схема: селекшн-скрин с небольшим количеством полей -> передача этих полей в параметры БАПИ, остальное хардкодится -> вызов БАПИ. Если известно, какая БАПИ обязана использоваться в программе, для тестирования БАПИ можно использовать черновой вариант программы.


Пометить тему как нерешенную
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация кода заполнения BAPI
СообщениеДобавлено: Чт, фев 14 2019, 14:22 
Начинающий
Начинающий

Зарегистрирован:
Пн, сен 03 2012, 12:12
Сообщения: 22
Пол: Мужской
писал очень давно, используется на нескольких проектах, пользуйтесь на здоровье )))

Code:
class ZCLBC_UTILS definition
  public
  final
  create public .

public section.
  type-pools ABAP .

  class-methods FILL_BAPIX
    importing
      value(IS_DATA) type ANY
      value(IS_OLD_DATA) type ANY optional
    changing
      !CS_DATAX type ANY
    raising
      ZCX_MESS_ERROR .
  class-methods FILL_BY_ELEMENT
    importing
      !IS_DATA type ANY
      !IO_FROM type ref to CL_ABAP_STRUCTDESCR optional
      !IO_TO type ref to CL_ABAP_STRUCTDESCR optional
    changing
      !CS_DATA type ANY
    raising
      ZCX_MESS_ERROR .
protected section.
private section.
ENDCLASS.



CLASS ZCLBC_UTILS IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCLBC_UTILS=>FILL_BAPIX
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_DATA                        TYPE        ANY
* | [--->] IS_OLD_DATA                    TYPE        ANY(optional)
* | [<-->] CS_DATAX                       TYPE        ANY
* | [!CX!] ZCX_MESS_ERROR
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD fill_bapix.

  DATA: lo_fail TYPE REF TO cx_root,
        lo_data TYPE REF TO cl_abap_structdescr,

        ls_comp TYPE abap_compdescr,
        lo_type TYPE REF TO cl_abap_typedescr.

  FIELD-SYMBOLS: <f_field>     TYPE any,
                 <f_old_field> TYPE any,
                 <f_field_x>   TYPE any.

  TRY .
      lo_data   ?= cl_abap_typedescr=>describe_by_data( is_data ).

      LOOP AT lo_data->components INTO ls_comp.
        UNASSIGN: <f_field>, <f_old_field>, <f_field_x>.

        ASSIGN COMPONENT ls_comp-name OF STRUCTURE is_data TO <f_field>.
        CHECK sy-subrc IS INITIAL AND <f_field> IS ASSIGNED.

        ASSIGN COMPONENT ls_comp-name OF STRUCTURE cs_datax TO <f_field_x>.
        CHECK sy-subrc IS INITIAL AND <f_field_x> IS ASSIGNED.

        IF cl_abap_typedescr=>describe_by_data( <f_field> )->absolute_name EQ cl_abap_typedescr=>describe_by_data( <f_field_x> )->absolute_name.
          <f_field_x> = <f_field>.
        ELSE.
          IF is_old_data IS SUPPLIED.
            ASSIGN COMPONENT ls_comp-name OF STRUCTURE is_old_data TO <f_old_field>.
            CHECK sy-subrc IS INITIAL AND <f_old_field> IS ASSIGNED.
            CHECK <f_field> NE <f_old_field>.
          ELSE.
            CHECK <f_field> IS NOT INITIAL.
          ENDIF.
          <f_field_x> = 'X'.
        ENDIF.

      ENDLOOP.

    CATCH cx_root INTO lo_fail.
      RAISE EXCEPTION TYPE zcx_mess_error
        EXPORTING
          previous = lo_fail.
  ENDTRY.

ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCLBC_UTILS=>FILL_BY_ELEMENT
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_DATA                        TYPE        ANY
* | [--->] IO_FROM                        TYPE REF TO CL_ABAP_STRUCTDESCR(optional)
* | [--->] IO_TO                          TYPE REF TO CL_ABAP_STRUCTDESCR(optional)
* | [<-->] CS_DATA                        TYPE        ANY
* | [!CX!] ZCX_MESS_ERROR
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD fill_by_element.

  TYPES: BEGIN OF lt_s_descr,
           stru  TYPE abap_abstypename,
           index TYPE i,
           field TYPE abap_compdescr-name,
           type  TYPE abap_abstypename,
         END OF lt_s_descr.
  STATICS lst_buff TYPE SORTED TABLE OF lt_s_descr WITH UNIQUE KEY stru index
                        WITH NON-UNIQUE SORTED KEY type COMPONENTS stru type.

  DATA: lo_data  TYPE REF TO cl_abap_structdescr,
        ls_descr TYPE lt_s_descr,
        li_from  TYPE TABLE OF lt_s_descr,
        li_to    TYPE TABLE OF lt_s_descr.
  FIELD-SYMBOLS: <f_field> TYPE any,
                 <f_copy>  TYPE any.

  TRY .
      IF io_from IS BOUND.
        lo_data = io_from.
      ELSE.
        lo_data ?= cl_abap_typedescr=>describe_by_data( is_data ).
      ENDIF.
      LOOP AT lst_buff
          INTO ls_descr
          WHERE stru = lo_data->absolute_name.
        APPEND ls_descr TO li_from.
      ENDLOOP.
      IF NOT sy-subrc IS INITIAL.
        LOOP AT lo_data->components
            INTO DATA(ls_comp).
          CLEAR ls_descr.
          ls_descr-stru = lo_data->absolute_name.
          ls_descr-index = sy-tabix.
          ls_descr-field = ls_comp-name.
          ASSIGN COMPONENT ls_comp-name OF STRUCTURE is_data TO <f_field>.
          ls_descr-type = cl_abap_typedescr=>describe_by_data( <f_field> )->absolute_name.
          INSERT ls_descr INTO TABLE lst_buff.
          APPEND ls_descr TO li_from.
        ENDLOOP.
      ENDIF.
      IF io_to IS BOUND.
        lo_data = io_to.
      ELSE.
        lo_data ?= cl_abap_typedescr=>describe_by_data( cs_data ).
      ENDIF.
      LOOP AT lst_buff
          INTO ls_descr
          WHERE stru = lo_data->absolute_name.
        APPEND ls_descr TO li_to.
      ENDLOOP.
      IF NOT sy-subrc IS INITIAL.
        LOOP AT lo_data->components
            INTO ls_comp.
          CLEAR ls_descr.
          ls_descr-stru = lo_data->absolute_name.
          ls_descr-index = sy-tabix.
          ls_descr-field = ls_comp-name.
          ASSIGN COMPONENT ls_comp-name OF STRUCTURE cs_data TO <f_field>.
          ls_descr-type = cl_abap_typedescr=>describe_by_data( <f_field> )->absolute_name.
          INSERT ls_descr INTO TABLE lst_buff.
          APPEND ls_descr TO li_to.
        ENDLOOP.
      ENDIF.
      SORT li_to BY type index."берем первое в структуре по типу
      LOOP AT li_from
          INTO ls_descr.
        READ TABLE li_to
            WITH KEY type = ls_descr-type
            BINARY SEARCH
            INTO DATA(ls_to)
            TRANSPORTING field.
        CHECK sy-subrc IS INITIAL.
        READ TABLE li_to
            WITH KEY type = ls_descr-type
                     field = ls_descr-field
            INTO ls_to
            TRANSPORTING field."если полей с один типом несколько, то по имени поля приоритет
        ASSIGN COMPONENT ls_descr-field OF STRUCTURE is_data TO <f_field>.
        ASSIGN COMPONENT ls_to-field OF STRUCTURE cs_data TO <f_copy>.
        <f_copy> = <f_field>.
      ENDLOOP.
    CATCH cx_root INTO DATA(lo_fail).
      RAISE EXCEPTION TYPE zcx_mess_error
        EXPORTING
          previous = lo_fail.
  ENDTRY.

ENDMETHOD.
ENDCLASS.


есть, что оптимизировать, но смысл общий понятен )

FILL_BAPIX для заполнение X-структур (передается: структура данных "как есть", структура данных "как было" (опционально, если не передать, то будут помечены все заполненные поля))
используется потом примерно так:
Code:
***SKIP***

        CALL METHOD zclbc_utils=>fill_bapix
          EXPORTING
            is_data     = ls_header
            is_old_data = ls_header_old
          CHANGING
            cs_datax    = ls_headerx.

        ls_headerx-updateflag = 'U'.

***SKIP***

        CALL FUNCTION 'BAPI_SALESORDER_CHANGE'
          EXPORTING
            salesdocument    = me->m_vbeln
            order_header_in  = ls_header
            order_header_inx = ls_headerx
***SKIP***


FILL_BY_ELEMENT как бонус, для заполнения всяких структур и автоматического заполнения, типа BAPISDHD/VBAK -> BAPISDHD1 и т.п.


Пометить тему как нерешенную
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация кода заполнения BAPI
СообщениеДобавлено: Пн, фев 18 2019, 17:45 
Начинающий
Начинающий

Зарегистрирован:
Вт, фев 12 2019, 18:37
Сообщения: 5
Всем большое спасибо за отзывчивость!


Пометить тему как нерешенную
Вернуться к началу
 Профиль Отправить email  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Часовой пояс: UTC + 4 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: Ahrefs [Bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB