1
Programación ABAP / Re:generar txt con campos separados por '|'
« en: 14 de Enero de 2013, 11:12:50 am »
Hola, ya he conseguido solucionarlo. Aquí dejo el código por si a alguien le hace falta.
*Declaramos el Type pool para la tabla de salida
TYPE-POOLS: truxs.
TABLES: dd02l.
*----------------------------------------------------------------------*
* TABLAS INTERNAS *
*----------------------------------------------------------------------*
DATA: gt_excel TYPE TABLE OF alsmex_tabline WITH HEADER LINE,
wa_excel TYPE alsmex_tabline.
DATA: BEGIN OF iout OCCURS 0,
rec(1000) TYPE c,
END OF iout.
DATA:
BEGIN OF gt_campos OCCURS 0,
campos(1000) TYPE c,
END OF gt_campos.
DATA:
BEGIN OF gt_condicion ,
condicion(100) TYPE c,
END OF gt_condicion.
*----------------------------------------------------------------------*
* VARIABLES *
*---------------------------------------------------------------------
DATA: gd_tabla(100) TYPE c.
DATA: fin_linea(100) TYPE c.
DATA: ti_campos LIKE STANDARD TABLE OF gt_campos WITH HEADER LINE.
DATA: ti_final LIKE STANDARD TABLE OF gt_campos.
DATA: wa_cabecera LIKE LINE OF gt_campos.
DATA: wa_campos LIKE LINE OF gt_campos.
DATA: ti_campos2 TYPE truxs_t_text_data.
DATA: i_tab LIKE STANDARD TABLE OF gt_campos WITH HEADER LINE.
DATA: where_tab LIKE STANDARD TABLE OF gt_condicion.
DATA: v_id TYPE i,
v_value(30),
gc_o TYPE c VALUE 'O',
gc_x TYPE c VALUE 'X',
gv_result TYPE c,
gv_existe TYPE c,
gv_error TYPE c.
*Esta tabla la utilizamos para las condiciones del excel.
DATA: where_clause(60) TYPE c.
DATA: generic_table_wa TYPE REF TO data,
generic_line TYPE REF TO data, "esta es la tabla general
o_elem TYPE REF TO cl_abap_elemdescr,
o_stru TYPE REF TO cl_abap_structdescr,
nomcamp(240) TYPE c,
intermitente TYPE c.
FIELD-SYMBOLS:
<table> TYPE ANY TABLE,
<wa> TYPE ANY,
<campo> TYPE ANY,
<comp_wa> TYPE abap_compdescr.
*----------------------------------------------------------------------
* PANTALLA DE SELECCIÓN
*---------------------------------------------------------------------
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (28) tcoment1.
PARAMETERS: p_fich(200) TYPE c MODIF ID a DEFAULT 'C:\' OBLIGATORY.
SELECTION-SCREEN END OF LINE.
*----------------------------------------------------------
INITIALIZATION.
tcoment1 = 'Carga el siguiente fichero:'.
*----------------------------------------------------------
*----------------------------------------------------------------------
* Evento AT SELECTION-SCREEN
*----------------------------------------------------------------------
AT SELECTION-SCREEN.
* Cuando se pulsa el botón de ejecutar realiza validaciones de los
* campos obligatorios
IF sy-ucomm = 'ONLI'.
IF p_fich IS INITIAL.
MESSAGE e001(zc) WITH 'El fichero es un campo'
'obligatorio'.
ENDIF.
ENDIF.
*----------------------------------------------------------------------
* Evento AT SELECTION-SCREEN ON VALUE-REQUEST
*----------------------------------------------------------------------
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_fich.
* Función que se encarga de la carga del excel de entrada.
CALL FUNCTION 'WS_FILENAME_GET'
EXPORTING
def_filename = p_fich
mask = ',*.XLS,*.xls.'
mode = gc_o
title = 'SUBIDA DE FICHERO'
IMPORTING
filename = p_fich
EXCEPTIONS
inv_winsys = 1
no_batch = 2
selection_cancel = 3
selection_error = 4
OTHERS = 5.
* Comprobamos que la carga del excel ha ido correctamente y si es así
* comprobamos que sea de tipo '.xls'
IF sy-subrc = 0.
IF p_fich NS '.XLS' OR
p_fich NS '.xls'.
MESSAGE i001(zc) WITH 'El archivo no es .XLS'.
gv_error = gc_x.
ENDIF.
ENDIF.
*--------------------------------------------------------------
TOP-OF-PAGE.
fin_linea = 0.
LOOP AT ti_campos.
* Buscar la longitud de salida de cada campo de la tabla
CONCATENATE gd_tabla '-' ti_campos INTO nomcamp.
o_elem ?= cl_abap_typedescr=>describe_by_name( nomcamp ).
* Escribir cada campo con la longitud de salida correspondiente
fin_linea = fin_linea + ( o_elem->output_length ) + 1.
ENDLOOP.
data linea(500).
linea = fin_linea + 1.
FORMAT COLOR COL_HEADING.
ULINE at (linea).
WRITE: / sy-vline NO-GAP.
LOOP AT ti_campos.
* Buscar la longitud de salida de cada campo de la tabla
CONCATENATE gd_tabla '-' ti_campos INTO nomcamp.
o_elem ?= cl_abap_typedescr=>describe_by_name( nomcamp ).
* Escribir cada campo con la longitud de salida correspondiente
WRITE:
AT (o_elem->output_length) ti_campos QUICKINFO ti_campos NO-GAP,
sy-vline NO-GAP.
ENDLOOP.
data: my_lisel(1000) type c .
clear my_lisel .
WRITE: / sy-vline NO-GAP.
ULINE at (fin_linea).
fin_linea = fin_linea + 1.
FORMAT RESET.
*----------------------------------------------------------------------
* PROCESO PRINCIPAL
*----------------------------------------------------------------------
START-OF-SELECTION.
*VERIFICAMOS QUE SE HAYA SELECCIONADO UN ARCHIVO DE EXCEL
*TAMBIÉN APLICA PARA EL FORMATO DE OFFICE 2007 .XLSX
* Comprueba de que no ha ocurrido ningún error en el evento anterior.
CHECK gv_error IS INITIAL.
*
** Inicializa las tablas y variables generales.
PERFORM inicializar.
IF p_fich IS NOT INITIAL.
PERFORM comprobar_si_existe.
ENDIF.
IF gv_existe = 'S'.
* Descarga el excel a una tabla interna.
PERFORM fichero_a_tabla_interna.
* Se mapea la tabla interna para mas tarde tratar los datos.
PERFORM mapear_tabla.
ELSE.
MESSAGE i001(zc) WITH 'El fichero o directorio no existe'.
ENDIF.
IF gd_tabla IS INITIAL.
MESSAGE e010(ad) WITH 'Error en el archivo, verifique datos'.
ELSE.
*SI TODO HA SALIDO BIEN, YA TENEMOS LOS DATOS EN NUESTRA TABLA INTERNA
* Crear la work area con referencia a la tabla para usar en el select
CREATE DATA generic_table_wa TYPE TABLE OF (gd_tabla).
ASSIGN generic_table_wa->* TO <table>.
CREATE DATA generic_table_wa TYPE (gd_tabla).
ASSIGN generic_table_wa->* TO <wa>.
CLEAR intermitente.
SELECT * INTO CORRESPONDING FIELDS OF TABLE <table>
FROM (gd_tabla) WHERE (where_tab).
* Control del color
IF intermitente = space.
FORMAT COLOR COL_BACKGROUND INTENSIFIED OFF.
intermitente = 'X'.
ELSE.
FORMAT COLOR COL_NORMAL INTENSIFIED ON.
CLEAR intermitente.
ENDIF.
* Mostrar el valor de todos los campos
LOOP AT <table> INTO <wa>.
WRITE: / sy-vline NO-GAP.
LOOP AT ti_campos.
ASSIGN COMPONENT ti_campos-campos OF STRUCTURE <wa> TO <campo>.
IF sy-subrc <> 0.
EXIT.
ENDIF.
WRITE: <campo> NO-GAP, sy-vline NO-GAP.
data: campo(255) type c.
move campo to wa_campos.
append wa_campos to ti_final.
clear campo.
NEW-LINE.
ENDLOOP.
refresh ti_final.
read line 1 field value sy-lisel into my_lisel.
my_lisel = my_lisel(fin_linea).
append my_lisel to ti_final.
data ent type i.
ent = 1.
while my_lisel is not INITIAL.
clear my_lisel.
ent = ent + 1.
read line ent field value sy-lisel into my_lisel.
my_lisel = my_lisel(fin_linea).
append my_lisel to ti_final.
ENDWHILE.
ent = ent + 1.
read line 1 field value sy-lisel into my_lisel.
my_lisel = my_lisel(fin_linea).
append my_lisel to ti_final.
ULINE at (fin_linea).
FORMAT COLOR COL_TOTAL INTENSIFIED OFF.
REFRESH ti_campos.
LOOP AT <table> ASSIGNING <campo>.
ti_campos = <campo>.
APPEND ti_campos.
ENDLOOP.
*Hacemos la bajada del archivo utilizando la tabla
*que obtuvimos en el paso anterior.
CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
filename = 'D:\prueba.txt'
TABLES
data_tab = ti_final[]
EXCEPTIONS
file_write_error = 1
no_batch = 2
gui_refuse_filetransfer = 3
invalid_type = 4
no_authority = 5
unknown_error = 6.
ENDIF.
*---------------------------------------------------------------------
*
* Form INICIALIZAR
**----------------------------------------------------------------------
FORM inicializar .
REFRESH: gt_excel.
CLEAR: gv_result, gv_existe, gt_excel,
gv_error.
ENDFORM. " INICIALIZAR
*---------------------------------------------------------------------
*
* Form COMPROBAR_SI_EXISTE
*---------------------------------------------------------------------
FORM comprobar_si_existe .
DATA lv_ruta_fichero TYPE string.
MOVE p_fich TO lv_ruta_fichero.
* Método para ver si existe el fichero.
gv_result = cl_gui_frontend_services=>file_exist( lv_ruta_fichero ).
* En caso de que exista el fichero.
IF NOT gv_result IS INITIAL.
gv_existe = 'S'.
ENDIF.
ENDFORM. " COMPROBAR_SI_EXISTE
*---------------------------------------------------------------------
*
* Form FICHERO_A_TABLA_INTERNA
**--------------------------------------------------------------------
FORM fichero_a_tabla_interna .
DATA: lv_fichero LIKE rlgrap-filename.
MOVE p_fich TO lv_fichero.
* Función que mete un excel en una tabla interna.
CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'
EXPORTING
filename = lv_fichero
i_begin_col = 1
i_begin_row = 1
i_end_col = 6
i_end_row = 10000
TABLES
intern = gt_excel
EXCEPTIONS
inconsistent_parameters = 1
upload_ole = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE i001(zc) WITH 'Error en el archivo, verifique datos'.
ENDIF.
ENDFORM. " FICHERO_A_TABLA_INTERNA
*---------------------------------------------------------------------
* Form MAPEAR_TABLA
*----------------------------------------------------------------------
FORM mapear_tabla .
* Se recorre la tabla interna para mapearla y crear una tabla interna
* que falicite su lectura y se pueda trabajar mejor con ella.
* ORDENAMOS DATOS EN TABLA FINAL.
LOOP AT gt_excel.
IF gt_excel-row = '0001' AND gt_excel-col = '0003'.
MOVE gt_excel-value TO gd_tabla.
ENDIF.
IF gt_excel-row >= 3 AND gt_excel-col = 3.
APPEND gt_excel-value TO ti_campos.
ENDIF.
IF gt_excel-row >= 1 AND gt_excel-col = 6.
APPEND gt_excel-value TO where_tab.
ENDIF.
ENDLOOP
ENDFORM.
*Declaramos el Type pool para la tabla de salida
TYPE-POOLS: truxs.
TABLES: dd02l.
*----------------------------------------------------------------------*
* TABLAS INTERNAS *
*----------------------------------------------------------------------*
DATA: gt_excel TYPE TABLE OF alsmex_tabline WITH HEADER LINE,
wa_excel TYPE alsmex_tabline.
DATA: BEGIN OF iout OCCURS 0,
rec(1000) TYPE c,
END OF iout.
DATA:
BEGIN OF gt_campos OCCURS 0,
campos(1000) TYPE c,
END OF gt_campos.
DATA:
BEGIN OF gt_condicion ,
condicion(100) TYPE c,
END OF gt_condicion.
*----------------------------------------------------------------------*
* VARIABLES *
*---------------------------------------------------------------------
DATA: gd_tabla(100) TYPE c.
DATA: fin_linea(100) TYPE c.
DATA: ti_campos LIKE STANDARD TABLE OF gt_campos WITH HEADER LINE.
DATA: ti_final LIKE STANDARD TABLE OF gt_campos.
DATA: wa_cabecera LIKE LINE OF gt_campos.
DATA: wa_campos LIKE LINE OF gt_campos.
DATA: ti_campos2 TYPE truxs_t_text_data.
DATA: i_tab LIKE STANDARD TABLE OF gt_campos WITH HEADER LINE.
DATA: where_tab LIKE STANDARD TABLE OF gt_condicion.
DATA: v_id TYPE i,
v_value(30),
gc_o TYPE c VALUE 'O',
gc_x TYPE c VALUE 'X',
gv_result TYPE c,
gv_existe TYPE c,
gv_error TYPE c.
*Esta tabla la utilizamos para las condiciones del excel.
DATA: where_clause(60) TYPE c.
DATA: generic_table_wa TYPE REF TO data,
generic_line TYPE REF TO data, "esta es la tabla general
o_elem TYPE REF TO cl_abap_elemdescr,
o_stru TYPE REF TO cl_abap_structdescr,
nomcamp(240) TYPE c,
intermitente TYPE c.
FIELD-SYMBOLS:
<table> TYPE ANY TABLE,
<wa> TYPE ANY,
<campo> TYPE ANY,
<comp_wa> TYPE abap_compdescr.
*----------------------------------------------------------------------
* PANTALLA DE SELECCIÓN
*---------------------------------------------------------------------
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (28) tcoment1.
PARAMETERS: p_fich(200) TYPE c MODIF ID a DEFAULT 'C:\' OBLIGATORY.
SELECTION-SCREEN END OF LINE.
*----------------------------------------------------------
INITIALIZATION.
tcoment1 = 'Carga el siguiente fichero:'.
*----------------------------------------------------------
*----------------------------------------------------------------------
* Evento AT SELECTION-SCREEN
*----------------------------------------------------------------------
AT SELECTION-SCREEN.
* Cuando se pulsa el botón de ejecutar realiza validaciones de los
* campos obligatorios
IF sy-ucomm = 'ONLI'.
IF p_fich IS INITIAL.
MESSAGE e001(zc) WITH 'El fichero es un campo'
'obligatorio'.
ENDIF.
ENDIF.
*----------------------------------------------------------------------
* Evento AT SELECTION-SCREEN ON VALUE-REQUEST
*----------------------------------------------------------------------
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_fich.
* Función que se encarga de la carga del excel de entrada.
CALL FUNCTION 'WS_FILENAME_GET'
EXPORTING
def_filename = p_fich
mask = ',*.XLS,*.xls.'
mode = gc_o
title = 'SUBIDA DE FICHERO'
IMPORTING
filename = p_fich
EXCEPTIONS
inv_winsys = 1
no_batch = 2
selection_cancel = 3
selection_error = 4
OTHERS = 5.
* Comprobamos que la carga del excel ha ido correctamente y si es así
* comprobamos que sea de tipo '.xls'
IF sy-subrc = 0.
IF p_fich NS '.XLS' OR
p_fich NS '.xls'.
MESSAGE i001(zc) WITH 'El archivo no es .XLS'.
gv_error = gc_x.
ENDIF.
ENDIF.
*--------------------------------------------------------------
TOP-OF-PAGE.
fin_linea = 0.
LOOP AT ti_campos.
* Buscar la longitud de salida de cada campo de la tabla
CONCATENATE gd_tabla '-' ti_campos INTO nomcamp.
o_elem ?= cl_abap_typedescr=>describe_by_name( nomcamp ).
* Escribir cada campo con la longitud de salida correspondiente
fin_linea = fin_linea + ( o_elem->output_length ) + 1.
ENDLOOP.
data linea(500).
linea = fin_linea + 1.
FORMAT COLOR COL_HEADING.
ULINE at (linea).
WRITE: / sy-vline NO-GAP.
LOOP AT ti_campos.
* Buscar la longitud de salida de cada campo de la tabla
CONCATENATE gd_tabla '-' ti_campos INTO nomcamp.
o_elem ?= cl_abap_typedescr=>describe_by_name( nomcamp ).
* Escribir cada campo con la longitud de salida correspondiente
WRITE:
AT (o_elem->output_length) ti_campos QUICKINFO ti_campos NO-GAP,
sy-vline NO-GAP.
ENDLOOP.
data: my_lisel(1000) type c .
clear my_lisel .
WRITE: / sy-vline NO-GAP.
ULINE at (fin_linea).
fin_linea = fin_linea + 1.
FORMAT RESET.
*----------------------------------------------------------------------
* PROCESO PRINCIPAL
*----------------------------------------------------------------------
START-OF-SELECTION.
*VERIFICAMOS QUE SE HAYA SELECCIONADO UN ARCHIVO DE EXCEL
*TAMBIÉN APLICA PARA EL FORMATO DE OFFICE 2007 .XLSX
* Comprueba de que no ha ocurrido ningún error en el evento anterior.
CHECK gv_error IS INITIAL.
*
** Inicializa las tablas y variables generales.
PERFORM inicializar.
IF p_fich IS NOT INITIAL.
PERFORM comprobar_si_existe.
ENDIF.
IF gv_existe = 'S'.
* Descarga el excel a una tabla interna.
PERFORM fichero_a_tabla_interna.
* Se mapea la tabla interna para mas tarde tratar los datos.
PERFORM mapear_tabla.
ELSE.
MESSAGE i001(zc) WITH 'El fichero o directorio no existe'.
ENDIF.
IF gd_tabla IS INITIAL.
MESSAGE e010(ad) WITH 'Error en el archivo, verifique datos'.
ELSE.
*SI TODO HA SALIDO BIEN, YA TENEMOS LOS DATOS EN NUESTRA TABLA INTERNA
* Crear la work area con referencia a la tabla para usar en el select
CREATE DATA generic_table_wa TYPE TABLE OF (gd_tabla).
ASSIGN generic_table_wa->* TO <table>.
CREATE DATA generic_table_wa TYPE (gd_tabla).
ASSIGN generic_table_wa->* TO <wa>.
CLEAR intermitente.
SELECT * INTO CORRESPONDING FIELDS OF TABLE <table>
FROM (gd_tabla) WHERE (where_tab).
* Control del color
IF intermitente = space.
FORMAT COLOR COL_BACKGROUND INTENSIFIED OFF.
intermitente = 'X'.
ELSE.
FORMAT COLOR COL_NORMAL INTENSIFIED ON.
CLEAR intermitente.
ENDIF.
* Mostrar el valor de todos los campos
LOOP AT <table> INTO <wa>.
WRITE: / sy-vline NO-GAP.
LOOP AT ti_campos.
ASSIGN COMPONENT ti_campos-campos OF STRUCTURE <wa> TO <campo>.
IF sy-subrc <> 0.
EXIT.
ENDIF.
WRITE: <campo> NO-GAP, sy-vline NO-GAP.
data: campo(255) type c.
move campo to wa_campos.
append wa_campos to ti_final.
clear campo.
NEW-LINE.
ENDLOOP.
refresh ti_final.
read line 1 field value sy-lisel into my_lisel.
my_lisel = my_lisel(fin_linea).
append my_lisel to ti_final.
data ent type i.
ent = 1.
while my_lisel is not INITIAL.
clear my_lisel.
ent = ent + 1.
read line ent field value sy-lisel into my_lisel.
my_lisel = my_lisel(fin_linea).
append my_lisel to ti_final.
ENDWHILE.
ent = ent + 1.
read line 1 field value sy-lisel into my_lisel.
my_lisel = my_lisel(fin_linea).
append my_lisel to ti_final.
ULINE at (fin_linea).
FORMAT COLOR COL_TOTAL INTENSIFIED OFF.
REFRESH ti_campos.
LOOP AT <table> ASSIGNING <campo>.
ti_campos = <campo>.
APPEND ti_campos.
ENDLOOP.
*Hacemos la bajada del archivo utilizando la tabla
*que obtuvimos en el paso anterior.
CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
filename = 'D:\prueba.txt'
TABLES
data_tab = ti_final[]
EXCEPTIONS
file_write_error = 1
no_batch = 2
gui_refuse_filetransfer = 3
invalid_type = 4
no_authority = 5
unknown_error = 6.
ENDIF.
*---------------------------------------------------------------------
*
* Form INICIALIZAR
**----------------------------------------------------------------------
FORM inicializar .
REFRESH: gt_excel.
CLEAR: gv_result, gv_existe, gt_excel,
gv_error.
ENDFORM. " INICIALIZAR
*---------------------------------------------------------------------
*
* Form COMPROBAR_SI_EXISTE
*---------------------------------------------------------------------
FORM comprobar_si_existe .
DATA lv_ruta_fichero TYPE string.
MOVE p_fich TO lv_ruta_fichero.
* Método para ver si existe el fichero.
gv_result = cl_gui_frontend_services=>file_exist( lv_ruta_fichero ).
* En caso de que exista el fichero.
IF NOT gv_result IS INITIAL.
gv_existe = 'S'.
ENDIF.
ENDFORM. " COMPROBAR_SI_EXISTE
*---------------------------------------------------------------------
*
* Form FICHERO_A_TABLA_INTERNA
**--------------------------------------------------------------------
FORM fichero_a_tabla_interna .
DATA: lv_fichero LIKE rlgrap-filename.
MOVE p_fich TO lv_fichero.
* Función que mete un excel en una tabla interna.
CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'
EXPORTING
filename = lv_fichero
i_begin_col = 1
i_begin_row = 1
i_end_col = 6
i_end_row = 10000
TABLES
intern = gt_excel
EXCEPTIONS
inconsistent_parameters = 1
upload_ole = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE i001(zc) WITH 'Error en el archivo, verifique datos'.
ENDIF.
ENDFORM. " FICHERO_A_TABLA_INTERNA
*---------------------------------------------------------------------
* Form MAPEAR_TABLA
*----------------------------------------------------------------------
FORM mapear_tabla .
* Se recorre la tabla interna para mapearla y crear una tabla interna
* que falicite su lectura y se pueda trabajar mejor con ella.
* ORDENAMOS DATOS EN TABLA FINAL.
LOOP AT gt_excel.
IF gt_excel-row = '0001' AND gt_excel-col = '0003'.
MOVE gt_excel-value TO gd_tabla.
ENDIF.
IF gt_excel-row >= 3 AND gt_excel-col = 3.
APPEND gt_excel-value TO ti_campos.
ENDIF.
IF gt_excel-row >= 1 AND gt_excel-col = 6.
APPEND gt_excel-value TO where_tab.
ENDIF.
ENDLOOP
ENDFORM.