Часть1
Не все знают, что в ALV-отчет можно добавить красивый заголовок на HTML.
Результат будет похож на это:
![](https://habrastorage.org/files/cf5/ead/ec1/cf5eadec1c92495d802de66051cef275.png)
А что если бы хотим нарисовать нечто свое?
Например:
![](https://habrastorage.org/files/069/513/965/069513965fa6427c9c9e1b61ae7b3a99.png)
Добро пожаловать под кат.
Поехали!
Я не нашел в инете, какой-либо инфы, и решил придумать нечто свое.
Стандартный заголовок рисуется примерно так:
FORM do_html_top_of_page USING p_do TYPE REF TO cl_dd_document.
*----------------------------------------------------------------------*
* .DATA
*----------------------------------------------------------------------*
DATA: ta TYPE REF TO cl_dd_table_element,
col1 TYPE REF TO cl_dd_area,
col2 TYPE REF TO cl_dd_area,
col3 TYPE REF TO cl_dd_area,
text TYPE sdydo_text_element,
str TYPE string,
rows TYPE int4.
DEFINE add_column.
call method ta->add_column
exporting
heading = text
importing
column = &1.
clear text.
END-OF-DEFINITION.
DEFINE add_text.
call method &1->add_text
exporting
text = text.
clear text.
END-OF-DEFINITION.
str = 'Параметры отчета:'.
CALL METHOD p_do->add_table
EXPORTING
with_heading = 'X'
no_of_columns = 2
width = '30%'
with_a11y_marks = 'X'
a11y_label = str
IMPORTING
table = ta.
text = 'Параметры отчета:'.
add_column: col1.
text = 'Значения'.
add_column: col2.
text = 'Заказ'.
add_text: col1.
text = gv_aufnr.
add_text: col2.
CALL METHOD ta->new_row.
ADD 1 TO rows.
ENDFORM. "do_html_top_of_page
Что-бы свое было универсально и легко подключалось,
в любой отчет, в котором возможны HTML-заголовки,
обернем это дело в функциональный модуль:
FORM do_html_top_of_page
*&---------------------------------------------------------------------*
USING p_do TYPE REF TO cl_dd_document.
*&---------------------------------------------------------------------*
DATA lt_html TYPE TABLE OF zparam WITH HEADER LINE.
lt_html-param = 'Важность'.
lt_html-value = 'Высокая'.
APPEND lt_html.
lt_html-param = 'Материал'.
lt_html-value = 'Все'.
APPEND lt_html.
lt_html-param = 'Период'.
lt_html-value = '01.01.2015 - 01.03.2016'.
APPEND lt_html.
CALL FUNCTION 'Z_FM_FORM_HTML_TAB'
EXPORTING
it_param = lt_html[]
iv_type = 'DARK'
CHANGING
dd_document = p_do.
ENDFORM.
Структура zparam проста:
PARAM CHAR100
VALUE CHAR100
В ФМ:
сначала заполняем CSS часть,
потом создаем таблицу на HTML,
в конце добавляем в dd_document или его область, если она есть на входе
Функциональный модуль:
FUNCTION z_fm_form_html_tab.
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*" IMPORTING
*" REFERENCE(IT_PARAM) TYPE ZTPARAM
*" REFERENCE(IV_TYPE) TYPE CHAR10
*" CHANGING
*" REFERENCE(DD_DOCUMENT) TYPE REF TO CL_DD_DOCUMENT
*" REFERENCE(DD_AREA) TYPE REF TO CL_DD_AREA OPTIONAL
*"----------------------------------------------------------------------
DATA lt_html TYPE TABLE OF sdydo_html_line WITH HEADER LINE.
DEFINE add_tag.
lt_html = &1.
append lt_html.
END-OF-DEFINITION.
DEFINE conc_tag_line.
concatenate '<td>' &1 '</td>' into lt_html.
append lt_html.
END-OF-DEFINITION.
*"----------------------------------------------------------------------
* Добавим CSS
*"----------------------------------------------------------------------
add_tag '<html>'.
add_tag '<style type="text/css">'.
CASE iv_type.
WHEN 'DARK'.
add_tag 'table {'.
add_tag 'font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif;'.
add_tag 'font-size: 12px;'.
add_tag 'border-collapse: collapse;'.
add_tag 'text-align: center;}'.
add_tag 'th, td:first-child {'.
add_tag 'background: #252F48;'.
add_tag 'color: white;'.
add_tag 'padding: 1px 1px;}'.
add_tag 'th, td {'.
add_tag 'border-style: solid;'.
add_tag 'border-width: 0 1px 1px 0;'.
add_tag 'border-color: white;}'.
add_tag 'td { background: #CAD4D6;}'.
add_tag 'th:first-child, td:first-child {'.
add_tag 'text-align: left;}'.
WHEN 'ZEBRA'.
add_tag 'table {'.
add_tag 'border-spacing: 0;'.
add_tag 'empty-cells: hide;}'.
add_tag 'td {'.
add_tag 'padding: 3px 3px;'. "5
add_tag 'text-align: center;'.
add_tag 'border-bottom: 1px solid #F4EEE8;'.
add_tag 'transition: all 0.5s linear;}'.
add_tag 'td:first-child {'.
add_tag 'text-align: left;'.
add_tag 'color: #3D3511;'.
add_tag 'font-weight: bold;}'.
add_tag 'th {'.
add_tag 'padding: 3px 3px;'. "5
add_tag 'color: #3D3511;'.
add_tag 'border-bottom: 1px solid #F4EEE8;'.
add_tag 'border-top-left-radius: 10px;'.
add_tag 'border-top-right-radius: 10px;}'.
add_tag 'td:nth-child(even)'.
add_tag ' {background: #F6D27E;}'.
add_tag 'td:nth-child(odd)'.
add_tag ' {background: #D1C7BF;}'.
add_tag 'th:nth-child(even) {'.
add_tag 'background: #F6D27E;}'.
add_tag 'th:nth-child(odd)'.
add_tag ' {background: #D1C7BF;}'.
add_tag '.round-top {'.
add_tag 'border-top-left-radius: 10px;}'.
add_tag '.round-bottom {'.
add_tag 'border-bottom-left-radius: 10px;}'.
add_tag 'tr:hover td{'.
add_tag 'background: #D1C7BF;'.
add_tag 'font-weight: bold;}'.
ENDCASE.
add_tag '</style>'.
*"----------------------------------------------------------------------
* Добавим HTML
*"----------------------------------------------------------------------
add_tag '<table>'.
add_tag '<tr>'.
add_tag '<th>Параметры отчета: </th>'.
add_tag '<th>Значение: </th>'.
add_tag '</tr>'.
DATA ls_param LIKE LINE OF it_param.
LOOP AT it_param INTO ls_param.
add_tag '<tr>'.
conc_tag_line: ls_param-param.
conc_tag_line: ls_param-value.
add_tag '</tr>'.
ENDLOOP.
add_tag '</table>'.
add_tag '</html>'.
*"----------------------------------------------------------------------
* Добавим HTML в область или документ
*"----------------------------------------------------------------------
IF dd_area IS NOT INITIAL.
dd_area->add_static_html( table_with_html = lt_html[] ).
ELSE.
dd_document->add_static_html( table_with_html = lt_html[] ).
ENDIF.
ENDFUNCTION.
Напомню получим:
![](https://habrastorage.org/files/069/513/965/069513965fa6427c9c9e1b61ae7b3a99.png)
Минус решения, если у пользователя повышенные настройки безопасности в IE, CSS оформление выводится не будет. Всем спасибо.
Комментарии (24)
ivanbolhovitinov
27.01.2016 07:26О вкусах можно спорить бесконечно.
Я предпочитаю попрощеEndrews
27.01.2016 08:37Иван, буду благодарен, если напишите, как регулировать высоту HTML-заголовка. Как-то смотрел, ничего не нашел и забил. Если параметров не много, можно и сузить, а если много расширить. А так авто-высота.
По второму пункту согласен, надо подумать, что с этим можно сделать, пока в голову не приходило.ivanbolhovitinov
27.01.2016 09:02Насчет высоты: У меня нет готового ответа. Надо экспериментировать, смотреть исходники самого ALV и обёрток, которые вы используете (видимо REUSE_ALV_GRID_DISPLAY_LVC).
Навскидку:
Высота рассчитывается внутри.
Логика у него внутри скорее всего простая (потому что высота регулируется внутри абапа, а у него нет встроенного браузера с линейкой).
ШТМЛ который вы генерируете содержит неожиданные ходы, которая его логика не предусматривает
Варианты:
- Находите код, который считает высоту, делаете выводы
- С самого начала пишете свой враппер на ALV, с вашей логикой, блэкджеком и комбобоксами
- Экспериментально подсовывая разный ШТМЛ выясняете что на него влияет
- Смотрите какой ШТМЛ по факту делают стандартные реализации, например через cl_salv_form_layout_grid, сравниваете со своим
ivanbolhovitinov
27.01.2016 09:15По коду.
Между макросами (define) и любой формой модуляризации кода (подпрограммы, функции, методы) лежит пропасть. Когда-то я давно думал, что макросы — удобный способ не писать слова PERFORM и USING, или какие-то ещё. Это не так.
Вы уверены, что вы действительно хотите ходить такими путями?Endrews
27.01.2016 09:50Да макрос удобен. Только не надо в него заворачивать слишком сложные конструкции.
Вот например код, смотрится органично, на мой взглядDEFINE calc_1milliage. perform calc_one_milliage using <fs_data>-equnr &1 changing &2 &3. add_line: &1 &2 &3. END-OF-DEFINITION. IF lv_read EQ 'X'. READ TABLE st_s835 WITH KEY sernr = <fs_data>-equnr sptag = <fs_data>-gstrp. IF sy-subrc IS INITIAL. <fs_data>-treml = st_s835-treml. <fs_data>-tacml = st_s835-tacml. ELSE. calc_1milliage: <fs_data>-gstrp <fs_data>-treml <fs_data>-tacml. ENDIF. ELSE. calc_1milliage: <fs_data>-gstrp <fs_data>-treml <fs_data>-tacml. ENDIF. .. IF lv_read EQ 'X'. READ TABLE st_s835 WITH KEY sernr = <fs_data>-equnr sptag = <fs_data>-dtnrp. IF sy-subrc IS INITIAL. <fs_data>-tacpp = st_s835-tacml. ELSE. calc_1milliage: <fs_data>-dtnrp lv_treml <fs_data>-tacpp. ENDIF. ELSE. calc_1milliage: <fs_data>-dtnrp lv_treml <fs_data>-tacpp. ENDIF.
Endrews
27.01.2016 09:58Или например очень удобноMETHOD set_col_names . DATA lr_columns TYPE REF TO cl_salv_columns. DATA: lr_column TYPE REF TO cl_salv_column. lr_columns = gr_rep->get_columns( ). lr_columns->set_optimize( abap_true ). * Установим тексты set_names: 'SERNR' 'Вагон' 'Вагон' 'Номер вагона'. set_names: 'SELEC' 'Выбор' 'Выбор' 'Выбор'. set_names: 'ICON' 'Статус' 'Статус' 'Статус'. ... А ведь колонок быть может быть очень много )) ENDMETHOD. ... DEFINE set_names. try. lr_column = lr_columns->get_column( &1 ). lr_column->set_short_text( &2 ). lr_column->set_medium_text( &3 ). lr_column->set_long_text( &4 ). catch cx_salv_not_found. endtry. END-OF-DEFINITION.
kanikeev
27.01.2016 09:42Даа, вы тот еще извращенец…
ABAP — язык бизнес-логики, для красивостей лучше смотреть в сторону bsp, webdynpro или sapui5.
Хотя, что это я? Сам на прошлой неделе верстал html-письма на нем-родимом :)kanikeev
27.01.2016 10:04-1раздутыйкакиндюкабапер mode on*
Куски html/css/шаблоны я храню в SO10 текстах — так проще потом править.
Ваш набор css/html можно было просто загнать в текст и заменой placeholder'ов подставить нужные значения.
Смесь переводимых текстов (параметры отчета) и непероводимых (th) в одном значении — это фу.
Объявление переменных в теле кода, а не в начале — фу (тут так принято). Тогда уж лучше использовать inline объявление, если версия позволяет.
раздутыйкакиндюкабапер mode off*
Не оценивайте мое брюзжание как критику. Дерзайте. Учитесь. Делитесь опытом.
Endrews
27.01.2016 10:11Про SO10 не думал, возможно вариант, но редактирую не часто, сделал CSS-стиль и забыл
Вообще css/html — не большой спец, поэтому тут надо добавлять)ivanbolhovitinov
27.01.2016 10:31А я бы не стал SO10 использовать, оно зависит от языка, в контексте это не факт. Его потом ещё и переносить надо. SMW0 предпочтительней, это объекты разработки на общих условиях.
kanikeev
30.01.2016 09:26-1Я все равно за SO10.
* Многоязычность — то, что надо, так как работаю в многоязычных системах.
* Текст можно поменять прямо в заблокированном для изменений продуктиве при необходимости (не будем спорить на тему безопасность против удобства). Я пишу код, а уж что там функциональщик занесет — его дело.
occam
28.01.2016 17:07-1Бизнес-логика в современном понимании и ABAP — это примерно как оснащение зайца стоп-сигналами :-D
kanikeev
30.01.2016 09:31-1Очень образно, но не совсем понятно, в чем особенность современного понимания бизнес-логики, и чем для этого не годится ABAP.
occam
31.01.2016 20:51-1Особенность, Lieber Sapper, всего лишь в том, что когда в форме 2-НДФЛ появится возможность не заполнять поле ИНН, тогда у пользователя 1С эта опция появится by design, а вот пользователь SAP «побежит» в отдел методологии с просьбой «need update, please!!» Аналогично с появлением формы 6-НДФЛ etc.etc.etc. Не кажется ли Вам, что бегать к аналитикам по любому новому «чиху» госорганов, которые случаются еженедельно, — это очень и очень далеко от логичного бизнеса и бизнес-логики в том числе?
occam
31.01.2016 20:58-1А ключевой смысл в том, что без оперативной методологической поддержки надстройка над учетной системой, маркетологически решающая все бизнес-задачи, на самом деле предстваляется бесполезным форком кобола, так?
kanikeev
01.02.2016 00:34-1Ваш личный неудачный опыт работы с SAP не является отсутствием оперативной методологической поддержки.
occam
01.02.2016 07:22Позвольте спросить, Вы инженер или маркетолог :-D Если первое, то можно ли увидеть гарантии присутствия оперативной Методологической поддержки силами вендора?
И не казалось ли Вам, что ЛЮБОЙ проект по внедрению эсэйпи на 80-90% делается, развивается и поддерживается людьми Заказчика, либо папочка с лицензиями просто пылится на полке у CFO/CIO/CAO? Аналогично: Oracle и AX.kanikeev
01.02.2016 11:45Я — консультант.
Ваш термин Оперативная методологическая поддержка слишком расплывчат и под него отлично подходит поддержка со стороны SAP.
Да — это не миф, да — я с нии работал, да — они помогают. Не совсем доволен их скоростью работы — но об этом уже написал.
По поводу 80-90% — это так. Так просто намного дешевле. А разве 1С сами всегда все внедряют и подерживают?
И опять повторю свой вопрос. Какое отношение имеют ваши претензии к вендору к языку программирования?
kanikeev
01.02.2016 00:32-1Хм… Наверное, я давно не работал с 1С. Во времена семерки тоже ничего не появлялось автоматом — приходили мальчики/девочки и накатывали обновления/пилили конфигурацию. В этом смысле просто те же самые аналитики бегали в бухгалтерию.
Не кажется ли вам, что слишком частые чихи госорганов не являются недостатком программного комплекса, и уж тем более языка программирования. Держите также в уме, что 1C работает исключительно на российский рынок с его реалиями, а SAP — на мировой, и российский далеко не является приоритетным. Это к тому, что на ежедневные чихи каждого ведомства разных государств реагировать сложнее.
Ну это то, что касается программного комплекса, а то, что касается именно языка — не увидел ни одного аргумента.
whydrae
27.01.2016 11:20-2Я бы на вашем месте занимался экспериментами над таблицами в UI5 (sap.ui.table.Table, sap.ui.table.AnalyticalTable) и соответсвующей обвязкой oData и т.п… Альзо, макросы большой не-не и вызывают дикую боль при отладке старых программ. ФМники и перформы уже тоже не советуют использовать, вместо них лучше писать классы и методы (п.с. говорю с колокольники стандарта и гайдлайнов официальных. Другое дело — легаси).
occam
Пасибо. С огромным удовольствием отмечаюсь вплюс, тк впервые вижу не раздутого как индюк «абапера», а спеца, понимающего проблемы и задумающего изменения к лучшему.
ps. Проект внедрения эсэйпи представляю по миллиметру и не вижу особых в нем преимуществ, чем, например, перед внедрением проекта на 1С, кроме разве, что утилизации ячеек памяти