Esto es un clásico de la programación ABAP que no puede faltar en todo desarrollo , proyecto , listado , etc... siempre habrá un usuario que te pedirá que el listado 'A', 'B' o 'C' tenga la opción de descargarse a una hoja Excel.
Para descargar una tabla interna a una hoja de excel: bapi MS_EXCEL_OLE_STANDARD_DAT
IMPORTANTE: Para que esta bapi os funcione, es necesario que la aplicación Microsoft EXCEL este instala en el equipo local. Esta bapi envía los datos al SapGUI y después al EXCEL, por tanto tampoco funcionara si ejecutáis el programa como un job en fondo o si queréis que el fichero se cree en el servidor o en una unidad de red.
Si la tabla interna tiene campos numéricos, por ejemplo integer, float... al ejecutar la bapi MS_EXCEL_OLE_STANDARD_DAT saltara un precioso dump. Esto esta relacionado con lo que anteriormente os he comentado, la Bapi no realiza ningún ajuste, transformación o cast con los datos, lo que puede derivar en problemas con campo numérico, decimales o fechas.
Hay que crear otra tabla interna, idéntica a la que queremos descargar a excel, pero con todos sus campos de tipo carácter. Traspasaremos los registros a la nueva tabla y descargaremos el contenido de la tabla a una hoja excel con la bapi MS_EXCEL_OLE_STANDARD_DAT.
Un ejemplo vale mas que mil palabras....
Listado ALV que muestra los vuelos para las compañías y fechas seleccionadas:
Nota: solo voy a pegar las partes importantes del código, si queréis el código completo del ejemplo lo tenéis aquí.
Añadir un pulsador para descargar el ALV a una hoja excel y el siguiente código para controlar el evento.
La tabla interna TL_NAME son las cabeceras de las columnas. Si comentáis el parámetro de entrad de la bapi o le pasáis una tabla interna vacía, generara la hoja excel sin cabecera para las columnas.
IMPORTANTE: Para que esta bapi os funcione, es necesario que la aplicación Microsoft EXCEL este instala en el equipo local. Esta bapi envía los datos al SapGUI y después al EXCEL, por tanto tampoco funcionara si ejecutáis el programa como un job en fondo o si queréis que el fichero se cree en el servidor o en una unidad de red.
Si la tabla interna tiene campos numéricos, por ejemplo integer, float... al ejecutar la bapi MS_EXCEL_OLE_STANDARD_DAT saltara un precioso dump. Esto esta relacionado con lo que anteriormente os he comentado, la Bapi no realiza ningún ajuste, transformación o cast con los datos, lo que puede derivar en problemas con campo numérico, decimales o fechas.
Hay que crear otra tabla interna, idéntica a la que queremos descargar a excel, pero con todos sus campos de tipo carácter. Traspasaremos los registros a la nueva tabla y descargaremos el contenido de la tabla a una hoja excel con la bapi MS_EXCEL_OLE_STANDARD_DAT.
Un ejemplo vale mas que mil palabras....
Listado ALV que muestra los vuelos para las compañías y fechas seleccionadas:
Nota: solo voy a pegar las partes importantes del código, si queréis el código completo del ejemplo lo tenéis aquí.
Añadir un pulsador para descargar el ALV a una hoja excel y el siguiente código para controlar el evento.
*---------------------------------------------------------------------*
* FORM USER_COMMAND_01 Process Call Back Events (Begin) *
*---------------------------------------------------------------------*
FORM user_command_01 USING ucomm LIKE sy-ucomm
selfield TYPE slis_selfield.
DATA: wl_file TYPE string.
CASE ucomm.
WHEN '&EXC'.
PERFORM get_filename CHANGING wl_file.
PERFORM download_to_exc USING wl_file ti_spfli.
ENDCASE.
ENDFORM. "user_command_01
*---------------------------------------------------------------------*
* Form GET_FILENAME
*---------------------------------------------------------------------*
* Abrir navegador para seleccionar fichero
*----------------------------------------------------------------------*
FORM get_filename CHANGING p_file TYPE string.
DATA w_file LIKE rlgrap-filename.
CALL FUNCTION 'KD_GET_FILENAME_ON_F4'
CHANGING
file_name = w_file
EXCEPTIONS
mask_too_long = 1
OTHERS = 2.
p_file = w_file.
ENDFORM. "GET_FILENAME
*---------------------------------------------------------------------*
* Form DOWNLOAD_TO_EXC
*---------------------------------------------------------------------*
FORM download_to_exc USING Pi_file TYPE STRING
ti_spfli TYPE type_t_spfli.
TYPES: BEGIN OF tl_name,
fldname(11) TYPE c,
END OF tl_name.
DATA: tl_name TYPE STANDARD TABLE OF tl_name.
DATA: wl_file TYPE rlgrap-filename.
FIELD-SYMBOLS: <FL> TYPE tl_name.
wl_file = Pi_file.
LOOP AT gt_fieldcat .
APPEND INITIAL LINE TO tl_name ASSIGNING <FL>.
<FL>-fldname = gt_fieldcat-fieldname.
ENDLOOP.
CALL FUNCTION 'MS_EXCEL_OLE_STANDARD_DAT'
EXPORTING
file_name = wl_file
data_sheet_name = 'SPFLI'
password_option = 0
TABLES
data_tab = ti_spfli
fieldnames = tl_name
EXCEPTIONS
file_not_exist = 1
filename_expected = 2
communication_error = 3
ole_object_method_error = 4
ole_object_property_error = 5
invalid_filename = 6
invalid_pivot_fields = 7
download_problem = 8
OTHERS = 9.
CASE sy-subrc.
WHEN 1.
MESSAGE e000(yv01) WITH 'File does not exist'.
WHEN 2.
MESSAGE e000(yv01) WITH 'Filename expected'.
WHEN 3.
MESSAGE e000(yv01) WITH 'Communication error'.
WHEN 4.
MESSAGE e000(yv01) WITH 'OLE object method error'.
WHEN 5.
MESSAGE e000(yv01) WITH 'OLE object property error'.
WHEN 6.
MESSAGE e000(yv01) WITH 'Invalid filename'.
WHEN 7.
MESSAGE e000(yv01) WITH 'Invalid pivot fields'.
WHEN 8.
MESSAGE e000(yv01) WITH 'Download problem'.
WHEN 9.
MESSAGE e000(yv01) WITH 'Other problem'.
ENDCASE.
ENDFORM. " DOWNLOAD_TO_EXC
La tabla interna TL_NAME son las cabeceras de las columnas. Si comentáis el parámetro de entrad de la bapi o le pasáis una tabla interna vacía, generara la hoja excel sin cabecera para las columnas.
![]() |
| Preguntamos donde quiere guardar la hoja excel |
![]() |
| Tabla interna descargada a hoja excel |
En este ejemplo , como todos los campos son de tipo caracter ( CONNID es NUMC, texto numérico ) , no existe ningun problema en pasar directamente la tabla a la bapi MS_EXCEL_OLE_STANDARD_DAT. Pero, si añadimos un nuevo campo numerico a la tabla interna:
TYPES: BEGIN OF type_spfli, carrid TYPE spfli-carrid, "compañía aérea connid TYPE spfli-connid, "Código de conexión de vuelo directo countryf TYPE spfli-countryfr, "Clave de país cityfrom TYPE spfli-cityfrom, "Ciudad de salida airpfrom TYPE spfli-airpfrom, "Aeropuerto de salida countryto TYPE spfli-countryto, "Clave de país cityto TYPE spfli-cityto, "Ciudad de llegada airpto TYPE spfli-airpto, "Aeropuerto de destino integer TYPE i, "CAMPO NUMERICO END OF type_spfli.
![]() |
| sólo se permiten caracteres |
*---------------------------------------------------------------------*
* Form DOWNLOAD_TO_EXC
*---------------------------------------------------------------------*
FORM download_to_exc USING pi_file TYPE string
ti_spfli TYPE type_t_spfli.
TYPES: BEGIN OF tl_name,
fldname(11) TYPE c,
END OF tl_name.
TYPES: BEGIN OF type_excel,
carrid(3) TYPE c,
connid(4) TYPE c,
countryfr(3) TYPE c,
cityfrom(20) TYPE c,
airpfrom(3) TYPE c,
countryto(3) TYPE c,
cityto(20) TYPE c,
airpto(3) TYPE c,
integer(15) TYPE c,
END OF type_excel.
DATA: tl_name TYPE STANDARD TABLE OF tl_name.
DATA: tl_excel TYPE STANDARD TABLE OF type_excel.
DATA: wl_file TYPE rlgrap-filename.
FIELD-SYMBOLS: <FN> TYPE tl_name,
<FO> TYPE TYPE_spfli,
<FD> TYPE type_excel.
wl_file = pi_file.
LOOP AT gt_fieldcat .
APPEND INITIAL LINE TO tl_name ASSIGNING <FN>.
<FN>-fldname = gt_fieldcat-fieldname.
ENDLOOP.
LOOP AT ti_spfli ASSIGNING <FO>.
APPEND INITIAL LINE TO TL_EXCEL ASSIGNING <FD>.
MOVE: <FO>-carrid TO <FD>-CARRID,
<FO>-connid TO <FD>-CONNID,
<FO>-countryfr TO <FD>-countryfr,
<FO>-cityfrom TO <FD>-cityfrom,
<FO>-airpfrom TO <FD-airpfrom,
<FO>-countryto TO <FD>-countryto,
<FO>-cityto TO <FD>-cityto,
<FO>-airpto TO <FD>-airpto.
WRITE <FO>-integer TO <FD>-INTEGER.
ENDLOOP.
CALL FUNCTION 'MS_EXCEL_OLE_STANDARD_DAT'
EXPORTING
file_name = wl_file
data_sheet_name = 'SPFLI'
password_option = 0
TABLES
data_tab = TL_EXCEL
fieldnames = tl_name
EXCEPTIONS
file_not_exist = 1
filename_expected = 2
communication_error = 3
ole_object_method_error = 4
ole_object_property_error = 5
invalid_filename = 6
invalid_pivot_fields = 7
download_problem = 8
OTHERS = 9.
CASE sy-subrc.
WHEN 1.
MESSAGE e000(yv01) WITH 'File does not exist'.
WHEN 2.
MESSAGE e000(yv01) WITH 'Filename expected'.
WHEN 3.
MESSAGE e000(yv01) WITH 'Communication error'.
WHEN 4.
MESSAGE e000(yv01) WITH 'OLE object method error'.
WHEN 5.
MESSAGE e000(yv01) WITH 'OLE object property error'.
WHEN 6.
MESSAGE e000(yv01) WITH 'Invalid filename'.
WHEN 7.
MESSAGE e000(yv01) WITH 'Invalid pivot fields'.
WHEN 8.
MESSAGE e000(yv01) WITH 'Download problem'.
WHEN 9.
MESSAGE e000(yv01) WITH 'Other problem'.
ENDCASE.
ENDFORM. " DOWNLOAD_TO_EXC
Después de ajustar el código, si volvemos a ejecutar y descargar a excel:
![]() |
| Descargar a hoja excel tabla interna con campos numéricos |
721793 - Problems with MS_EXCEL_OLE_STANDARD_DAT
104165 - Problems with MS EXCEL-download from HR-reports



