When I was using SAP Data Services 4.2.13 last year, I faced some challenges in loading some data from some “Unstable excel files”. These excel files had some strange formats and, it was required to fetch data from those files even when sometimes the columns were coming swapped or missing.
To write an excel to a table using SAP Data Services in cases where the excel is somehow “complex” you can use Python in a user-defined transform.
If you are familiar with some programming code (if you know Python better) this tutorial will help you with this task.
So let’s do it!
Pre-requirements
Remember that the Python you are using depends on what you have installed in your system. It might be Python 2 in the old versions or Python 3. Make sure you have Python 3 installed on the Data Services server otherwise you will have a lot of issues with text fields.
Be sure you have all the libraries needed. probably you will need to have a good bases to support you on this if you are not familiar with pip or if you don’t have the right authorizations to install them on the server.
Creating the Logic
The first step is to define your structure and flow.
Programing in your User-Defined transform
Keep all of your logic to read the excel and identify the columns you need.
Then use highlighted lines of code to write to output.
You will also need to define the output columns in the UDT editor by clicking on the “Launch Python Editor …” button.
Then on the left side click I/O Fields and Output Fields right click and hit “Insert…” menu item.
Do this for each of your output columns (in the example gave 6 of them)
Then in the Output tab of the main UDT editor screen, select the 6 columns and they will be mapped to Schema Out.
You will need to possibly call the AddRecord function in a loop, once for each row in the excel.
Code used
import csv
import xlrd
#import xlsxwriter
#from xlwt import Workbook
from os import sys
newRec = DataManager.NewDataRecord()
Collection.GetRecord(newRec, 1)
path = newRec.GetField(u’FILE_PATH’) + u’\’
print path
workbook = xlrd.open_workbook(path + u’Master_Sheet.xlsx’)
worksheet = workbook.sheet_by_name(u’Learning Rooms’)
#wb = xlsxwriter.Workbook()
#wb = xlsxwriter.Workbook(path + u’new_Master_Sheet.xlsx’)
#sheet1 = wb.add_worksheet(‘first_sheet’)
for row_index in xrange(worksheet.nrows):
newRecord = DataManager.NewDataRecord(1)
for col_index in xrange(worksheet.ncols):
if worksheet.cell(0,col_index).value == u’Learning Room Name ‘:
newRecord.SetField(u’Learning Room Name’, worksheet.cell(row_index,col_index).value)
#sheet1.write(row_index,new_col_index,worksheet.cell(row_index,col_index).value
if worksheet.cell(0,col_index).value == u’Jam Group ID (required by KTE Reporting Services)’:
newRecord.SetField(u’Jam Group ID’, worksheet.cell(row_index,col_index).value)
if worksheet.cell(0,col_index).value == u’Learning Room Type’:
newRecord.SetField(u’Learning Room Type’, worksheet.cell(row_index,col_index).value)
if worksheet.cell(0,col_index).value == u’Learning Room Technical ID’:
newRecord.SetField(u’Learning Room Technical ID’, worksheet.cell(row_index,col_index).value)
if worksheet.cell(0,col_index).value == u’Region Requester ‘:
newRecord.SetField(u’Region Requester’, worksheet.cell(row_index,col_index).value)
if worksheet.cell(0,col_index).value == u’Status’:
newRecord.SetField(u’Status’, worksheet.cell(row_index,col_index).value)
#col_index = col_index +1
Collection.AddRecord(newRecord)
del newRecord
#print new_col_index
#wb.close()
#new_workbook = xlrd.open_workbook(path + u’new_Master_Sheet.xlsx’)
#new_worksheet = new_workbook.sheet_by_name(u’first_sheet’)
#with open(u'{}’.format(path + u’Master_Sheet.csv’), u’wb’) as csvfile:
# writetocsv = csv.writer(csvfile, quoting = csv.QUOTE_ALL)
# for rownum in xrange(new_worksheet.nrows):
# writetocsv.writerow([unicode(x).encode(u’utf-8′) for x in new_worksheet.row_values(rownum)])
# writetocsv.writerow(
# list(x.encode(u’utf-8′) if type(x) == type(u”) else x for x in worksheet.row_values(rownum))
# )
#csvfile.close()
del newRec
del path
del workbook
del worksheet
I hope this is useful to you guys. Let me know in the comments if you have any questions and your findings and what yet what kind of post you would like to see here.
Happy coding!
Автор | Сообщение | ||
---|---|---|---|
Заголовок сообщения: Импорт данных из Excel в внутреннюю таблицу Добавлено: Чт, авг 25 2011, 08:48 |
|||
|
Подскажите пожалуйста ФМы или Методы для импорта данных из Excel. Хотелось бы чтобы была возможность обращения к конкретной странице
|
||
Вернуться к началу |
|
||
LinevskiySV |
Заголовок сообщения: Re: Импорт данных из Excel в внутреннюю таблицу Добавлено: Чт, авг 25 2011, 09:23 |
|
|
Вернуться к началу |
|
BenderMTB |
Заголовок сообщения: Re: Импорт данных из Excel в внутреннюю таблицу Добавлено: Чт, авг 25 2011, 13:14 |
||
|
ФМ ALSM_EXCEL_TO_INTERNAL_TABLE работает, но у него есть ограничение в 50 символов. TYPE-POOLS: OLE2. Code: DATA: App TYPE ole2_object, Create object App ‘Excel.Application’.
|
||
Вернуться к началу |
|
||
Besa |
Заголовок сообщения: Re: Импорт данных из Excel в внутреннюю таблицу Добавлено: Чт, авг 25 2011, 16:41 |
|
BenderMTB написал(а): ФМ ALSM_EXCEL_TO_INTERNAL_TABLE работает, но у него есть ограничение в 50 символов. Да, есть такое, поэтому его копируют в ZALSM_EXCEL_TO_INTERNAL_TABLE и немножко изменяют, и получается 255.
|
Вернуться к началу |
|
Parazit |
Заголовок сообщения: Re: Импорт данных из Excel в внутреннюю таблицу Добавлено: Чт, авг 25 2011, 23:03 |
|
|
Вернуться к началу |
|
LinevskiySV |
Заголовок сообщения: Re: Импорт данных из Excel в внутреннюю таблицу Добавлено: Пт, авг 26 2011, 16:50 |
|
Besa написал: BenderMTB написал(а): ФМ ALSM_EXCEL_TO_INTERNAL_TABLE работает, но у него есть ограничение в 50 символов. Да, есть такое, поэтому его копируют в ZALSM_EXCEL_TO_INTERNAL_TABLE и немножко изменяют, и получается 255. Да большинство людей скорее всего так и сделали, когда пришлось работать с данным ФМ
|
Вернуться к началу |
|
DrAlexNone |
Заголовок сообщения: Re: Импорт данных из Excel в внутреннюю таблицу Добавлено: Ср, сен 07 2011, 15:16 |
||
|
На самом деле в ФМ ALSM_EXCEL_TO_INTERNAL_TABLE в обработке есть серьезный косяк, который описан в SAP NOTES, данная ФМ импортирует не более 10000 строк. Проблема в типе NUMC4 для указания их числа. Легко переписывается или копируется в пользовательскую Z функцию с минимальными изменениями в типах полей.
|
||
Вернуться к началу |
|
||
Besa |
Заголовок сообщения: Re: Импорт данных из Excel в внутреннюю таблицу Добавлено: Ср, сен 07 2011, 15:31 |
|
А точно, и это тоже… Будем юзать разработку Parazit-а
|
Вернуться к началу |
|
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.
Excel to Internal Table
In the following program I have entered an excel with
data. Now I need to pass this excel into SAP system. The data will be converted
into internal format of SAP and an internal table will be populated. Finally
when we have the data in our internal table then we can use those data as
required. In this example I have used Field-Symbol. We can use normal internal
table & work area in the same fashion.
REPORT zsr_bdc
NO STANDARD PAGE HEADING LINE-SIZE 255.
TYPE-POOLS truxs.
DATA dref TYPE REF TO data.
TYPES: BEGIN OF ts_excl,
ccode TYPE string,
porg TYPE string,
accgrp TYPE string,
END OF ts_excl.
FIELD-SYMBOLS: <wa_excl> TYPE ts_excl,
<it_excl> TYPE STANDARD TABLE,
<it_data> TYPE STANDARD TABLE.
INITIALIZATION.
PARAMETERS p_file TYPE rlgrap—filename.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
PERFORM f4_filename.
START-OF-SELECTION.
PERFORM convert_excel_to_table.
PERFORM display_data.
*&———————————————————————*
*& Form F4_FILENAME
*&———————————————————————*
*& text
*&———————————————————————*
FORM f4_filename .
CALL FUNCTION ‘F4_FILENAME’
EXPORTING
field_name = ‘P_FILE’
IMPORTING
file_name = p_file.
ENDFORM.
*&———————————————————————*
*& Form CONVERT_EXCEL_TO_TABLE
*&———————————————————————*
*& text
*&———————————————————————*
FORM convert_excel_to_table .
CREATE DATA dref TYPE truxs_t_text_data.
ASSIGN dref->* TO <it_data>.
CREATE DATA dref TYPE TABLE OF ts_excl.
ASSIGN dref->* TO <it_excl>.
CALL FUNCTION ‘TEXT_CONVERT_XLS_TO_SAP’
EXPORTING
i_line_header = ‘X’
i_tab_raw_data = <it_data>
i_filename = p_file
TABLES
i_tab_converted_data = <it_excl>
EXCEPTIONS
conversion_failed = 1
OTHERS = 2.
ENDFORM.
*&———————————————————————*
*& Form DISPLAY_DATA
*&———————————————————————*
*& text
*&———————————————————————*
FORM display_data .
WRITE: / ‘Company’,
12 ‘Purchase Org.’,
42 ‘Account Group’.
ULINE.
IF <it_excl> IS ASSIGNED.
LOOP AT <it_excl> ASSIGNING <wa_excl>.
WRITE: /4 <wa_excl>—ccode,
12 <wa_excl>—porg,
42 <wa_excl>—accgrp.
ENDLOOP.
ENDIF.
ENDFORM.
The excel file is as follows.
Execute the program and then browse the excel file.
The output is as follows.
Одна ячейка в EXCEL-таблице соответствует одному полю во внутренней таблице.
Допустим есть EXCEL-таблица
Перенесем ее в нашу внутреннюю таблицу SAP.
*&———————————————————————*
*& Report ZDOWNLOAD_ME41
*&
*&———————————————————————*
report zdownload_me41.
«структура соответствует загружаемому файлу из EXCEL <<<
types: begin of ta_excel,
txz01 type ekpo—txz01,
anmng type rm06e—anmng,
meins type ekpo—meins,
end of ta_excel,
«>>>
tt_excel type standard table of ta_excel.
data: excel_tab type tt_excel.
parameters: filename like rlgrap—filename obligatory.
«Событие — обработка F4 для имени файла
at selection-screen on value-request for filename.«Запрос имени файла
call function ‘WS_FILENAME_GET’
exporting
def_filename = ‘ ‘
mask = ‘,*.xls,*.xls.’
mode = ‘O’
title = ‘Выбор файла‘
importing
filename = filename
exceptions
inv_winsys = 01
no_batch = 02
selection_cancel = 03
selection_error = 04.
start-of-selection.
*собственно сама загрузка excel файл во внутр.таблицу
perform select_from_excel.
*&———————————————————————*
*& Form SELECT_FROM_EXCEL
*&———————————————————————*
* Данные из EXCEL в табл.
*———————————————————————-*
form select_from_excel .
data: lt_raw type truxs_t_text_data.
call function ‘TEXT_CONVERT_XLS_TO_SAP’
exporting
* I_FIELD_SEPERATOR =
* I_LINE_HEADER =
i_tab_raw_data = lt_raw
i_filename = filename
tables
i_tab_converted_data = excel_tab
exceptions
conversion_failed = 1
others = 2.
if sy—subrc <> 0.
message ‘Ошибка загрузки данных из файла‘ type ‘E’.
endif.
endform. » SELECT_FROM_EXCEL
Результат данных манипуляций