В общем для упрощения работы и расширения функциональности были разработаны два модуля для чтения данных из EXCEL (на основании ALSM_EXCEL_TO_INTERNAL_TABLE) и второй модуль который производит заполнение внутренней таблицы переданной в качестве параметра, при этом если в таблице EXCEL есть имена колонок (строка заголовка), то данные раскладываются по соответствующим полям внутренней таблицы.
Функциональный модуль: Y_ALSM_EXCEL_TO_INTERNAL_TABLE - Чтение данных из EXCEL таблицы с заданного листа/активного листа. Читается или все данные листа или только данные из выбранной области. Структура YTSH_ALSMEX_TABLINE, аналогична структуре ALSMEX_TABLINE, только переменная VALUE расширена до 255 символов, тут как говорится по желанию.
FUNCTION y_alsm_excel_to_internal_table .
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*" IMPORTING
*" VALUE(FILENAME) LIKE RLGRAP-FILENAME
*" VALUE(SHEET_NAME) TYPE CHAR30 OPTIONAL
*" VALUE(I_BEGIN_COL) TYPE I OPTIONAL
*" VALUE(I_BEGIN_ROW) TYPE I OPTIONAL
*" VALUE(I_END_COL) TYPE I OPTIONAL
*" VALUE(I_END_ROW) TYPE I OPTIONAL
*" TABLES
*" INTERN STRUCTURE YTSH_ALSMEX_TABLINE
*" EXCEPTIONS
*" INCONSISTENT_PARAMETERS
*" ERROR_OLE
*"----------------------------------------------------------------------
DATA: excel_tab TYPE ty_t_sender.
DATA: ld_separator TYPE c.
DATA: application TYPE ole2_object,
workbook TYPE ole2_object,
range TYPE ole2_object,
worksheet TYPE ole2_object,
activeworkbook TYPE ole2_object.
DATA: h_cell_start TYPE ole2_object,
h_cell_end TYPE ole2_object.
DATA:
ld_rc TYPE i.
* Rückgabewert der Methode "clipboard_export "
* Makro für Fehlerbehandlung der Methods
DEFINE m_message.
case sy-subrc.
when 0.
when 1.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
when others. raise error_ole.
endcase.
END-OF-DEFINITION.
* check parameters
IF i_begin_row > i_end_row. RAISE inconsistent_parameters. ENDIF.
IF i_begin_col > i_end_col. RAISE inconsistent_parameters. ENDIF.
* Get TAB-sign for separation of fields
CLASS cl_abap_char_utilities DEFINITION LOAD.
ld_separator = cl_abap_char_utilities=>horizontal_tab.
* open file in Excel
IF application-header = space OR application-handle = -1.
CREATE OBJECT application 'Excel.Application'.
m_message.
ENDIF.
SET PROPERTY OF application 'DisplayAlerts' = 0.
m_message.
CALL METHOD OF application 'Workbooks' = workbook.
m_message.
CALL METHOD OF workbook 'Open' EXPORTING #1 = filename.
m_message.
IF sheet_name = space.
GET PROPERTY OF application 'ACTIVESHEET' = worksheet.
m_message.
ELSE.
CALL METHOD OF application 'ActiveWorkbook' = activeworkbook.
m_message.
CALL METHOD OF activeworkbook 'WorkSheets' = worksheet
EXPORTING #1 = sheet_name.
m_message.
CALL METHOD OF worksheet 'Select'.
m_message.
ENDIF.
IF ( i_begin_row = space OR i_begin_col = space ) AND
( i_end_row = space OR i_end_col = space ).
CALL METHOD OF worksheet 'Columns' = h_cell_start.
m_message.
CALL METHOD OF worksheet 'Rows' = h_cell_end.
m_message.
ELSE.
* mark whole spread sheet
CALL METHOD OF worksheet 'Cells' = h_cell_start
EXPORTING #1 = i_begin_row #2 = i_begin_col.
m_message.
CALL METHOD OF worksheet 'Cells' = h_cell_end
EXPORTING #1 = i_end_row #2 = i_end_col.
m_message.
ENDIF.
CALL METHOD OF worksheet 'RANGE' = range
EXPORTING #1 = h_cell_start #2 = h_cell_end.
m_message.
CALL METHOD OF range 'SELECT'.
m_message.
* copy marked area (whole spread sheet) into Clippboard
CALL METHOD OF range 'COPY'.
m_message.
* read clipboard into ABAP
CALL METHOD cl_gui_frontend_services=>clipboard_import
IMPORTING
data = excel_tab
EXCEPTIONS
cntl_error = 1
* ERROR_NO_GUI = 2
* NOT_SUPPORTED_BY_GUI = 3
OTHERS = 4
.
IF sy-subrc <> 0. MESSAGE a037(alsmex). ENDIF.
PERFORM separated_to_intern_convert TABLES excel_tab intern
USING ld_separator.
* clear clipboard
REFRESH excel_tab.
CALL METHOD cl_gui_frontend_services=>clipboard_export
IMPORTING
data = excel_tab
CHANGING
rc = ld_rc
EXCEPTIONS
cntl_error = 1
* ERROR_NO_GUI = 2
* NOT_SUPPORTED_BY_GUI = 3
OTHERS = 4.
IF sy-subrc <> 0. MESSAGE a037(alsmex). ENDIF.
* quit Excel and free ABAP Object - unfortunately, this does not kill
* the Excel process
CALL METHOD OF application 'QUIT'.
m_message.
* to kill the Excel process it's necessary to free all used objects
FREE OBJECT h_cell_start. m_message.
FREE OBJECT h_cell_end. m_message.
FREE OBJECT range. m_message.
FREE OBJECT worksheet. m_message.
FREE OBJECT workbook. m_message.
FREE OBJECT activeworkbook. m_message.
FREE OBJECT application. m_message.
ENDFUNCTION.
Используемые подпрограммы INCLUDE LYTSH_ALSMEXF01
*----------------------------------------------------------------------*
***INCLUDE LYTSH_ALSMEXF01 .
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form SEPARATED_TO_INTERN_CONVERT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM separated_to_intern_convert TABLES i_tab TYPE ty_t_sender
i_intern TYPE ty_t_itab
USING i_separator TYPE c.
DATA: l_sic_tabix LIKE sy-tabix,
l_sic_col TYPE kcd_ex_col.
DATA: l_fdpos LIKE sy-fdpos.
REFRESH i_intern.
LOOP AT i_tab.
l_sic_tabix = sy-tabix.
l_sic_col = 0.
WHILE i_tab CA i_separator.
l_fdpos = sy-fdpos.
l_sic_col = l_sic_col + 1.
PERFORM line_to_cell_separat TABLES i_intern
USING i_tab l_sic_tabix l_sic_col
i_separator l_fdpos.
ENDWHILE.
IF i_tab <> space.
CLEAR i_intern.
i_intern-row = l_sic_tabix.
i_intern-col = l_sic_col + 1.
i_intern-value = i_tab.
APPEND i_intern.
ENDIF.
ENDLOOP.
ENDFORM. " SEPARATED_TO_INTERN_CONVERT
*---------------------------------------------------------------------*
FORM line_to_cell_separat TABLES i_intern TYPE ty_t_itab
USING i_line
i_row LIKE sy-tabix
ch_cell_col TYPE kcd_ex_col
i_separator TYPE c
i_fdpos LIKE sy-fdpos.
DATA: l_string TYPE ty_s_senderline.
DATA l_sic_int TYPE i.
CLEAR i_intern.
l_sic_int = i_fdpos.
i_intern-row = i_row.
l_string = i_line.
i_intern-col = ch_cell_col.
* csv Dateien mit separator in Zelle: --> ;"abc;cd";
IF ( i_separator = ';' OR i_separator = ',' ) AND
l_string(1) = gc_esc.
PERFORM line_to_cell_esc_sep USING l_string
l_sic_int
i_separator
i_intern-value.
ELSE.
IF l_sic_int > 0.
i_intern-value = i_line(l_sic_int).
ENDIF.
ENDIF.
IF l_sic_int > 0.
APPEND i_intern.
ENDIF.
l_sic_int = l_sic_int + 1.
i_line = i_line+l_sic_int.
ENDFORM. "line_to_cell_separat
*---------------------------------------------------------------------*
FORM line_to_cell_esc_sep USING i_string
i_sic_int TYPE i
i_separator TYPE c
i_intern_value TYPE ty_d_itabvalue.
DATA: l_int TYPE i,
l_cell_end(2).
FIELD-SYMBOLS: <l_cell>.
l_cell_end = gc_esc.
l_cell_end+1 = i_separator .
IF i_string CS gc_esc.
i_string = i_string+1.
IF i_string CS l_cell_end.
l_int = sy-fdpos.
ASSIGN i_string(l_int) TO <l_cell>.
i_intern_value = <l_cell>.
l_int = l_int + 2.
i_sic_int = l_int.
i_string = i_string+l_int.
ELSEIF i_string CS gc_esc.
* letzte Celle
l_int = sy-fdpos.
ASSIGN i_string(l_int) TO <l_cell>.
i_intern_value = <l_cell>.
l_int = l_int + 1.
i_sic_int = l_int.
i_string = i_string+l_int.
l_int = STRLEN( i_string ).
IF l_int > 0 . MESSAGE x001(kx) . ENDIF.
ELSE.
MESSAGE x001(kx) . "was ist mit csv-Format
ENDIF.
ENDIF.
ENDFORM. "line_to_cell_esc_sep
Данные TOP-иклуда:
FUNCTION-POOL ytsh_alsmex. "MESSAGE-ID ..
TYPE-POOLS: ole2.
* value of excel-cell
TYPES: ty_d_itabvalue TYPE ytsh_alsmex_tabline-value,
* internal table containing the excel data
ty_t_itab TYPE ytsh_alsmex_tabline OCCURS 0,
* line type of sender table
BEGIN OF ty_s_senderline,
line(4096) TYPE c,
END OF ty_s_senderline,
* sender table
ty_t_sender TYPE ty_s_senderline OCCURS 0.
*
CONSTANTS: gc_esc VALUE '"'.
Далее для упрощения чтения данных во внутренние таблицы используется функциональный модуль: Y_TSH_EXCEL_LOAD_TO_INTTABLE. Данные модуль вызывает Y_ALSM_EXCEL_TO_INTERNAL_TABLE а затем полученные данные из ячеек таблицы EXCEL размешает в поля полученной на входе внутренней таблицы.
FUNCTION y_tsh_excel_load_to_inttable .
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*" IMPORTING
*" REFERENCE(FILENAME) LIKE RLGRAP-FILENAME
*" REFERENCE(SHEET_NAME) TYPE CHAR30 OPTIONAL
*" REFERENCE(HEADER_ROW) TYPE SY-TABIX DEFAULT 1
*" TABLES
*" IT_DATA
*" EXCEPTIONS
*" ERROR
*" HEADER_LINE_NOT_SET
*"----------------------------------------------------------------------
DATA: ls_intern LIKE ytsh_alsmex_tabline,
lt_intern LIKE ytsh_alsmex_tabline OCCURS 1 WITH HEADER LINE.
DATA: l_fld_name(50) TYPE c,
l_type(1) TYPE c.
FIELD-SYMBOLS: <fld> TYPE ANY.
IF header_row = space. RAISE header_line_not_set. ENDIF.
CALL FUNCTION 'Y_ALSM_EXCEL_TO_INTERNAL_TABLE'
EXPORTING
filename = filename
sheet_name = sheet_name
TABLES
intern = lt_intern
EXCEPTIONS
inconsistent_parameters = 1
error_ole = 2
OTHERS = 3.
IF sy-subrc <> 0. RAISE error. ENDIF.
REFRESH: it_data.
LOOP AT lt_intern WHERE row <> header_row.
ON CHANGE OF lt_intern-row.
IF it_data <> space. APPEND it_data. ENDIF.
CLEAR: it_data.
ENDON.
READ TABLE lt_intern INTO ls_intern
WITH KEY row = header_row col = lt_intern-col.
CONCATENATE 'IT_DATA-' ls_intern-value INTO l_fld_name.
ASSIGN (l_fld_name) TO <fld>.
IF sy-subrc = 0.
DESCRIBE FIELD <fld> TYPE l_type.
CASE l_type.
WHEN 'F' OR 'P'. REPLACE ',' WITH '.' INTO lt_intern-value.
ENDCASE.
<fld> = lt_intern-value.
UNASSIGN <fld>.
ENDIF.
ENDLOOP.
IF sy-subrc = 0. APPEND it_data. ENDIF.
ENDFUNCTION.
Предполагается, что в переменной HEADER_ROW задается строка EXCEL-таблицы, которая содержит имена колонок внутренней таблицы.
PS: По быстрому типа хватает в большинстве случаев.
PS: 30.02.2013 Подправил работу с типами переменных, чтобы при при запятой в поле числа, была замена на точку, если значение ячейки копируется в переменную типа FLOAT.