Link Search Menu Expand Document

Импорт данных во внутреннюю таблицу из Excel или CSV файла с указанием мэппинга и обработкой ошибок

image


Примеры ZCL_EUI_FILE_IO

SE38 -> ZEUI_TEST_EXCEL

" Тип загрузки из Excel
DATA(lo_file_io) = NEW zcl_eui_file_io(
  iv_file_name    = zcl_eui_file=>mc_extension-xlsx
  " Заголовок экрана ( для метода SHOW )
  iv_status_title = `Загруженные данные` ).

" Показ Open диалога (метод ZCL_EUI_FILE)
lo_file_io->import_from_file(
  iv_window_title = `Пожалуйста укажите файл для загрузки` ).
 
" Данные о полете
DATA(lt_import) = VALUE spfli_tab( ). 
 
" Загружаем все поля SPFLI, без проверки ошибок
lo_file_io->export_to_itab(
  ir_table        = REF #( lt_import )
  iv_row_from     = 2       " Со второй строки
).

" Если пользователь подтвердил данные в новом экране
CHECK lo_file_io->popup( )->show( ) = 'OK'.

" Данные о полете
DATA(lt_import) = VALUE spfli_tab( ).

" Тип загрузки из CSV
DATA(lo_file_io) = NEW zcl_eui_file_io(
  iv_file_name    = zcl_eui_file=>mc_extension-csv ).

" Файл в виде строки
lo_file_io->import_from_string(
  iv_string   = lv_csv_data
  " ПУ UTF-8
  iv_encoding = zcl_eui_conv=>mc_encoding-utf_16le ).

" Укажем мэппинг нужных полей. Прочие будут проигнорированы
DATA(lt_mapping) = VALUE zcl_eui_file_io=>tt_excel_map(
   " Для Excel удобнее column_name = 'B', 'C', 'D'
   ( field = 'CARRID'    column_index = 2 )
   ( field = 'CONNID'    column_index = 3 )
   ( field = 'COUNTRYFR' column_index = 4 )
).

" Используем значения IV_ENCODING, IV_ROW_DELIMITER, IV_FIELD_DELIMITER пу
" Указать можно вызвав EXPORT_TO_ITAB_CSV( )
lo_file_io->export_to_itab(
  ir_table        = REF #( lt_import )
  it_excel_map    = REF #( lt_mapping )
*  iv_row_from     = 1 " С первой строки
).

" Если файл содержит данные
CHECK lt_import[] IS NOT INITIAL.

...

METHODS:
  " Обработчик ошибок импорта данных (-> EXPORT_TO_ITAB)
  on_mapping_error FOR EVENT mapping_error OF zcl_eui_file_io
    IMPORTING
        iv_source    " Исходный текст
        iv_row       " Номер строки
        is_excel_map " Мэппинг поля
        io_error     " CX_* исключение
        cv_value     " Значение для изменения cv_value->*
        cs_row.      " Строка импортируемой таблицы
...

" Тип загрузки из Excel
DATA(lo_file_io) = NEW zcl_eui_file_io( ).

" Файл из сетевой папки
lo_file_io->import_from_file( iv_full_path = `I:\$secret\2020-06-27.xlsx` ).

" Укажем мэппинг нужных полей. Прочие будут проигнорированы
DATA(lt_mapping) = VALUE zcl_eui_file_io=>tt_excel_map(
   ( field = 'CARRID'    column_name = 'B' )
   ( field = 'CONNID'    column_name = 'C' )

...

" Загрузка данных
lo_file_io->export_to_itab(
  ir_table        = REF #( lt_import )
  " Если нет мэппинга загружаем все поля
  it_excel_map    = REF #( lt_mapping )
  " Если нет обработчика исключение
  io_handler      = me
).

...

METHOD on_mapping_error.
  " Значение пу в случае ошибки
  IF is_excel_map-field = 'DISTANCE'.
    ASSIGN cv_value->* TO <lv_distance>.
    " Исходное значение в виде строки IV_SOURCE
    <lv_distance> = 77777.
  ENDIF.
  
...

image


Стандартные способы

Наверное многие знают про CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE' для импорта из Excel
и cl_gui_frontend_services=>gui_upload( filetype = 'DAT' ) для импорта из CSV.

Но данные методы имеют ряд ограничений:

  • ALSM_EXCEL_TO_INTERNAL_TABLE работает через OLE (есть проблемы при копировании большого объема данных)
  • Оба работают только с Presentation Server
  • Нет обработки ошибок в файле и мэппинга данных (Какой столбец куда должен попасть)

Особенности реализации

  • Класс ZCL_EUI_FILE_IO наследует от ZCL_EUI_FILE. И умеет все что умеет делать родитель.

  • Для Excel используется класс CL_FDT_XL_SPREADSHEET (доступный с 7.02) который лишен проблем с OLE. https://codezentrale.de/abap-excel-datei-xlsx-in-interne-tabele-laden-cl_fdt_xl_spreadsheet-2/

  • CSV в свою очередь поддерживает разные символы для разделения данных и разные кодировки

image

  • Обработка ошибок в файле (дата или число не правильного формата) происходит с помощю события MAPPING_ERROR
    В обработчике можно обработать ошибку и изменить само значение

image

  • В таблице мэппинга вы можете указать column_name или column_index
    Сам мэппинг не обязателен. Если он не указан он будет совпадать с внутренней таблицей, те первый столбец таблицы столбец A, второй B итд
     " Field of internal table
     field        TYPE fieldname,

     " Convenient for Excel
     column_name  TYPE char3,

     " More convenient for CSV. Could be filled automatically
     column_index TYPE i,

Тк данный класс наследует от ZCL_EUI_FILE, то ему доступны его методы.
Это дает возможность писать цепочки как и в родителе

Для загрузки из файла цепочка может выглядеть следующим образом

 " Если указать расширение файла 'xlsx' или 'csv', диалоги сохранения(открытия)
 " и метод EXPORT_TO_ITAB будут сразу же настроены
 " Также в конструктор можно передать XSTRING
 new ZCL_EUI_FILE( IV_FILE_NAME = 'xlsx' )->
    " Данный шаг может быть заменен на загрузку из любого источника
    IMPORT_FROM_FILE( )->
    " Сам импорт с указанием обработчика ошибок
    EXPORT_TO_ITAB( io_handler = me)

IMPORT_FROM_ITAB

Импорт из внутренней таблицы(те выгрузку в файл) работает наподобие простого отчета
Для более сложных отчетов лучше использовать https://github.com/bizhuka/xtt

TODO Экспорт нескольких внутренних таблиц в 1 файл без указания шаблона(Для debug)