Экспортировать данные из SAP в Excel довольно просто. Ниже описано, как экспортировать таблицу SAP в Excel или экспортировать отчет SAP в Excel с помощью другой процедуры. После выполнения экспорта в SAP Excel вы сможете поэкспериментировать с извлечением данных из SAP с помощью расширенного vlookup в Excel, сравнения строк в Excel, подсчета количества вхождений и других стандартных функций электронных таблиц.
Экспортировать данные из SAP в Excel довольно просто. Ниже описано, как экспортировать таблицу SAP в Excel или экспортировать отчет SAP в Excel с помощью другой процедуры. После выполнения экспорта в SAP Excel вы сможете поэкспериментировать с извлечением данных из SAP с помощью расширенного vlookup в Excel, сравнения строк в Excel, подсчета количества вхождений и других стандартных функций электронных таблиц.
Оказавшись в транзакции отображения таблицы в системе SAP, найдите значок стрелки в верхней части таблицы и щелкните по нему.
Там должна быть опция под названием Spreadsheet.
Выберите эту опцию, сохраните файл локально и откройте его в Excel — электронная таблица на самом деле будет файлом Excel, несмотря на то, что она не вызывается напрямую в SAP.
Онлайн-обучение основным навыкам SAP
Экспорт таблицы в SAP в Excel
Начиная с экрана отображения таблицы, такого как отображение записей транзакции SE16N, с таблицей MARC, выбранной для отображения, данными завода для материала, найдите значок со стрелкой вверху таблицы.
При нажатии на этот значок отобразится раскрывающееся меню с несколькими вариантами загрузки:
- Электронная таблица будет экспортировать данные SAP в Excel,
- обработка текста экспортирует данные SAP в Word,
- локальный файл экспортирует данные в текстовый файл, который можно открыть с помощью Notepad ++ или другого текстового редактора,
- отправка откроет внутренний документ создания SAP и отправит транзакцию,
- сохранение в SAP сохранит данные в SAP,
- ABC анализ покажет некоторые графики,
- HTML скачать предложит данные для загрузки в HTML-файл для отображения в браузере или опубликовать в Интернете.
Чтобы экспортировать данные SAP в Excel, выберите параметр «Электронная таблица».
Параметры экспорта из SAP в электронную таблицу
После выбора экспорта электронной таблицы будет предложено несколько вариантов, позволяющих экспортировать файл в различные форматы из Excel MHTML, что может быть полезно для файлов, слишком больших для Excel, формата OpenOffice или других форматов: внутренний формат XML SAP, Формат Excel MHTML, формат Excel Office 2003 XML, формат OpenOffice OpenDocument 2.0, Excel в существующем формате XXL, формат Excel MHTML на 2000/1997 годы, формат Excel Office Open XML (XLSX).
Последний, офисный формат XML Open XML XLSX, является стандартным форматом для последней программы Microsoft Excel 2016 и Excel Office 356.
Выберите формат Excel Office Open XML, чтобы выполнить экспорт данных SAP в MSExcel.
Экспорт данных SAP в файл Excel
Следующим шагом будет сохранение файла Excel, содержащего экспортированные данные SAP, на компьютере. Откроется приглашение, расположенное по умолчанию в папке экспорта SAP по умолчанию, которая обычно представляет собой папку графического интерфейса пользователя SAP, расположенную в папке файлов программного обеспечения локального компьютера.
Скорее всего, файл уже будет существовать, особенно при экспорте большого количества данных. Если необходимо отобразить данные только в Excel, чтобы выполнить несколько операций копирования и вставки в другую электронную таблицу Excel или в другую программу, достаточно заменить существующий файл.
Экспорт данных SAP открыт в Excel
После того, как файл будет сохранен на компьютере, Excel автоматически откроет экспорт данных SAP, который только что был создан.
Ожидайте некоторое время, чтобы открыть программу, в зависимости от длины файла.
Как правило, почти невозможно открыть файл, содержащий более 50000 записей.
В этом случае необходимо использовать критерии фильтрации в SAP, чтобы экспортировать меньше данных, а затем копировать и вставлять их вручную один за другим из разных экспортов Excel в один файл Excel.
И вот, через некоторое время программа Excel отобразит экспортированный файл данных SAP в электронной таблице.
Теперь можно воспроизводить данные, поступающие прямо из SAP S/4 HANA в Excel Office 365 или другой версии Office.
Как загрузить огромные данные из таблицы SAP?
Для загрузки огромных данных из таблицы SAP лучше всего использовать загрузку фонового файла, вместо того чтобы напрямую открывать экспорт данных SAP в электронную таблицу Excel — точно так же, как при экспорте отчета SAP в Excel.
Выберите формат экспорта, который занимает меньше места, например не преобразованный, поскольку, например, использование экспорта HTML значительно увеличит пространство файла, добавив дополнительные символы HTML.
Как скачать огромные данные из таблицы SAP? Выберите текст с опцией экспорта вкладок, так как это самый легкий экспорт
Необращенный экспорт данных SAP — лучший способ загрузить огромные данные из таблицы SAP, так как файловое пространство на диске будет сокращено. Просто откройте его в Excel как текстовый файл со столбцами, разделенными символом «|».
Если данные для загрузки из SAP по-прежнему слишком велики, попробуйте загрузить их несколькими небольшими порциями, используя транзакцию SAP для просмотра данных SE16N, например, с фильтрами, и выполните несколько экспортов данных.
SAP GUI по умолчанию выбран формат экспорта SAP Excel, как его изменить?
Если вы выполнили процесс экспорта SAP Excel с помощью электронной таблицы Excel и использовали опцию «всегда использовать выбранный формат», опция выбора экспорта Excel всегда будет использоваться в системе SAP для вашего пользователя.
Чтобы изменить выбранный формат экспорта SAP Excel по умолчанию, просто откройте отчет, например представление таблицы в SE16N, и щелкните правой кнопкой мыши в любом месте таблицы.
В открывшемся контекстном меню выберите опцию «Электронная таблица …», и всплывающее окно, позволяющее выбрать формат экспорта SAP Excel из списка доступных форматов, вернется в ваш графический пользовательский интерфейс SAP вместе с возможностью отменить выбор. Опция «всегда использовать выбранный формат».
Извлечение SAP в Excel будет выполнено в соответствии с вновь выбранным форматом экспорта SAP Excel и будет установлено по умолчанию или нет, в зависимости от того, выбрали ли вы вариант экспорта SAP Excel «всегда использовать выбранный формат».
Как изменить выбранный по умолчанию формат для экспорта электронных таблиц.
Как вернуть различные варианты загрузки из SAP в Excel?
Как скачать ABAP Excel?
Можно запрограммировать загрузку ABAP Excel для экспорта данных в нужный формат файла, создав внутреннюю таблицу, которая затем будет загружена пользователем SAP.
Однако создание загрузки ABAP Excel — это техническая операция, которую должен выполнить разработчик с правом доступа к системе. Лучшее решение для этого — следовать пути обучения SAP ABAP Programmer и создавать программу самостоятельно или попросить компетентного консультанта сделать это от вашего имени.
Отсутствует опция экспорта SAP в электронную таблицу, что делать?
Если у вас отсутствует опция экспорта SAP в электронную таблицу, скорее всего, она была заменена другим именем после обновления. Вы по-прежнему можете извлекать данные из SAP в Excel, выбрав текст с опцией экспорта вкладок.
Экспорт в электронную таблицу отключен в SAP: он был заменен текстом с экспортом вкладок
Всякий раз, когда опция SAP-таблицы SAP недоступна, просто используйте другой вариант, такой как текст с экспортом вкладок, который имеет тот же результат, что и экспорт SAP-таблицы SAP.
Параметр электронной таблицы отсутствует после обновления EHP7
Как сбросить настройки экспорта в Excel в SAP?
Если параметр извлечения данных из SAP неправильно настроен для загрузки Excel в SAP, например, в транзакции ME2N, лучший способ сбросить настройки экспорта в Excel в SAP — выбрать вручную параметр Дополнительно: Список: Экспорт: Электронная таблица или использовать клавиатуру сочетание CTRL + SHIFT + F7 при выполнении экспорта новой таблицы и выбор вручную нужного формата.
Ярлык для загрузки SAP Excel: CTRL + SHIFT + F7
Невозможно сбросить настройки сохранения для экспорта в формат электронных таблиц Excel
Как скопировать поля таблицы SAP в Excel?
Чтобы скопировать определенные поля таблицы SAP в Excel, начните с открытия таблицы в SAP. Затем используйте комбинацию клавиш CTRL + Y, чтобы открыть курсор выбора в интерфейсе SAP.
Теперь вы сможете выбрать определенный набор полей таблицы в SAP, щелкнув один угол целевого выделения и перетащив курсор мыши в противоположный угол выделения целевых ячеек, удерживая нажатой комбинацию клавиш CTRL + Y на вашем клавиатура.
После выбора ячеек отпустите клавиши и мышь и скопируйте данные с помощью комбинации клавиш CTRL + C. Теперь вы можете вставить скопированные поля таблицы SAP в Excel или любую другую программу обработки данных.
SAP Fiori: экспорт в Excel
Не всегда можно экспортировать таблицы Fiori для Excel в качестве электронной таблицы. Для некоторых таблиц даже не возможно выбрать данные вручную, и скопируйте вставку в электронную таблицу!
Однако всякий раз, когда доступно вариант экспортировки в Excel в SAP FFiori, сдержанный экспорт в значок электронной таблицы будет отображаться прямо над таблицей данных, на правой стороне.
Просто нажмите на этот значок, и содержимое таблицы напрямую будет переведено в файл Excel, который будет загружен вашим браузером.
Часто Задаваемые Вопросы
- В каких форматах вы можете экспортировать SAP в Excel?
- После экспорта вам будет представлено несколько вариантов, позволяющих экспортировать файл в различные форматы из Excel MHTML, которые могут быть полезны для файлов, которые слишком велики для Excel, формата OpenOffice или других форматов.
Введение в SAP HANA для нетехников в видео
In this Blog-post I’d like to give a few insights on how we process XLSX file by using latest ABAP, which might be quite different than in most other implementations, for example:ABAP and OLE or Excel with SAP – An Overview
By using CL_XLSX_DOCUMENT (available from 2008), it is easy to load file, workbook, sheets, rows and columns. A good example code can be found within class CL_EHFND_XLSX(available on ABAP AS 752 SP-Level 0004, Software Component S4CORE Release 102, SP 4.).
On the other hand, you can set document format by using IF_IXML_NODE, below example code show how …
lo_xlsx_doc = cl_xlsx_document=>load_document( <XSTRING of xlsx file> )
lo_workbookpart = lo_xlsx_doc->get_workbookpart( ).
lo_wordsheetparts = lo_workbookpart->get_worksheetparts( ).
lo_wordsheetpart = lo_wordsheetparts->get_part( 0 ).
lo_sheet_content = lo_wordsheetpart->get_data( ).
CREATE OBJECT lo_xml_document.
lo_xml_document->parse_xstring( lo_sheet_content ).
DATA(lo_node_datavalidation_init) = lo_node_datavalidations->clone( ).
....
DATA(lo_node_datavalidation) = lo_node_datavalidation_init->clone( ).
lo_node_datavalidation->set_name( 'dataValidation' ).
CONCATENATE ls_validation-column lv_begin_str ':' ls_validation-column lv_end_str INTO
DATA(lv_sqref).
DATA(lo_attrs_map_datavalidation) = lo_node_datavalidation->get_attributes( ).
DATA(lo_attr_sqref) = lo_attrs_map_datavalidation->get_named_item_ns( 'count' )->clone( ).
lo_attr_sqref->set_name( 'sqref' ).
lo_attr_sqref->set_value( lv_sqref ).
lo_attrs_map_datavalidation->set_named_item_ns( lo_attr_sqref ).
lo_attrs_map_datavalidation->remove_named_item_ns( 'count' ).
DATA(lo_attr_showerrormsg) = lo_attr_sqref->clone( ).
lo_attr_showerrormsg->set_name( 'showErrorMessage' ).
lo_attr_showerrormsg->set_value( '1' ).
lo_attrs_map_datavalidation->set_named_item_ns( lo_attr_showerrormsg ).
.....
Executable SE38 report.
Main functionalities of this report are:
- Download any DDIC table’s content into xlsx file
- Change value in the xlsx file
- upload xlsx file into DDIC table
- check changed value in DDIC table.
And the dynamic structure is used in this report. The code style is what I would like to present also.
User Interface
selection-screen begin of block b04 with frame title text-b04.
parameters p_exp radiobutton group radi user-command action default 'X'.
parameters p_imp radiobutton group radi.
selection-screen end of block b04.
selection-screen begin of block b01 with frame title text-b01.
parameters p_table type dd02l-tabname modif id gp1 obligatory memory id ht.
parameters p_file type localfile modif id gp2 obligatory memory id hf.
parameters p_sql type string modif id gp3.
selection-screen comment /1(75) comm.
selection-screen end of block b01.
initialization.
comm = `e.g. RLDNR = 'Y1' AND RRCTY = 'U'`.
at selection-screen on value-request for p_file.
* call function 'F4_FILENAME'
* exporting
* field_name = 'P_FILE'
* importing
* file_name = p_file.
data(title) = |Select Excel File, e.g. *.xlsx|.
data(defaultextension) = |.xlsx|.
data(filefilter) = `Excel Files (*.xlsx)|*.xlsx`.
data it_tab type filetable.
data returncode type i.
call method cl_gui_frontend_services=>file_open_dialog
exporting
window_title = title
default_extension = defaultextension
* default_filename =
* file_filter = filefilter
* with_encoding =
* initial_directory =
* multiselection =
changing
file_table = it_tab
rc = returncode
* user_action =
* file_encoding =
* exceptions
* file_open_dialog_failed = 1
* cntl_error = 2
* error_no_gui = 3
* not_supported_by_gui = 4
* others = 5
.
if sy-subrc <> 0.
* Implement suitable error handling here
endif.
read table it_tab assigning field-symbol(<selectedfilename>) index 1.
if sy-subrc = 0.
p_file = <selectedfilename>-filename.
endif.
Main Functionality
Download table content into local excel file (xlsx)
Select action “Export”
Input existing table , e.g. Table Name T000, File Full Path: c:demot000.xlsx
Change the value of non-key column in xlsx file.
start-of-selection.
try.
data(configurationhandler) = new lcl_configuration( filefullpath = conv #( p_file )
tablename = conv #( p_table )
sqlscript = p_sql ).
if p_exp = abap_true.
configurationhandler->export( ).
else.
configurationhandler->import( ).
endif.
catch lcx_configuration into data(configurationexception).
write: / configurationexception->local_text.
endtry.
Upload local excel file (*.xlsx) into table
Select action “Import”
Input existing table , e.g. Table Name T000, File Full Path: c:demot000.xlsx
Empty row will be skip, and table entries will be modified (Insert or Update). It is not possible to delete existing table entry.
start-of-selection.
try.
data(configurationhandler) = new lcl_configuration( filefullpath = conv #( p_file )
tablename = conv #( p_table )
sqlscript = p_sql ).
if p_exp = abap_true.
configurationhandler->export( ).
else.
configurationhandler->import( ).
endif.
catch lcx_configuration into data(configurationexception).
write: / configurationexception->local_text.
endtry.
Exception Handling
You will get exception of structure infliction if xlsx file is not for that table.
"check file structure, first line of excel file
data(columncount) = firstsheet->get_last_column_number_in_row( 1 ).
data column type i value 1.
"data tablecomponents type cl_abap_structdescr=>component_table.
data(tablecomponents) = me->tablestructure->get_components( ).
data invalidcolumn type string.
types: begin of columninfo,
column type i,
columnname type string,
end of columninfo.
types columnsinfo type standard table of columninfo with empty key.
data columnfromfile type columnsinfo.
do columncount times.
data(cellvalue) = firstsheet->get_cell_content(
exporting
iv_row = 1
iv_column = column ).
append initial line to columnfromfile assigning field-symbol(<columnfromfile>).
<columnfromfile>-column = column.
<columnfromfile>-columnname = cellvalue.
if line_exists( tablecomponents[ name = cellvalue ] ).
delete tablecomponents where name = cellvalue.
else.
invalidcolumn = invalidcolumn && |,{ cellvalue }|.
endif.
column = column + 1.
enddo.
data missingcolumns type string.
loop at tablecomponents reference into data(currentcomponent).
missingcolumns = missingcolumns && |, { currentcomponent->*-name }|.
endloop.
if not invalidcolumn is initial.
raise exception type lcx_configuration
exporting
text = |Find invalid columns: { invalidcolumn } |.
endif.
First row will be the table columns’ name
Local Class Definition
*&---------------------------------------------------------------------*
*& Include ZZZZ_HOME_CFG_FINE_TUNING_LCL
*&---------------------------------------------------------------------*
class lcx_configuration definition
inheriting from cx_static_check.
public section.
data local_text type string.
methods constructor importing text type string.
endclass.
class lcx_configuration implementation.
method constructor.
super->constructor( ).
local_text = text.
endmethod.
endclass.
*&---------------------------------------------------------------------*
*& Class lcl_configuration
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
class lcl_configuration definition.
public section.
data filefullpath type string.
data tablename type string.
data sqlscript type string.
data tableinfo type tadir.
data tablestructure type ref to cl_abap_structdescr.
data tabletype type ref to cl_abap_tabledescr.
data tabledata type ref to data.
class-methods validate_sql_script
changing sqlscript type string.
class-methods validate_table
changing checkedtablename type string
raising lcx_configuration.
methods constructor "Constructore method
importing filefullpath type string
tablename type string
sqlscript type string
raising lcx_configuration.
methods import raising lcx_configuration.
methods export raising lcx_configuration.
protected section.
methods get_filecontent
returning value(filecontent) type xstring
raising lcx_configuration.
methods extract_data_from_table
raising lcx_configuration.
methods check_file
raising lcx_configuration.
methods extract_data_from_excel
raising lcx_configuration.
methods get_tablecontent
exporting tablecontent type any table
raising lcx_configuration.
private section.
endclass.
class lcl_configuration implementation.
method constructor.
if filefullpath is initial or tablename is initial.
raise exception type lcx_configuration
exporting
text = |File Name { filefullpath } and Table Name { tablename } should be provided|.
endif.
me->filefullpath = filefullpath.
me->tablename = tablename.
me->sqlscript = sqlscript.
lcl_configuration=>validate_table( changing checkedtablename = me->tablename ).
me->tablestructure ?= cl_abap_typedescr=>describe_by_name( me->tablename ).
if not me->tablestructure is bound.
raise exception type lcx_configuration
exporting
text = |Exception occurs when parsing Table Structure for { tablename } |.
endif.
try.
me->tabletype = cl_abap_tabledescr=>create( p_line_type = me->tablestructure ).
catch cx_sy_table_creation into data(tabletypeexception).
raise exception type lcx_configuration
exporting
text = |Exception occurs when parsing Table Type for { tablename } |.
endtry.
create data tabledata type handle me->tabletype.
endmethod.
method import.
"Update DDIC table content from (client PC) excel file
me->extract_data_from_excel( ).
field-symbols <finaltabledata> type standard table.
data finaltabledata type ref to data.
create data finaltabledata type handle me->tabletype.
assign finaltabledata->* to <finaltabledata>.
field-symbols <tabledata> type standard table.
assign me->tabledata->* to <tabledata>.
loop at <tabledata> assigning field-symbol(<currenttabledata>).
assign component 'MANDT' of structure <currenttabledata> to field-symbol(<lv_client>).
if sy-subrc = 0.
<lv_client> = ''.
if not <currenttabledata> is initial.
<lv_client> = sy-mandt.
append <currenttabledata> to <finaltabledata>.
else.
"delete <tabledata> from <currenttabledata>.
endif.
else.
if <currenttabledata> is initial.
"delete <tabledata> from <currenttabledata>.
endif.
endif.
endloop.
data(checkedtablename) = me->tablename.
lcl_configuration=>validate_table( changing checkedtablename = checkedtablename ).
if not <finaltabledata> is initial.
modify (checkedtablename) from table <finaltabledata>.
"break-point.
if sy-subrc <> 0.
rollback work.
raise exception type lcx_configuration
exporting
text = |Exception occurs when modifying table: { tablename } |.
else.
message s001(00) with |Table: { tablename } is modified successfully.|.
endif.
endif.
endmethod.
method export.
"Create client PC excel file from DDIC table
data(filecontent) = me->get_filecontent( ).
cl_scp_change_db=>xstr_to_xtab( exporting im_xstring = filecontent
importing ex_xtab = data(filecontenttab) ).
cl_gui_frontend_services=>gui_download(
exporting
bin_filesize = xstrlen( filecontent )
filename = |{ me->filefullpath }|
filetype = 'BIN'
confirm_overwrite = abap_true
importing
filelength = data(bytestransferred)
changing
data_tab = filecontenttab
exceptions
file_write_error = 1
no_batch = 2
gui_refuse_filetransfer = 3
invalid_type = 4
no_authority = 5
unknown_error = 6
header_not_allowed = 7
separator_not_allowed = 8
filesize_not_allowed = 9
header_too_long = 10
dp_error_create = 11
dp_error_send = 12
dp_error_write = 13
unknown_dp_error = 14
access_denied = 15
dp_out_of_memory = 16
disk_full = 17
dp_timeout = 18
file_not_found = 19
dataprovider_exception = 20
control_flush_error = 21
not_supported_by_gui = 22
error_no_gui = 23
others = 24
).
if sy-subrc <> 0.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
else.
message s001(00) with bytestransferred ' bytes transferred'.
endif.
endmethod.
method get_filecontent.
me->extract_data_from_table( ).
if me->tabledata is initial.
raise exception type lcx_configuration
exporting
text = |Table { tablename } has no entry.|.
endif.
"Get file content from table
clear filecontent.
try.
data(xlsx_handling) = cl_ehfnd_xlsx=>get_instance( ).
data(xlsx_document) = xlsx_handling->create_doc( ).
data(xlsx_sheets) = xlsx_document->get_sheets( ).
data(first_xlsx_sheet) = xlsx_document->get_sheet_by_id( xlsx_sheets[ 1 ]-sheet_id ).
first_xlsx_sheet->change_sheet_name( 'Data' ).
data(lv_column) = 1.
loop at me->tablestructure->components reference into data(component).
first_xlsx_sheet->set_cell_content( iv_row = 1 iv_column = lv_column iv_value = component->name ).
lv_column = lv_column + 1.
endloop.
data(lv_row) = 2.
field-symbols <tabledata> type standard table.
assign me->tabledata->* to <tabledata>.
loop at <tabledata> assigning field-symbol(<currenttabledata>).
lv_column = 1.
loop at me->tablestructure->components reference into component.
assign component component->name of structure <currenttabledata> to field-symbol(<columnvalue>).
first_xlsx_sheet->set_cell_content( iv_row = lv_row iv_column = lv_column iv_value = <columnvalue> ).
lv_column = lv_column + 1.
endloop.
lv_row = lv_row + 1.
endloop.
filecontent = xlsx_document->save( ).
catch cx_openxml_format into data(openxml_format_exception).
raise exception type lcx_configuration
exporting
text = |Error occurs when constructing excel file instance. cx_openxml_format|.
catch cx_openxml_not_found into data(openxml_not_found_exception).
raise exception type lcx_configuration
exporting
text = |Error occurs when constructing excel file instance. CX_OPENXML_NOT_FOUND |.
catch cx_openxml_not_allowed into data(openxml_not_allowed_exception).
raise exception type lcx_configuration
exporting
text = |Error occurs when constructing excel file instance. CX_OPENXML_NOT_ALLOWED |.
endtry.
endmethod.
method get_tablecontent.
"Get table content from file
endmethod.
method validate_table.
"raise exception if table does not exist
select single * from tadir into @data(tableinfo) where obj_name = @checkedtablename and object = 'TABL'. "#EC CI_GENBUFF.
if sy-subrc <> 0.
raise exception type lcx_configuration
exporting
text = |Table { checkedtablename } does not exist.|.
endif.
try.
checkedtablename =
cl_abap_dyn_prg=>check_table_or_view_name_str(
val = checkedtablename
packages = conv #( tableinfo-devclass )
incl_sub_packages = abap_true
).
catch cx_abap_not_a_table
cx_abap_not_in_package.
return.
endtry.
endmethod.
method extract_data_from_table.
data sql_script type string.
data checkedtablename type string.
sql_script = me->sqlscript.
checkedtablename = me->tablename.
lcl_configuration=>validate_sql_script( changing sqlscript = sql_script ).
lcl_configuration=>validate_table( changing checkedtablename = checkedtablename ).
field-symbols <tabledata> type standard table.
assign tabledata->* to <tabledata>.
if me->sqlscript is initial.
select * from (checkedtablename) into table <tabledata>.
else.
select * from (checkedtablename) into table <tabledata> where (sql_script).
endif.
endmethod.
method validate_sql_script.
if sqlscript is initial.
return.
endif.
sqlscript = replace( val = sqlscript
sub = `'`
with = `''`
occ = 0 ).
concatenate `'` sqlscript `'` into sqlscript separated by space.
try.
sqlscript =
cl_abap_dyn_prg=>check_char_literal( sqlscript ).
data(lv_len) = strlen( sqlscript ) - 2.
sqlscript = sqlscript+1(lv_len).
sqlscript = replace( val = sqlscript
sub = `''`
with = `'`
occ = 0 ).
catch cx_abap_invalid_value into data(lo_exception).
clear sqlscript.
endtry.
endmethod.
method check_file.
endmethod.
method extract_data_from_excel.
field-symbols <exceldata> type standard table.
assign me->tabledata->* to <exceldata>.
data(xlsxhandler) = cl_ehfnd_xlsx=>get_instance( ).
check not xlsxhandler is initial.
try.
data(xstring_excel) = cl_openxml_helper=>load_local_file( me->filefullpath ).
catch cx_openxml_not_found into data(openxml_not_found).
return.
endtry.
try.
data(xlsxdocument) = xlsxhandler->load_doc( iv_file_data = xstring_excel ).
catch cx_openxml_format into data(openxml_format).
return.
catch cx_openxml_not_allowed into data(openxml_not_allowed).
return.
catch cx_dynamic_check into data(dynamic_check).
return.
endtry.
"extract data from first sheet
try.
data(firstsheet) = xlsxdocument->get_sheet_by_id( iv_sheet_id = 1 ).
catch cx_openxml_format into openxml_format.
raise exception type lcx_configuration
exporting
text = |Error occurs when extract data from first sheet: CX_OPENXML_FORMAT |.
catch cx_openxml_not_found into openxml_not_found.
raise exception type lcx_configuration
exporting
text = |Error occurs when extract data from first sheet: OPENXML_NOT_FOUND |.
catch cx_dynamic_check into dynamic_check.
raise exception type lcx_configuration
exporting
text = |Error occurs when extract data from first sheet: CX_DYNAMIC_CHECK |.
endtry.
"return if no sheet in xlsx file
check not firstsheet is initial.
"check file structure, first line of excel file
data(columncount) = firstsheet->get_last_column_number_in_row( 1 ).
data column type i value 1.
"data tablecomponents type cl_abap_structdescr=>component_table.
data(tablecomponents) = me->tablestructure->get_components( ).
data invalidcolumn type string.
types: begin of columninfo,
column type i,
columnname type string,
end of columninfo.
types columnsinfo type standard table of columninfo with empty key.
data columnfromfile type columnsinfo.
do columncount times.
data(cellvalue) = firstsheet->get_cell_content(
exporting
iv_row = 1
iv_column = column ).
append initial line to columnfromfile assigning field-symbol(<columnfromfile>).
<columnfromfile>-column = column.
<columnfromfile>-columnname = cellvalue.
if line_exists( tablecomponents[ name = cellvalue ] ).
delete tablecomponents where name = cellvalue.
else.
invalidcolumn = invalidcolumn && |,{ cellvalue }|.
endif.
column = column + 1.
enddo.
data missingcolumns type string.
loop at tablecomponents reference into data(currentcomponent).
missingcolumns = missingcolumns && |, { currentcomponent->*-name }|.
endloop.
if not invalidcolumn is initial.
raise exception type lcx_configuration
exporting
text = |Find invalid columns: { invalidcolumn } |.
endif.
if not missingcolumns is initial.
raise exception type lcx_configuration
exporting
text = |Columns do not exist in excel file: { missingcolumns } |.
endif.
tablecomponents = me->tablestructure->get_components( ).
data(rowcount) = firstsheet->get_last_row_number( ).
data currentrow type i value 2.
while currentrow <= rowcount.
append initial line to <exceldata> assigning field-symbol(<currentrow>).
loop at columnfromfile reference into data(currentcolumn).
cellvalue = firstsheet->get_cell_content(
exporting
iv_row = currentrow
iv_column = currentcolumn->*-column ).
assign component currentcolumn->*-columnname of structure <currentrow> to field-symbol(<cellvalue>).
<cellvalue> = cellvalue.
endloop.
currentrow = currentrow + 1.
endwhile.
endmethod.
endclass.
Conclusion
Thank you for your interest in XLSX2ABAP and ABAP2XLSX. Example code is tested on SAP_BASIS 755, S4CORE 105.
ABAP программа загрузки данных из EXCEL в SAP систему. Разберу на примере загрузку Excel файла, проверку и преобразование данных, полученных при загрузке ABAP.
Это полезная и часто используемая задача.
Рассмотрим один из вариантов загрузки данных из Excel на примере программы ABAP. Подробно разберу каждый блок программы для лучшего понимания. Ссылку на файл Excel для тестирования данной программы приведу в конце данной статьи.
Селекционный экран ABAP для выбора файла
Создаю селекционный экран ABAP на который добавлю одно поле для выбора файла из которого будут загружаться данные.
PARAMETERS p_file TYPE string LOWER CASE. |
Средство поиска ABAP для файла
Так же в этой части кода добавляю средство поиска ABAP для поля файла через использование события AT SELECTION-SCREEN ON VALUE-REQUEST.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file. cl_salv_test_data=>select_file( IMPORTING filename = p_file ). |
Определяю тип для внутренней таблицы результата
Я определил локальный тип структуры результата для большей наглядности в статье, но на его месте может быть и тип ABAP словаря.
START-OF-SELECTION. TYPES: BEGIN OF ts_data, carrid TYPE s_carr_id, connid TYPE s_conn_id, fldate TYPE s_date, price TYPE s_price, currency TYPE s_currcode, planetype TYPE s_planetye, seatsmax TYPE s_seatsmax, seatsocc TYPE s_seatsocc, gjahr TYPE gjahr, monat TYPE monat, END OF ts_data. |
Внутренняя таблица lt_sflight это таблица в которую будет помещён итоговый уже преобразованный результат загрузки. А таблица lt_intern это внутренняя таблица abap в которую изначально будут помещены данные из Excel для дальнейшей обработки.
DATA: lt_sflight TYPE STANDARD TABLE OF ts_data, lt_intern TYPE TABLE OF alsmex_tabline. |
ФМ ALSM_EXCEL_TO_INTERNAL_TABLE
Сама загрузка происходит при вызове функционального метода ALSM_EXCEL_TO_INTERNAL_TABLE, разберём подробно его параметры:
CALL FUNCTION ‘ALSM_EXCEL_TO_INTERNAL_TABLE’ EXPORTING filename = CONV rlgrap—filename( p_file ) i_begin_col = 1 i_begin_row = 2 i_end_col = 10 i_end_row = 10000 TABLES intern = lt_intern EXCEPTIONS inconsistent_parameters = 1 upload_ole = 2 OTHERS = 3. |
- filename – путь к файлу Excel. Использование конструкции CONV в этом случае преобразует параметр p_file к нужному типу.
- i_begin_col – номер колонки с которой начинать загрузку
- i_begin_row – номер строки с которой начинаем загрузку. В нашем случае установил значение 2 так как мне не нужно обрабатывать первую строку заголовка.
- i_end_col – сколько колонок нам нужно анализировать при загрузке
- i_end_row – сколько записей максимум берётся для анализа.
- intern – внутренняя таблица в которую будут загружаться данные из файла.
Обработка результата загрузки данных из Excel
С использованием конструкции нового синтаксиса LOOP AT GROUP BY обходим таблицу сгруппировав её по столбцу row, в котором расположен номер строки. И после обработки всей группы с одинаковым номером строки мы добавляем запись в таблицу результата и переходим к следующей группе.
Более подробно загрузка и обработка данных после разбирается в видео и не забывайте подписаться на мой канал YouCoder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
LOOP AT lt_intern INTO DATA(ls_intern) GROUP BY ( row = ls_intern—row ) REFERENCE INTO DATA(lr_grp). DATA(ls_alv) = VALUE ts_data( ). LOOP AT GROUP lr_grp REFERENCE INTO DATA(lr_item). CHECK lr_item—>value IS NOT INITIAL. CASE lr_item—>col. WHEN 1. ls_alv—carrid = lr_item—>value. WHEN 2. ls_alv—connid = lr_item—>value. WHEN 3. ls_alv—fldate = |{ lr_item—>value+6(4) }{ lr_item—>value+3(2) }{ lr_item—>value(2) }|. » 29.04.2015 20150429 WHEN 4. lr_item—>value = replace( val = lr_item—>value regex =‘[,]’ with = ‘.’ occ = 0 ). » 427,94 ls_alv—price = lr_item—>value. WHEN 5. ls_alv—currency = lr_item—>value. WHEN 6. ls_alv—planetype = lr_item—>value. WHEN 7. ls_alv—seatsmax = lr_item—>value. WHEN 8. IF strlen( lr_item—>value ) > 10. ls_alv—seatsocc = lr_item—>value. ENDIF. WHEN 9. IF lr_item—>value CO |0123456789| AND lr_item—>value >= 1 AND lr_item—>value <= 9999. ls_alv—gjahr = lr_item—>value. ENDIF. WHEN 10. IF lr_item—>value CO |0123456789| AND lr_item—>value >= 1 AND lr_item—>value <= 12 . ls_alv—monat = lr_item—>value. ENDIF. WHEN OTHERS. CONTINUE. ENDCASE. ENDLOOP. APPEND ls_alv TO lt_sflight. ENDLOOP. |
Конструкции языка ABAP используемые в коде выше:
- replace – замена символа в строке ABAP
- strlen – длина строки ABAP
- LOOP AT GROUP – группировка в цикле ABAP
Быстрый вывод внутренней таблицы ABAP на экран для тестирования:
cl_demo_output=>display( lt_sflight ). |
Шаблон программы ABAP загрузки данных из Excel.
Ниже привёл полный код программы загрузки для удобства копирования и тестирования:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
START-OF-SELECTION. TYPES: BEGIN OF ts_data, carrid TYPE s_carr_id, connid TYPE s_conn_id, fldate TYPE s_date, price TYPE s_price, currency TYPE s_currcode, planetype TYPE s_planetye, seatsmax TYPE s_seatsmax, seatsocc TYPE s_seatsocc, gjahr TYPE gjahr, monat TYPE monat, END OF ts_data. DATA: lt_sflight TYPE STANDARD TABLE OF ts_data, lt_intern TYPE TABLE OF alsmex_tabline. IF p_file IS NOT INITIAL. CALL FUNCTION ‘ALSM_EXCEL_TO_INTERNAL_TABLE’ EXPORTING filename = CONV rlgrap—filename( p_file ) i_begin_col = 1 i_begin_row = 2 i_end_col = 10 i_end_row = 10000 TABLES intern = lt_intern EXCEPTIONS inconsistent_parameters = 1 upload_ole = 2 OTHERS = 3. IF sy—subrc = 0. LOOP AT lt_intern INTO DATA(ls_intern) GROUP BY ( row = ls_intern—row ) REFERENCE INTO DATA(lr_grp). DATA(ls_alv) = VALUE ts_data( ). LOOP AT GROUP lr_grp REFERENCE INTO DATA(lr_item). CHECK lr_item—>value IS NOT INITIAL. CASE lr_item—>col. WHEN 1. ls_alv—carrid = lr_item—>value. WHEN 2. ls_alv—connid = lr_item—>value. WHEN 3. ls_alv—fldate = |{ lr_item—>value+6(4) }{ lr_item—>value+3(2) }{ lr_item—>value(2) }|. » 29.04.2015 20150429 WHEN 4. lr_item—>value = replace( val = lr_item—>value regex =‘[,]’ with = ‘.’ occ = 0 ). » 427,94 ls_alv—price = lr_item—>value. WHEN 5. ls_alv—currency = lr_item—>value. WHEN 6. ls_alv—planetype = lr_item—>value. WHEN 7. ls_alv—seatsmax = lr_item—>value. WHEN 8. IF strlen( lr_item—>value ) > 10. ls_alv—seatsocc = lr_item—>value. ENDIF. WHEN 9. IF lr_item—>value CO |0123456789| AND lr_item—>value >= 1 AND lr_item—>value <= 9999. ls_alv—gjahr = lr_item—>value. ENDIF. WHEN 10. IF lr_item—>value CO |0123456789| AND lr_item—>value >= 1 AND lr_item—>value <= 12 . ls_alv—monat = lr_item—>value. ENDIF. WHEN OTHERS. CONTINUE. ENDCASE. ENDLOOP. APPEND ls_alv TO lt_sflight. ENDLOOP. ENDIF. cl_demo_output=>display( lt_sflight ). ENDIF. |
Если статья оказалась Вам полезна поддержите проект. Спасибо!
Сайт ABAP программирование YouCoder – это сборник статей и видео о языке программирования ABAP и работе в SAP системе. Есть как уроки abap для начинающих так и новый синтаксис в ABAP и SAP обучение для консультантов SAP.
1. Аннотация
Автор дает краткий обзор существующих методов создания печатных форм в Excel-совместимых форматах, а также знакомит читателя с инструментом XLSX Workbench посредством серии «пошаговых» примеров: от простого к сложному. Примеры демонстрируют реализацию элементов типовых печатных форм: Табличная часть, Изображение, Диаграмма, Иерархическая структура (дерево).
2. Введение
С выгрузкой данных в MS Excel-совместимый формат рано или поздно сталкивается каждый ABAP-разработчик, так как данный формат не теряет своей популярности у пользователей, и они довольно часто предпочитают Excel другим средствам — SmartForms и AdobeForms. На тему реализации Excel-форм уже накопилось огромное количество информации и наработок, и для каждой типовой задачи можно найти массу решений. Однако, у этого есть и обратная сторона — разнообразие способов реализации одной и той же задачи не способствует поддержанию порядка в этой части разработок и, как следствие, усложняет их сопровождение. Не претендуя на полноту списка, я изложу лишь наиболее часто встречаемые мной на проектах подходы к форматированной выгрузке данных в Excel.
Примечание. Инструмент SmartForms пришел на смену морально устаревшему SapScript, обладая гораздо более дружественным графическим интерфейсом и позволяя обходиться без программирования в 90% случаев. Ссылка по теме.
Примечание. Официальное название PDF-Based Print Forms считается более продвинутым и современным инструментом для создания форм, чем SmartForms. Является составной частью более крупного решения SAP Interactive Forms by Adobe. Ссылка по теме.
Как правило, выгрузка основывается на файле-шаблоне, хранимом в WEB-репозитарии и содержащем базовое форматирование результирующей формы. В тексте шаблона имеются особые метки, которые в runtime заменяются на значения, передаваемые из программы печати. Другие размеченные области шаблона могут дублироваться, удаляться и претерпевать изменения согласно логике, имплементированной в программе печати или в макросе VBA. Использование файла-шаблона позволяет, в случае необходимости, легко вносить изменения в формат отдельных ячеек и областей.
Технологии выгрузки:
-
Формирование файла исключительно средствами DOI / OLE / VBA в различных сочетаниях.
Традиционный стандартный набор низкоуровневых API Desktop office integration (DOI) позволяет сделать многое, а в сочетании с VBA — практически всё (разумеется, в рамках возможностей MS Excel). Но напрямую в программах печати эти API используется довольно редко. Чаще на их основе разрабатываются более удобные пользовательские решения для выгрузки форм. Передача данных из программы печати в целевые ячейки шаблона может быть реализована следующими способами (но не только ими):- Передача значений из программы печати непосредственно в целевые ячейки шаблона средствами DOI / OLE.
- Передача внутренних таблиц в шаблон средствами DOI в виде коллекции таблиц и последующий их разбор и форматирование VBA-макросом.
- Выгрузка внутренней таблицы в промежуточный CSV (или какой-либо другой) файл с последующей загрузкой его в шаблон, разбором и форматированием VBA-макросом. Как уже было сказано, главный плюс использования DOI / OLE / VBA — в абсолютной гибкости форматирования. Минусы же следующие:
- Требуются разрешения на запуск макросов (если используются).
- Невозможность работы в фоновом режиме.
- Загрузка локальной машины пользователя. Длительное формирование «тяжелого» файла (или большого числа файлов) может существенно замедлить или вовсе парализовать остальную работу пользователя.
-
Сборка файла в открытых форматах на стороне сервера приложений .
- Сборка файла в формате «Таблица XML 2003» (XMLSS). Технически этот формат представляет собой единый XML-файл, описывающий содержимое книги Excel. До появления формата «Open XML», формат «Таблица XML 2003» был единственной возможностью получения Excel-совместимой формы в фоновом режиме. Собственно, в этом заключается его главный плюс. Минусы же данного формата в том, что файл на выходе получается довольно «тяжелый» по сравнению с XLS или XLSX, а также, не поддерживает многие опции форматирования (такие как условное форматирование, диаграммы, рисунки и др.). Чаще всего такой файл получают посредством XSLT-трансформации (которая, кроме прочего, выполняет функцию шаблона). В этом случае, я бы дополнительным плюсом назвал использование только штатных средств (т.е. без использования различных Z-утилит). А дополнительным минусом — довольно кропотливый труд при внесении даже небольших изменений в исходное форматирование.
-
Сборка файла в формате «Open XML» (XLSX, XLSM). Технически этот формат представляет собой ZIP-архив, содержащий несколько XML-файлов, описывающих различные составляющие книги Excel. Кроме того, что данный формат современнее, чем XLS, существует возможность формирования его прямо на сервере приложений, без участия приложения MS Excel. Возможные средства реализации:
- Стандартные классы CL_XLSX_* находятся в пакете S_OOXML_XLSX. Как и DOI, они представляют собой низкоуровневые API, которые в исходном виде использовать непосредственно в программе печати весьма трудоемко (к тому же для их использования необходимо иметь базовые представления о спецификации формата Open XML). Таким образом, к этим API сама собой напрашивается пользовательская «обертка» для более комфортной работы.
- Хорошо известная пользовательская разработка западных коллег — набор классов для работы с XLSX и XLSM файлами. Данная разработка проще в использовании, чем, CL_XLSX_* , а также, поддерживает VBA-макросы (в случае с XLSM-файлом), что существенно расширяет её функциональность. Справедливости ради, стоит сказать, что иногда невозможно обойтись без постобработки файла средствами DOI / OLE / VBA. Дело в том, что некоторые вещи (такие как: контроль автоматических разрывов страниц; вставка итоговых строк по каждой печатной странице; настройка оптимальной высоты/ширины для объединенных ячеек; и др.) умеет делать только приложение MS Excel. Но, к счастью, такие требования к формам не слишком часты.
- Стандартные классы CL_XLSX_* находятся в пакете S_OOXML_XLSX. Как и DOI, они представляют собой низкоуровневые API, которые в исходном виде использовать непосредственно в программе печати весьма трудоемко (к тому же для их использования необходимо иметь базовые представления о спецификации формата Open XML). Таким образом, к этим API сама собой напрашивается пользовательская «обертка» для более комфортной работы.
Примечание. Desktop Office Integration (DOI) — набор ABAP-интерфейсов, позволяющих установить взаимодействие между ABAP-программой и офисными приложениями, установленными на локальной машине пользователя, посредством OLE2-интерфейса. Ссылка по теме.
Примечание. Формат XML Spreadsheet (XMLSS) описывает основное содержимое и форматирование книги. Однако, следующие функции не поддерживаются: Диаграммы, OLE-объекты, Рисунки и автофигуры, VBA-проекты, Группировка строк/столбцов. Ссылка по теме.
Примечание. Формат Office Open XML (так же известный как Open XML или OOXML) предназначен для большинства офисных документов (электронные таблицы, текст, презентации и т.д.) был изначально разработан Microsoft. Файл представляет собой ZIP-архив, содержащий некоторое количество XML-файлов («parts»). Также в ZIP-архиве могут содержаться медиафайлы, например, растровые изображения и др. Ссылка по теме.
Перечисленные подходы, в разной степени удобства использования, решают вопрос экспорта данных в Excel-формат. Но отчего их такое множество? И почему такого «разброда и шатания» не наблюдается для SmartForms или AdobeForms? По большей части не потому ли, что (вместо API-полуфабрикатов) для них изначально созданы удобные и самодостаточные среды разработки, позволяющие визуально конструировать структуру формы и настраивать все её опции? Этот риторический вопрос сподвиг меня к разработке визуального конструктора Excel-форм XLSX Workbench, с которым я и хотел бы вас познакомить в настоящей статье. Главное отличие XLSX Workbench от имеющихся на сегодняшний день решений в простоте и наглядности процесса разработки формы — знать ABAP и VBA при этом не обязательно, всё делается с помощью кликов мышью. Этот инструмент с легкостью позволяет создавать как простые, так и очень сложные (в том числе и полностью динамические) формы. В качестве дополнительного бонуса — возможность получения формы в фоновом режиме.
Примечание. XLSX Workbench — бесплатный и находящийся в открытом доступе инструмент для создания печатных форм в формате OpenXML (XLSX). Официальный сайт проекта.
Приведенные ниже (разделы 4-9) примеры базируются на стандартных таблицах из модели данных для обучения SAP Flight Model.
Примечание. Flight model — это набор объектов ABAP-словаря (таблиц, структур, типов) и программных компонентов, имеющих логическую взаимосвязь. Являются основой для многих стандартных обучающих примеров. Ссылка по теме.
3. Основные понятия в XLSX Workbench
Рис.1. Модель
Контекст служит для передачи данных между Программы печати и Формой (Рис.1). Контекстом может быть любая структура, табличный тип и даже элемент данных. Главное условие — это должен быть тип, объявленный в словаре данных. Проще говоря — заходим в SE11 и создаем табличный тип или структуру (либо берем уже имеющуюся) — это и будет контекст.
Программа печати (Рис.1). нужна только для того, чтобы заполнить данными контекст и вызвать Ф.М. ZXLWB_CALLFORM, передавая ему на вход этот контекст.
Форма (Рис.1). создается и редактируется в транзакции ZXLWB_WORKBENCH. Процесс разработки формы повторяет многие принципы разработки в SmartForms. Например, за основу взято представление структуры формуляра в виде иерархии компонентов. Форматирование итогового документа определяется сочетанием отдельных фрагментов шаблона (компонент «Паттерн»), а за передачу текста в ячейку документа отвечает компонент «Значение», который связан с Контекстом. Существуют и другие компоненты («Цикл», «Папка» и др.), с помощью которых возможно реализовать почти любое требование по форматированию.
4. Создание простейшей формы. Вывод полей: Исполнитель/ Телефон/ E-mail.
4.1. Контекст
В качестве контекста будем использовать структуру, объявленную в словаре данных. Зайдем в транзакцию SE11 и создадим структуру (тип данных) с наименованием ZXLWB_EXAMPLE1_CONTEXT (Рис.2). В структуру добавим три поля — все они имеют тип STRING:
- FULLNAME (Исполнитель)
- PHONE (Телефон)
После этого активируем созданную структуру.
Рис.2. Создание структуры
4.2. Формуляр
4.2.1. Создание и сохранение формуляра
Запустим транзакцию ZXLWB_WORKBENCH и создадим форму с наименованием, например, EXAMPLE1 (Рис.3):
Рис.3. Создадание формы
Сразу же после создания сохраним формуляр, нажав на кнопку с дискеткой и указав требуемый пакет для сохранения (Рис.4):
Рис.4. Сохранение формуляра
4.2.2. Разметка шаблона
В Excel-шаблоне, находящемся в правой части экрана, нарисуем следующее (Рис.5):
Рис.5. Разметка шаблона
4.2.3. Присвоение контекста формуляру
Для привязки контекста к формуляру необходимо выделить корневой узел Структуры формуляра и на вкладке «Свойства формуляра», в пункте «Наименование контекста» нажать кнопку с карандашом. На открывшемся popup-экране укажем ZXLWB_EXAMPLE1_CONTEXT . На предложение «создать структуру формуляра автоматически» отвечаем утвердительно, как показано на Рис.6:
Рис.6. Присвоение контекста и автоматическое создание структуры формуляра
В результате, будет автоматически создана такая структура, как показана на Рис.7:
Рис.7. Структура формуляра
4.2.4. Связь компонентов структуры формуляра с Excel-шаблоном
Теперь нам необходимо установить связь узлов дерева Структуры формуляра с областями Excel-шаблона. Схема связи представлена на Рис.8:
Рис.8. Схема связи компонентов с шаблоном
Сначала выполним связь, обозначенную на Рис.8 синей линией:
- Выделим в дереве Структуры формуляра узел с цветной клеткой (так обозначается компонент Паттерн).
- Затем, в Excel-шаблоне выделим диапазон ячеек A1:G7.
- Затем, во вкладке «Свойства компонента», в пункте «Область в шаблоне» нажмем кнопку с карандашом (Рис.9):
Рис.9. Связь Паттерна с шаблоном установлена
В результате этих трех несложных действий компонент Паттерн оказался связан с выделенной областью шаблона.
Заменим наименование и описание Паттерна на более понятное (Рис.10):
Рис.10. Смена наименования и описания Паттерна
Теперь выполним связь с шаблоном для оставшихся трех компонентов: FULLNAME, PHONE и EMAIL. Этот тип компонентов называется Значением и служит для передачи данных из одного поля контекста в одну ячейку Excel-формы. Принцип связывания этих компонентов с шаблоном точно такой же, как и для Паттерна (Рис.9) .
4.2.5. Активация формуляра
Активируем формуляр нажатием кнопки со «спичкой».
4.3. Программа печати
Программа печати включает в себя три этапа:
- Объявление контекста
- Заполнение контекста
- Вызов Ф.М.’ZXLWB_CALLFORM’
Создадим отчет (тип 1-Выполняемая программа) с наименованием, например, ZXLWB_EXAMPLE1 и вставим в него этот код (не забыв активировать) :
REPORT zxlwb_example1.
* объявили контекст
DATA gs_context TYPE zxlwb_example1_context .
* заполнили контекст
PERFORM fill_context .
* отобразили форму
*Вызов
CALL FUNCTION ‘ZXLWB_CALLFORM’
EXPORTING
iv_formname = ‘EXAMPLE1’
iv_context_ref = gs_context
EXCEPTIONS
OTHERS = 2.
IF sy-subrc NE 0 .
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF .
*&———————————————————————*
*& Form fill_context
*&———————————————————————*
* Заполнение контекста
*———————————————————————-*
FORM fill_context .
*=======================================================================
* 1) Исполнитель/ Телефон/ E-mail
*=======================================================================
DATA:
ls_address TYPE bapiaddr3 ,
lt_return TYPE STANDARD TABLE OF bapiret2 .
CALL FUNCTION ‘BAPI_USER_GET_DETAIL’
EXPORTING
username = sy-uname
IMPORTING
address = ls_address
TABLES
return = lt_return.
CONCATENATE ls_address-fullname ‘(‘ sy-uname ‘)’
INTO gs_context-fullname » —>> Исполнитель
SEPARATED BY space .
gs_context-phone = ls_address-tel1_numbr . » —>> Телефон
gs_context-email = ls_address-e_mail . » —>> E-mail
ENDFORM . «fill_context
4.4. Проверка результата
Запустим нашу программу печати ZXLWB_EXAMPLE1 (например, нажатием клавиши F8). Если мы всё сделали правильно, то увидим результат, показанный на Рис.11:
Рис.11. Печать отчёта
5. Вывод таблицы Авиакомпаний
5.1. Контекст
Добавим в наш контекст поле TABCARR с табличным типом TY_SCARR. Таким образом, мы добавили в контекст вложенную таблицу (Рис.12):
Рис.12. Добавление в контекст вложенной таблицы TABCARR
5.2. Формуляр
После того, как мы добавили новое поле в контекст, необходимо перезапустить транзакцию ZXLWB_WORKBENCH, для актуализации контекста в форме.
5.2.1. Разметка шаблона
Добавим в шаблон «серую строку» (Рис.13) под той областью, что мы разметили ранее.
Рис.13. Добавление «серой» строки в шаблон
5.2.2. Добавление компонента Цикл
Добавим Цикл ниже Паттерна (на одном уровне с ним). Для этого, выделим в дереве структуры вышестоящий узел SHEET и нажмем на кнопку «Создать компонент». Из появившегося списка выберем компонент Цикл. На следующем экране укажем его название и описание. После этого созданный компонент Цикл отобразится в дереве структуры (Рис.14)
Рис.14. Добавление компонента Цикл в дерево структуры
Теперь свяжем Цикл с таблицей TABCARR из контекста. Для этого во вкладке «Свойства компонента», в пункте «Связь с контекстом» нажмем кнопку с карандашом и в popup-списке выберем TABCARR (Рис.15):
Рис.15. Связываем Цикл с таблицей контекста
5.2.3. Добавление компонента Паттерн для строки таблицы.
Выделив узел Цикла в дереве структуры, нажмем кнопку «Создать компонент». Из появившегося списка выберем Паттерн и укажем его название и описание. После этого, созданный компонент Паттерн отобразится в дереве структуры (Рис.16):
Рис.16. Добавление компонента Паттерн для строки таблицы в дерево структуры
Свяжем добавленный Паттерн с областью в Excel-шаблоне. Для этого сначала выделим узел Паттерна в дереве, затем, выделим в шаблоне ячейки A8:G8, и после этого, во вкладке «Свойства компонента» в пункте «Область в шаблоне» нажмем на кнопку с карандашом. Связь с шаблоном установлена.
5.2.4. Добавление Значений для строки таблицы.
Выделив узел Паттерна строки в дереве структуры, нажмем кнопку «Создать компонент». В появившемся списке, дважды щелкнем на изображении точки с тремя стрелочками — так включается режим создания Значений путем выбора полей из контекста. В появившемся списке дважды щелкнем по полям CARRNAME и CURRCODE — слева них появится зеленая галочка. Нажмем кнопку «Создать» внизу списка, после этого созданные Значения отобразится в дереве структуры (и они уже будут иметь связь с контекстом), как это показано на Рис.17:
Рис.17. Добавление Значений в дерево структуры
Теперь остается только сопоставить созданные Значения с целевыми ячейками шаблона по схеме, показанной на Рис.18:
Рис.18. Схема связи Значений с целевыми ячейками шаблона
Для этого выделим узел компонента в дереве структуры, затем выделим целевую ячейку шаблона, после этого, во вкладке «Свойства компонента» в пункте «Область в шаблоне» нажмем кнопку с карандашом. Связь с шаблоном установлена.
5.2.5. Активация формуляра
Активируем формуляр нажатием кнопки со «спичкой».
5.3. Программа печати
Вставим в подпрограмму FILL_CONTEXT новые строчки кода (ниже заполнения полей Исполнитель/ Телефон/ E-mail):
*=======================================================================
* 2) Таблица авиакомпаний
*=======================================================================
SELECT *
INTO TABLE gs_context-tabcarr[]
FROM scarr .
5.4. Проверка результата
Запустим нашу программу печати ZXLWB_EXAMPLE1 и увидим такой результат, как на Рис.19:
Рис.19. Печать отчёта
6. Вывод футера с логотипом
Под таблицей выведем нижнюю часть формы, называемую футером, или «подвалом». В футер поместим картинку (логотип), которая будет загружаться в формуляр прямо из WEB-репозитария. Мы можем её видеть в транзакции SMW0 (Рис.20):
Рис.20. Объект логотипа в WEB-репозитарии
6.1. Контекст
Добавим в контекст новое поле LOGO с типом RAWSTRING (Рис.21):
Рис.21. Добавление поля в контекст
6.2. Формуляр
Перезапустим транзакцию ZXLWB_WORKBENCH, для актуализации контекста в форме.
6.2.1. Разметка шаблона
Добавим прямоугольную область, внутри которой будет располагаться логотип. Он будет занимать несколько объединенных ячеек в правом нижнем углу этой области (Рис.22):
Рис.22. Локализация логотипа в форме
6.2.2. Добавление компонентов Паттерна и Рисунка
Добавим Паттерн ниже Цикла (на одном уровне с ним). Для этого, выделим в дереве структуры вышестоящий узел SHEET и нажмем на кнопку «Создать компонент». Из появившегося списка выберем компонент Паттерн. На следующем экране укажем его название и описание. После этого созданный компонент Паттерн отобразится в дереве структуры (Рис.23):
Рис.23. Паттерн в дереве структуры
Для созданного Паттерна FOOTER создадим дочерний узел Рисунок. Выделим узел Паттерна в структуре формуляра и нажмем на кнопку «Создать компонент». Из появившегося списка выберем компонент Рисунок. На следующем экране укажем его название и описание. После этого созданный компонент отобразится в дереве структуры (Рис.24):
Рис.24. Рисунок в дереве структууры
Теперь необходимо сопоставить созданные Паттерн и Рисунок с областями шаблона по схеме, показанной на Рис.25:
Рис.25. Схема связи компонентов с шаблоном
Для этого выделим узел компонента в дереве структуры, затем выделим целевую область шаблона, после этого, во вкладке «Свойства компонента» в пункте «Область в шаблоне» нажмем кнопку с карандашом. Связь с шаблоном установлена.
Для компонента Рисунок дополнительно необходимо установить связь с
Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland
Зарегистрироваться
У вас уже есть учетная запись?
Войти
Из моего опыта общения с парой SAP-Excel могу сказать, что существует три основных способа вставки табличных данных в Excel.
1. Можно вставить данные в Excel через буфер обмена на клиентской машине. (для этого их надо туда скопировать, например, с помощью ФМ CLPB_EXPORT)
2. Можно выгрузить tab-delimited файл клиенту и открыть его в Excel.
3. Можно выгрузить файл в каком-нибудь формате на машину клиенту и вставить его в Excel через QueryTables.
При втором способе почти не получится влиять на преобразование типов полей, а в первом варианте это не достаточно гибко. В третьем же случае можно определять формат вставляемого файла как угодно (задавать и разделитель, и формат столбцов).
Названия готового ФМ сам не знаю, но можно довольно легко написать собственный ФМ, работающий с Excel через OLE, например, одним из перечисленных способов (при этом гибкость реализации будет выше).
_________________
Счастье есть!
Часовой пояс: UTC + 3 часа
Кто сейчас на конференции
Сейчас этот форум просматривают: Google [Bot]
SAP форум.RU © 2000-2012 Михаил Вершков
Python для генерации статических отчетов XLSX по данным SAP-систем
Статья предназначена в первую очередь для консультантов и архитекторов, работающих с продуктами SAP, перед которыми стоит задача проектирования и реализации решения по подготовке отчетности в формате Excel.
В настоящее время все большую популярность набирают облачные решения для визуализации данных, демонстрируя двузначный рост год-к-году по большинству показателей. Однако не все компании — клиенты поставщиков облачных решений могут позволить себе использовать “облака” по самым разным причинам: от требований безопасности данных до недостаточной функциональности или даже более высокой стоимости владения по сравнению с on-premise.
Поэтому время от времени возникают задачи подготовки отчетности для визуализации в on-premise-инструментах. Автор долгое время работал и продолжает работать с решениями SAP, поэтому именно решения SAP (SAP BW/4, SAP S/4), как поставщики данных для отчетности, наиболее близки. Однако предлагаемый подход может быть скопирован и на другие системы-источники. Никаких препятствий к этому нет.
Задача формулируется так: реализовать on-premise решение по автоматической и регулярной подготовке отчетов по бизнес-данным SAP-систем (BW/4 или S/4).
Технические требования к отчетам:
минимальное время отклика при открытии отчета пользователем (2-4 сек)
возможность смотреть отчеты как на настольном, так и на мобильном устройстве (планшет, телефон)
комбинация табличных и графических представления данных на одной странице
несколько страниц (вкладок) с отчетами
корректное разбиение на страницы при печати на принтере/PDF.
отдельные табличные представления могут содержать большое число строк и/или столбцов (более 1 млн ячеек совокупно).
реализуют кросс-табличный формат
содержат итоги, подитоги по строкам и столбцам.
содержат иерархические группировки
содержат данные нарастающим итогом по календарным аналитикам
поддерживают функции “автофильтр”, “фиксация прокрутки” и некоторые другие функции Excel (например, комментарии к ячейкам, merge cells)
добавление статических картинок
условное форматирование ячеек
построены по csv-выгрузкам данных из исходных систем. Это означает, что отчеты содержат данные, сформированные на момент выгрузки данных из исходных систем. Чем чаще выполняется выгрузка, тем более актуальные данные в отчетах.
Наиболее близкими стандартными инструментами SAP, подходящими для этой задачи, является a)SAP BW on HANA + Broadcaster или b)SAP BW/4 HANA + SAP BI Platform + SAP Crystal Report Enterprise + Publishing.
Вариант a) подходит для клиентов, остающихся пока на решении SAP BW on HANA.
Вариант b) — для клиентов, перешедших на новое перспективное решение SAP BW/4 HANA и имеющих лицензии SAP BI Platform
Однако, оба этих варианта имеют те или иные ограничения, которые может быть крайне непросто или даже невозможно преодолеть, в т.ч. даже с добавлением “точечной” разработки (макросы VBA, ABAP-программы или кода на встроенном script-языке в Crystal Reports). Даже если в первоначальной постановке задачи нерешаемых требований нет, это не означает, что в будущем такие требования не появятся. Это означает, что лучше с самого начала выбрать подход, достаточно гибкий для решения как известных сейчас, так и неизвестных, но ожидаемых будущих требований.
Очевидно, что реализация третьего варианта, варианта с) будет с высокой долей собственной разработки отдельных компонентов целевого решения. Какие же опции могут существовать для технологических решений SAP в этом случае?
Существуют классы из библиотеки ABAP2XLSX (Apache2 licence model). Написанные на ABAP, они содержат методы по генерации XLSX-файла без использования Excel: XLSX-файлы создаются напрямую из кода на ABAP. Создав программную “обертку” для этих классов внутри S/4 или BW, вы можете генерировать XLSX-файлы с требуемым форматированием. Запускать эту генерацию возможно как диалоговом, так и в пакетном (batch) режиме, что позволяет настроить автоматическую публикацию, рассылку и пр. по расписанию или событиям.
Таким образом, все стадии процесса: извлечение данных, преобразования в формат отчета и генерация XLSX реализуются на одном языке (ABAP), и являются неотъемлемой частью хорошо знакомой в SAP-мире инфраструктуры жизненного цикла и среды выполнения ABAP-кода.
Но представляет интерес и альтернативный подход, который при определенном масштабе более эффективен и функционален. Речь идет о генерации XLSX-файла в коде на Python. Существует минимум две очень популярные python-библиотеки генерации Excel-кода: openpyxl и xlsxwriter. Это дает больше гибкости при выборе и развитии вашего решения, чем использование единственно возможной библиотеки на ABAP.
Процессы целевого решения могут выглядеть, например, так:
Данные системы-источника выгружаются на регулярной основе в текстовые csv-файлы. Файлы выгружаются в каталоги сервера приложений SAP или на выделенный файловый сервер или даже в облачный каталог, если это позволяют политики безопасности.
csv-файлы считываются Python-программой, которая затем выполняет обработку данных (расчет подитогов, итогов, расчет нарастающих итогов, объединение нескольких наборов данных, подтягивание наименований к кодам аналитик и т.п и т.д.), генерацию и публикацию XLSX-файла
Архитектура целевого решения состоит из:
SAP-системы-источника данных, которая генерирует csv-файлы. Генератором файлов может быть:
В последнем случае легко настроить считывание данных из т.н. BW-запросов, в которых нередко реализуют сложную логику расчета бизнес-показателей пользовательских отчетов. Инструмент создания BW-моделей и -запросов (SAP HANA Studio BWMT) нельзя назвать инструментом “конечного пользователя”, но тем не менее он обладает мощным функционалом, позволяющим в создании даже сложных объектов во многих случаях обходиться без программирования. Однако, верно и то, что с помощью этого инструмента добиться желаемой производительности (см. требования выше) практически не представляется возможным. Поэтому результат работы BW-запроса — [кросс-]табличное представление данных — приходится визуализировать в Excel не стандартным инструментом SAP Analysis for Excel, а просто Excel. Но XLSX-файл нужно ещё подготовить и где-то разместить. А для этого применяются.
Python-программы, использующие библиотеки:
работы с данными — pandas;
генерации XLSX-файлов — openpyxl или/и xlsxwriter;
любые другие библиотеки Python для дополнительных преобразований считанных из файлов данных;
Сервер для запуска Python-программ. При наличии лицензий, можно рассмотреть SAP Data Intelligence, но подойдут и другие решения. На самых начальных этапах, при небольшом количестве Python-программ — генераторов XLSX-файлов можно обойтись средствами планирования задач операционной системы
Полученный XLSX-файл конечный пользователь может просмотреть как в Excel, так и его opensource-аналогах (LibreOffice, OpenOffice). Последнее особенно важно для компаний, в которых не используются продукты Microsoft Office или планируется от них отказаться. Использование же стандартного on-premise SAP-инструмента для визуализации данных BW-отчетов — SAP Analysis for Excel невозможно без Excel, т.к. технически он является его addOn.
Несколько слов про центральную часть архитектуры — Python-программы. Принимая во внимание, что генерировать XLSX-файл можно и с помощью ABAP-библиотеки, в Python это делать во многих аспектах удобнее:
существенно больше программистов на Python, чем на ABAP. Python изучают чуть ли не в школах, не говоря уже о ВУЗах. Нетрудно предположить, что и уровень зарплатных ожиданий для Python также ниже при прочих равных
Существенно больше готовых и бесплатных Python-библиотек, которые выполнят необходимые преобразования и расчеты.
возможно разрабатывать Python-код для генерации XLSX-файлов без доступа к SAP-системам, практически в offline-режиме. Так удобнее отдавать работу на outsource.
проще пользоваться всеми возможностями git-репозиториев. Да, в ABAP это тоже возможно, но это гораздо менее распространено.
Более лаконичный код, чем на ABAP.
Например, при таких исходных данных для визуализации
следующий компактный код
выполняет преобразование строк в исходном массиве: разбивает строку на поля, разделенные ;. Последние 2 поля, которые по смыслу есть “показатели”, сохраняются как числа float. Первые 4 поля — это аналитики и хранятся как строки.
На выходе кода — кросс-таблица, в которой по строкам — развертка по полям A и B, а по столбцам — развертка по полям C и D. Поле E — один (из двух в исходных данных) показателей, используемый в кросс-таблице.
Если добавить код для расчета подитогов и итогов по строкам и столбцам (еще 5 — 6 строк кода), получится
Очевидно, что это уже почти готовая “матрица” для публикации в XLSX, после чего останется только применить форматирование [опять же, методами Python-библиотеки генерации XLSX] и файл готов. Файл можно публиковать средствами Python или операционной системы, и затем открывать в Excel, LibreOffice и т п.
Что касается производительности и потребления системных ресурсов при выполнении всех шагов процесса, начиная от выгрузки данных в csv из SAP и заканчивая генерацией XSLX-файла в Python-программе, то предложенная архитектура позволяет управлять распределением нагрузки, перенося ее с одних компонент на другие.
Например, если Python-код потребляет слишком много памяти при выполнении подготовки данных (слишком сложные расчеты или/и миллионы строк в выгрузке), то можно, не меняя степени параллелизации выполнения Python, и не выполняя аппаратного масштабирования, рассмотреть перенос вычислений или/и большее уплотнение данных на стороне SAP-сервера. Возможно и обратное, когда уменьшать нагрузку следует уже на SAP-сервер.
SAP R/3 форум ABAP консультантов
Russian ABAP Developer’s Club
Russian ABAP Developer’s Club Forum Index -> Submit a new program | Новые материалы, программы для сайта
View previous topic :: View next topic | ||||||||||||||||||||||||
Author | Message | |||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Anton Sikidin Участник соглашение по переменным: соглашение по заполнению шаблона: шаблон сохраняем как таблица xml 2003 загружаем шаблон, выбираем имя. в программе когда все переменные посчитаны вызвать форму
в таблице it_source находится сгенерированный xml документ, Z_TEST_EXPORT_TO_EXCE — имя шаблона. тестовый шаблон в приложении test.xml, рабочий легкоадоптируемый пример ниже, впримере показано как правильно выгрузить xml документ в кодировке utf-8 и избежать проблем с конвертацией. Генерировать xml отчеты на ABAP — это как генерировать html странички на PHP: нет в этом ничего страшного и интересного. парсер странно работает,и покорежил текст программы, прикладываю в приложении sample.rar types data *выбираем данные * генерируем XML * оперделяем кодировку IF sy-subrc <> 0. * выгружаем данные form export_to_excel TABLES it_source type tt_string using IV_OBJID TYPE W3OBJID . : KEY type WWWDATATAB LOOP AT lt_bufer INTO wa_bufer . find REGEX ‘($#(.*)$#)’ in wa_bufer SUBMATCHES lv_str lv_str2. REPLACE lc_lt in lv_str2 WITH ‘<‘. ASSIGN (lv_str2) to <field>. REPLACE REGEX ‘($#(.*)$#)’ in wa_bufer WITH lv_str3. APPEND wa_bufer to it_source. » if tabname defined — loop at table ASSIGN (lv_tabname) to <table>. LOOP AT <table> ASSIGNING <wa>. clear lv_tabname. » get key of object OBJ_NAME RELID = ‘MI’ PGMID = ‘R3TR’ OBJECT = ‘W3MI’ » get object » convert raw data to string » process template 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. » find table name » new row occured, process buffer «reach end of row, add last line to buffer and process buffer —————————————-старая версия——————————————— Сам этим методом пользуюсь уже около 2-х лет, это модифицированный вариант того что нам принесли и показали, изначальное авторство неизвестно. Недавно меня спросили как я делаю такие красивые отчеты, и я подумал что это будет полезно еще кому-нибудь. работает на системах с поддержкой юникода. Иногда нужно получить красивый отчет для бухгалтерии вроде такого обычно образец этого отчета приходит в Excel. открываем шаблон, и заменяем все переменные тексты переменными из программы, завернув их в $#$# например $#sy-datum$# есть правило по одной переменной на ячейку, если нужно больше собираете заранее в 1-ну переменную и кладете ее в ячейку первая ячейка каждой строчки должна содержать текст, если текст не нужен, тогда пробел. в строке которую нужно размножить ставим $!$ играемся со шрифтами, форматом отображения и прочее. у нас получается такой шаблон
ставим курсор в ячейку а1 и сохраняем как Таблица XML 2003 (*.xml) полученный файл скармливаем программе Z_ASIKIDIN_TEMP, исходники в архиве, программа простая содержит только текст, запускаем выбираем файл жмем F8. рядом с файлом появятся 2 файла: один %имя%.txt второй %имя%1.txt нам нужен второй. открываем копируем все в какой-нибудь инклюд. иногда в ячейке много текста что он не помещается в одну строку редактора
в конце строки закрываем кавычку ставим точку, в начале следующей строки добавляем xml_simple ‘
в том месте где мы ставили $!$ будет длинный комментарий выделено красным, начало и конец строки выделено фиолетовым. все это дело заворачиваем в loop
для ячеек содержащих дату меняем в самом конце поменять xml_download4. или поменять это в генераторе. когда нужно распечатать if pa_print is not INITIAL. в самом начале нужно подключить 2 инклюда с макросами и переменными, или можно их слить в один include ZBFI_RES_DEBT_uni. » unicode convert все отчет готов! исходники и рабочие примеры в архиве Z_ASIKIDIN_XML — демо пример инклюды необходимые для работы Генератор отчета сам отчет
Сейчас пытаюсь испробовать на документе. Скажите, а как сделать так, чтобы при пустых ячейках рамка не копировалась? в sample.rar ни в программе ни в xml-ке ненашел строки ss:StyleID=»s27″ Для примера sample.rar нужно после строки 165
Добавить
Это хардкод, но работает, красивое решение позже. Можно дописать в шаблон свли стили. не прокатил. |