Posted: Thu Mar 22, 2012 1:30 am Post subject: Выгрузка произвольного отчета в Excel за 15 минут
Разработка пошла в продуктив банков и предприятий, получил feedback, решено было переписать начисто красиво и правильно. Теперь это процедура на 200 строчек и никаких ручных действий.
соглашение по переменным:
-все переменные используемые в отчете должны быть определены глобально
-таблицы используемые в отчете должны быть без headerline.
соглашение по заполнению шаблона:
-если в отчете используются таблицы то первый столбец должен содержать либо текст либо 1 пробел,иначе отчет не откроется.
- одна переменная на ячейку
- переменная заключается в $# $#, например $#sy-uname$#
- строка содержащая ячейки таблицы должна содержать текст $!$Table_name$!$, где Table_name имя внутренней таблицы определенной глобально без headerline
- ячейки таблицы содержат переменные $#<wa>-field1$# $#<wa>-field2$# $#<wa>-field3$# и т.д., где field1 field2 field3 имена полей таблицы
- перед сохранением установить курсор в поле А1
шаблон сохраняем как таблица xml 2003
идем в транзакцию smw0 выбираем двоичные данные для WEB RFC приложений, F8, F8, параметры настройки->ведение MIME типов, добавить туда *.xml .
загружаем шаблон, выбираем имя.
в программе когда все переменные посчитаны вызвать форму
Code:
PERFORM export_to_excel TABLES it_source USING 'Z_TEST_EXPORT_TO_EXCEL'.
в таблице it_source находится сгенерированный xml документ, Z_TEST_EXPORT_TO_EXCE - имя шаблона.
тестовый шаблон в приложении test.xml,
рабочий легкоадоптируемый пример ниже, впримере показано как правильно выгрузить xml документ в кодировке utf-8 и избежать проблем с конвертацией.
Генерировать xml отчеты на ABAP - это как генерировать html странички на PHP: нет в этом ничего страшного и интересного.
парсер странно работает,и покорежил текст программы, прикладываю в приложении sample.rar
Code:
program xz.
types
: tt_string TYPE STANDARD TABLE OF string
.
TABLES
: TADIR
.
data
: gt_outtab type table of TADIR
, it_source TYPE TABLE OF string
, code type CPCODEPAGE
, CODEPAGE TYPE ABAP_ENCODING
.
*выбираем данные
select * from TADIR into table gt_outtab up to 5 rows.
* генерируем XML
PERFORM export_to_excel TABLES it_source USING 'Z_TEST_EXPORT_TO_EXCEL'.
form export_to_excel TABLES it_source type tt_string using IV_OBJID TYPE W3OBJID .
data
: KEY type WWWDATATAB
, HTML LIKE W3HTML OCCURS 100 WITH HEADER LINE
, MIME LIKE W3mime OCCURS 100 WITH HEADER LINE
, lv_tabname type string
, lt_bufer TYPE TABLE OF string WITH HEADER LINE
, wa_bufer type string
, lt_string TYPE TABLE OF string
, lv_str TYPE string
, lv_str2 TYPE string
, lv_str3 TYPE string
, lv_string type string
.
CONSTANTS
: lc_lt(4) VALUE '<'
, lc_gt(4) VALUE '>'
.
FIELD-SYMBOLS
: <field>
, <table> TYPE ANY TABLE
, <wa>
.
define process_buffer.
LOOP AT lt_bufer INTO wa_bufer .
find REGEX '(\$#(.*)\$#)' in wa_bufer SUBMATCHES lv_str lv_str2.
IF sy-subrc = 0.
REPLACE lc_lt in lv_str2 WITH '<'.
REPLACE lc_gt in lv_str2 WITH '>'.
ASSIGN (lv_str2) to <field>.
lv_str3 = <field>.
REPLACE REGEX '(\$#(.*)\$#)' in wa_bufer WITH lv_str3.
APPEND wa_bufer to it_source.
else.
APPEND wa_bufer to it_source.
ENDIF.
ENDLOOP.
end-of-DEFINITION.
define flush.
" if tabname defined - loop at table
IF lv_tabname is not INITIAL.
ASSIGN (lv_tabname) to <table>.
LOOP AT <table> ASSIGNING <wa>.
process_buffer.
ENDLOOP.
else.
process_buffer.
ENDIF.
clear lv_tabname.
REFRESH lt_bufer.
end-of-DEFINITION.
" get key of object
SELECT single * FROM WWWDATA AS F INNER JOIN TADIR AS P
ON F~OBJID = P~OBJ_NAME
INTO CORRESPONDING FIELDS OF KEY
WHERE F~SRTF2 = 0
AND F~RELID = 'MI'
AND P~PGMID = 'R3TR'
AND P~OBJECT = 'W3MI'
AND P~OBJ_NAME = IV_OBJID .
" get object
CALL FUNCTION 'WWWDATA_IMPORT'
EXPORTING
KEY = KEY
TABLES
HTML = HTML
MIME = MIME
EXCEPTIONS
OTHERS = 1.
" convert raw data to string
CALL FUNCTION 'WSI_RAW_TO_STRING'
IMPORTING
OUTPUT = lv_string
TABLES
INPUT = MIME
EXCEPTIONS
CONVERTION_FAILURE = 1
OTHERS = 2.
IF SY-SUBRC <0>CR_LF INTO TABLE lt_string.
" process template
REFRESH it_source.
LOOP AT lt_string INTO lv_string .
REPLACE ALL OCCURRENCES OF '''' IN lv_string WITH ''''''.
find regex '(ss:ExpandedRowCount="\d+")' in lv_string SUBMATCHES lv_str lv_str2.
IF sy-subrc = 0.
REPLACE REGEX '(ss:ExpandedRowCount="\d+")' in lv_string WITH ''.
ENDIF.
" find table name
find REGEX '(\$!\$(.*)\$!\$)' in lv_string SUBMATCHES lv_str lv_str2.
IF sy-subrc = 0.
REPLACE REGEX '(\$!\$(.*)\$!\$)' in lv_string WITH ''.
lv_tabname = lv_str2.
ENDIF.
" new row occured, process buffer
find regex '(<Row)' in lv_string .
IF sy-subrc = 0.
flush.
ENDIF.
"reach end of row, add last line to buffer and process buffer
find regex '(</Row>)' in lv_string.
IF sy-subrc = 0.
APPEND lv_string to lt_bufer.
flush.
else.
APPEND lv_string to lt_bufer.
ENDIF.
ENDLOOP.
flush.
endform.
----------------------------------------старая версия---------------------------------------------
небольшая программа и последовательность шагов как выгрузить произвольный отчет в Excel.
Сам этим методом пользуюсь уже около 2-х лет, это модифицированный вариант того что нам принесли и показали, изначальное авторство неизвестно.
Недавно меня спросили как я делаю такие красивые отчеты, и я подумал что это будет полезно еще кому-нибудь.
работает на системах с поддержкой юникода.
Иногда нужно получить красивый отчет для бухгалтерии вроде такого
обычно образец этого отчета приходит в Excel.
открываем шаблон, и заменяем все переменные тексты переменными из программы, завернув их в $#$# например $#sy-datum$#
есть правило по одной переменной на ячейку, если нужно больше собираете заранее в 1-ну переменную и кладете ее в ячейку
первая ячейка каждой строчки должна содержать текст, если текст не нужен, тогда пробел.
в строке которую нужно размножить ставим $!$
играемся со шрифтами, форматом отображения и прочее.
у нас получается такой шаблон
ставим курсор в ячейку а1 и сохраняем как Таблица XML 2003 (*.xml)
полученный файл скармливаем программе Z_ASIKIDIN_TEMP, исходники в архиве, программа простая содержит только текст, запускаем выбираем файл жмем F8.
рядом с файлом появятся 2 файла: один %имя%.txt второй %имя%1.txt
нам нужен второй.
открываем копируем все в какой-нибудь инклюд.
иногда в ячейке много текста что он не помещается в одну строку редактора
в конце строки закрываем кавычку ставим точку, в начале следующей строки добавляем xml_simple '
в том месте где мы ставили $!$ будет длинный комментарий выделено красным, начало и конец строки выделено фиолетовым.
все это дело заворачиваем в loop
для ячеек содержащих дату меняем
perform to_utf CHANGING it_zaaqb-ERSDA .
на
perform date_convert CHANGING it_zaaqb-ERSDA .
в самом конце поменять
xml_download4.
на
xml_download5 'отчет.xls'.
или поменять это в генераторе.
когда нужно распечатать
вызываем инклюд
if pa_print is not INITIAL.
include z_asikidin_report.
endif.
в самом начале нужно подключить 2 инклюда с макросами и переменными, или можно их слить в один
include ZBFI_RES_DEBT_uni. " unicode convert
include ZBFI_RES_DEBT_xml. " export to excel/xml
все отчет готов!
990 строчек кода написано.
исходники и рабочие примеры в архиве
Z_ASIKIDIN_XML - демо пример
инклюды необходимые для работы
ZBFI_RES_DEBT_UNI
ZBFI_RES_DEBT_XML
Никак, средствами моей оазработки, можно сделать в шаблоне условное форматирование и убирать рамки если ячейка пустая
------------
А не наврал, условное флрматирование то в екселе для zwww_openform, в этой разработке быстро не получится.
------------------
Опять наврал можно сделать, для этого нужно заменить стиль ячейки. Для примера sample.rar ss:StyleID="s27" нужно поменять на ss:StyleID="Default"
Никак, средствами моей оазработки, можно сделать в шаблоне условное форматирование и убирать рамки если ячейка пустая
------------
А не наврал, условное флрматирование то в екселе для zwww_openform, в этой разработке быстро не получится.
------------------
Опять наврал можно сделать, для этого нужно заменить стиль ячейки. Для примера sample.rar ss:StyleID="s27" нужно поменять на ss:StyleID="Default"
Рабочий пример будеь позже
в sample.rar ни в программе ни в xml-ке ненашел строки ss:StyleID="s27"
Тут получается как. Из SMW0 тянется файл, туда вставляются значения по переменным. т.е. на этапе формирования файла начит.
А не подскажете, в какую сторону копать в "form export_to_excel" _________________ С уважением, mvs87.
REPLACE REGEX '(\$#(.*)\$#)' in wa_bufer WITH lv_str3.
IF <field> is initial.
BREAK-POINT.
replace 'ss:StyleID="s22"' in wa_bufer with 'ss:StyleID="Default"'.
ENDIF.
не прокатил.
В отладчике менял ss:StyleID="s22" на ss:StyleID="Default"
тож не получается.
может не Default нужно? _________________ С уважением, mvs87.
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG. SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG. Every effort is made to ensure content integrity. Use information on this site at your own risk.