В SAP NetWeaver есть функционал для использования длинных текстов (более 100 символов и даже более 1000 😊). более технически корректное название sapscript text или, иногда, стандартные тексты.
Длинный текст может использоваться в качестве шаблонов в письмах, печатных формах, формировании договоров и любых других сущностей, где может быть «многабукав».
В одной из следующих статей мы детально разберем, как можно использовать шаблонизацию (это было пожелание одного из слушателей ABAP FIleOS) для писем на основе длинных текстов, а в этой статей покажем, как можно создать длинный текст с вложенными частями и как их прочитать в ABAP (по сути, базовые операции с сапскрипт).
Итак, пусть у нас имеется следующий текст, разделенный на логические части (а точнее 4 части).
Вводная часть текста, поясняющая про чего этот текст (например, тип договора и предмет договора; приветствие в письме и т.д.). Какой-то блок, который по форме одинаков для многих текстов, но отличается лишь некоторыми данными (например, участники договора купли-продажи; письмо, содержащее информацию о заказе/клиенте и т.д.) Поясняющая часть (которая может быть вообще разная для разных даже однотипных текстов). Завершающая часть в тексте, которая может повторяться для нескольких текстов. |
Работа с составным длинным текстом (INCLUDE и копирование текстов)
Теперь я сделаю длинный текст в транзакции SO10, разбив текст также на 4 части. Для этого запускаю транзакцию SO10. Текст назову ZSD_MAIL_ORDER_CREATED_ALL.
Для наполнения содержим я буду использовать старый редактор (и, да я считаю его очень удобным для данных целей). Чтобы сменить/установить редактор используйте пункт меню Goto -> Change Editor/Configure Editor.
Для разделения текста на части я использую команду :/ (двоеточие и слэш) и укажу тексты, которые будут являться составными частями моего составного текста (самих текстов еще нет; я их сделаю следующим шагом также через транзакцию SO10).
Следующим шагом я создам каждый из указанных текстов через транзакцию SO10: ZSD_MAIL_ORDER_CREATED_01, ZSD_MAIL_ORDER_CREATED_02, ZSD_MAIL_ORDER_CREATED_03, ZSD_MAIL_ORDER_CREATED_04. На скриншотах ниже показано наполнение каждого из этих текстов.
В моем случае было удобно вводить текст простым вводом, однако полезно иметь ввиду функцию загрузки и выгрузки текста из файла, из другого текста и из буфера.
Для вставки текста из файла, меню: Text -> Upload/Download
Для загрузки текста из другого стандартного текста, меню: Insert -> Text -> Standard
Затем указываем параметры текста (можем вставить как ссылку на текст, так и его содержимое через галку «Expand Immediately»).
С помощью кнопки Выделить / F2, мы можем выделить строки текста и отправить его в буфер (в один из 5 буферов – то есть мы можем сделать за один раз сразу 5 выделений текста – ворду и не снилось…; относительно недавно с этим начала справляться windows и то только с помощью доп.ПО 😊 ).
После выделения нужных строк – они посинеют (цвет SAP). И их можно запомнить в буфере.
А затем (в другом тексте) мы можем извлечь скопированные строки из буфера
Просмотреть общий итог всего составного текста можно через предпросмотр.
Видим, что система отображает именно содержимое вложенных текстов, а не INCLUDE с командами. И это полезно.
Чтение составных длинных текстов через ABAP
Итак, мы сделали составной текст, а также наполнили каждую часть содержимым. Как считать этот текст через ABAP/4 ?
Полный текст программы. Нам нужно 3 шага:
1) Считаем длинные тексты при помощи функ.модуля READ_TEXT
2) Заменим INCLUDE в составном тексте через функц.модуль TEXT_INCLUDE_REPLACE
3) Затем заменим управляющие конструкции (если таковые есть) с помощью ФМа TEXT_CONTROL_REPLACE.
На экран выведем получившуюся строку через CL_ABAP_BROWSER.
DATA ls_txt_head_in TYPE thead. DATA ls_txt_head_out TYPE thead. DATA lt_txt_lines TYPE tline_tab. DATA lv_txt_full_str TYPE string. DATA lv_txt_full_html TYPE string. ls_txt_head_in-tdid = p_tdid. ls_txt_head_in-tdspras = p_langu. ls_txt_head_in-tdobject = p_tdobj. ls_txt_head_in-tdname = p_tdname. _read_text_lines( EXPORTING is_txt_head = ls_txt_head_in IMPORTING es_txt_head = ls_txt_head_out et_txt_lines = lt_txt_lines ). CASE abap_true. WHEN do_html. _convert2html( EXPORTING is_txt_head = ls_txt_head_out CHANGING ct_txt_lines = lt_txt_lines cv_txt_str = lv_txt_full_html ). _show_string( EXPORTING iv_str_show = lv_txt_full_html iv_no_wrap = abap_true ). WHEN OTHERS. _replace_include_n_controls( CHANGING cs_txt_head = ls_txt_head_out ct_txt_lines = lt_txt_lines ). _convert2string( CHANGING ct_txt_lines = lt_txt_lines cv_txt_str = lv_txt_full_str ). _show_string( lv_txt_full_str ). ENDCASE.
METHOD _replace_include_n_controls. DATA lv_was_changed_replace TYPE abap_bool. DATA lv_was_changed_control TYPE abap_bool. IF ct_txt_lines IS INITIAL. RETURN. ENDIF. CALL FUNCTION 'TEXT_INCLUDE_REPLACE' EXPORTING header = cs_txt_head IMPORTING changed = lv_was_changed_replace newheader = cs_txt_head TABLES lines = ct_txt_lines. CALL FUNCTION 'TEXT_CONTROL_REPLACE' EXPORTING header = cs_txt_head IMPORTING changed = lv_was_changed_control newheader = cs_txt_head TABLES lines = ct_txt_lines. ENDMETHOD.
Также хотел бы обратить внимание на конвертацию длинного текста в формат HTML. Если HTML – это то, для чего Вы хотите использовать шаблон, то можете использовать ФМ CONVERT_ITF_TO_HTML. Подстановку и замену управляющих конструкций этот ФМ делает автоматически (при указании параметра 😊 ) (листинг3).
METHOD _convert2html. "CHANGING ct_txt_lines TYPE tline_tab " cv_txt_str TYPE string. DATA lt_htmlline TYPE htmltable. FIELD-SYMBOLS <fs_html_line> TYPE htmlline. CLEAR cv_txt_str . CALL FUNCTION 'CONVERT_ITF_TO_HTML' EXPORTING * i_codepage = " Target character set i_header = is_txt_head " Text header of input text * i_page = space " Page specification for page window format * i_window = space " Window specification for page window format * i_syntax_check = space " Activating the ITF syntax check * i_replace = 'X' " Expanding symbols and includes * i_print_commands = space " Outputting commands and text elements * i_html_header = 'X' " Output of the HTML header tag * i_funcname = space " Exit module for link interpretation * i_title = space " Title in HTML header * i_background = space " File name for HTML image as background * i_bgcolor = space " Background color of text * i_unescape_formats = " Exception Formats for Masking Special Characters * i_escape_spaces = space " Masking of Blank Characters * i_encoding = space " Define Character Set Coding in Header * IMPORTING * e_html_text = " Text Content in HTML as Xstring TABLES t_itf_text = ct_txt_lines " Text lines in ITF (input) t_html_text = lt_htmlline " Text lines in HTML (output) * t_conv_charformats = " Table for character formats * t_conv_parformats = " Table for paragraph formats EXCEPTIONS syntax_check = 1 " Incorrect inout text ITF syntax replace = 2 " Errors expanding includes and symbols illegal_header = 3 " Text header incorrect OTHERS = 4. IF sy-subrc <> 0. * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ENDIF. LOOP AT lt_htmlline ASSIGNING <fs_html_line>. IF cv_txt_str IS INITIAL. cv_txt_str = <fs_html_line>-tdline. ELSE. cv_txt_str = cv_txt_str && <fs_html_line>-tdline. ENDIF. ENDLOOP. ENDMETHOD.
Установка переменных
Конечно, никакие шаблоны не используются как статичные тексты. Одна из важных причин существования шаблонов (а в данном случае мы рассматриваем сапскрипт как шаблоны) – это возможность наполняться переменными данными. Давайте попробуем наполнить наш текст переменными. Переменные в текстах сапскрипт бывают трёх видов: системные, программные (класс, группа функций, исполняемая программа – это программы) и стандартные.
Давайте добавим в наш текст переменные. Синтаксис символов-переменных такой &SOME_VAR&. (подробнее тут). При использовании переменных полезно иметь ввиду опции форматирования: опции позволяют использовать нужный формат даты, времени; не выводить пустые переменные, добавлять пре- и пост- тексты к переменным и другие возможности (подробнее тут).
Добавим в текст ZSD_MAIL_ORDER_CREATED_02 переменные:
* |
Какой-то блок, который по форме одинаков для многих текстов |
* |
, но отличается лишь некоторыми данными (например, |
* |
участники договора купли-продажи; письмо, содержащее информацию |
* |
о заказе/клиенте и т.д.) |
* |
|
* |
Текущая дата: &DATE& |
* |
SYREPID: &SY-REPID& |
* |
|
* |
Переменная из объекта: |
* |
S-V1: &S-V1& |
* |
&’S-V2: ‘S-V2& |
/: |
IF &S-V3& EQ ‘СОЛОВЕЙ’. |
* |
LLM-алгоритм говорит, что речь о птицах. |
/: |
ENDIF. |
В данном тексте мы вывели дату через переменную &DATE& (она доступна в любом тексте); вывели имя отчета через &SY-REPID&, а также вывели значения переменных из той, программы, которая будет читать текст.
Переменная в тексте |
Пояснение |
&S-V1& |
Выводит значение переменной S-V1. То есть где-то в программе есть структура S (одна буква для краткости), а в ней есть поле V1. Строка будет выведена в любом случае даже если переменная пустая |
&’S-V2: ‘S-V2& |
В этом случае мы имеем пре-текст, то есть строчка не будет выведена, если переменная пустая |
IF &S-V3& EQ ‘СОЛОВЕЙ’. |
А такие конструкции позволяет дорабатывать части шаблона с помощью проверки условий через IF. |
Обратим внимание, что для замены именно переменных мы используем функциональный модуль: TEXT_SYMBOL_REPLACE. В качестве параметра передаем ему имя той программы (как правило, вызывающей, которая содержит переменные для шаблона).
REPORT zrep_c8a014_long_txt_symb. TYPES: BEGIN OF ts_model , v1 TYPE string , v2 TYPE string , v3 TYPE string , v4 TYPE string , END OF ts_model . PARAMETERS: p_tdname TYPE thead-tdname DEFAULT 'ZSD_MAIL_ORDER_CREATED_ALL' , p_tdobj TYPE thead-tdid DEFAULT 'TEXT' , p_tdid TYPE thead-tdid DEFAULT 'ST' , p_langu TYPE sylangu DEFAULT 'RU' . START-OF-SELECTION. DATA lv_txt TYPE string. DATA ls_txt_h TYPE thead. data s TYPE ts_model. ls_txt_h-tdid = p_tdid. ls_txt_h-tdspras = p_langu. ls_txt_h-tdobject = p_tdobj. ls_txt_h-tdname = p_tdname. s-v1 = 'Переменная V1'. s-v2 = 'Вторая переменная'. s-v3 = 'СОЛОВЕЙ'. lv_txt = NEW zcl_c8a014_long_text( sy-cprog )->r( ls_txt_h ). DATA lv_as_html_out TYPE string. lv_as_html_out = | <html dir="ltr" lang="ru"> | && |<head> <meta charset="UTF-8">| && |<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">| && |<title>ABAP String Show </title>| && |</head> <body>| && |<div> { lv_txt } </div>| && |</body> </html>| . cl_abap_browser=>show_html( EXPORTING html_string = lv_as_html_out " HTML String ).
Код класса ZCL_C8A014_LONG_TEXT доступен по ссылке. Текст программе в той же папке на github.
Таким образом, мы можем использовать длинные тексты в качестве шаблона.
Перенос текстов через транспортный запрос
Длинные тексты автоматически не вносятся в запрос. Однако в случае необходимости, их можно положить в запрос принудительно, сделав следующую запись в транспортном запросе.
R3TR TEXT TEXT, ZSD_MAIL_ORDER_CREATED_02,ST,R
В документации также, в качестве альтернативы ручному добавлению, обозначены две программы ( RSTXR3TR и RSTXSCRP) и рекомендация обратиться к справке.
Заключение
Сапскрипт-тексты можно использовать в качестве шаблонов. С их помощью можно сделать вложенный шаблон, наполнить его переменными и условными конструкциями. Однако, не стоит забывать про перенос текстов – автоматически тексты в запрос не добавляются. А также факт того, что сапскрипт-тексты хранятся в неструктурированном виде в рамках оперативной базы. В следующих статьях мы рассмотрим, как можно нарисовать «стилизованное письмо с картинками» на основе сапскрипта, а также альтернативы сапскрипту для ведения шаблонов.
ссылка на оригинал статьи https://habr.com/ru/articles/841422/
Добавить комментарий