jueves, 28 de julio de 2011

Descargar cualquier tabla a un directorio del servidor de aplicaciones

Con esta función podremos descargar cualquier tabla, sea cual sea su estructura, a un fichero de texto en un directorio del servidor de aplicaciones. Podemos consultar los directorios mediante la transacción AL11.
Cómo parámetros le pasaremos el nombre del directorio, el nombre del fichero y la tabla de datos. Opcionalmente le podemos decir que sobreescriba el fichero en caso de que exista y el separador a utilizar entre los campos de una fila de datos.

FUNCTION z_crearfichero.
*"----------------------------------------------------------------------
*"*"Interfase local
*" IMPORTING
*" REFERENCE(I_DIRECTORY) TYPE DXFILE-FILENAME
*" REFERENCE(I_FILENAME) TYPE DXFILE-FILENAME
*" REFERENCE(I_OVERWRITE) TYPE CHAR1 OPTIONAL
*" REFERENCE(I_SEPARATOR) TYPE CHAR1 DEFAULT ';'
*" REFERENCE(IT_DATA) TYPE TABLE
*" EXCEPTIONS
*" EX_ERRORDIRECTORY
*" EX_FILEEXISTS
*"----------------------------------------------------------------------

* Verificamos la existencia del directorio de destino
DATA: lt_ocs_file LIKE ocs_file OCCURS 0,
ls_ocs_file LIKE ocs_file,
ld_directory LIKE ocs_file-name,
ld_filename LIKE ocs_file-name.

MOVE i_directory TO ld_directory.
MOVE i_filename TO ld_filename.

CALL FUNCTION 'OCS_GET_FILE_INFO'
EXPORTING
dir_name = ld_directory
file_name = '*'
TABLES
dir_list = lt_ocs_file
EXCEPTIONS
no_authority = 1
activity_unknown = 2
not_a_directory = 3
no_media_in_drive = 4
too_many_errors = 5
too_many_files = 6
bracket_error_in_filename = 7
no_such_parameter = 8.

* No podemos acceder al directorio o no existe
IF sy-subrc NE 0.
RAISE ex_errordirectory.
ENDIF.

* Comprobamos si existe.
READ TABLE lt_ocs_file INTO ls_ocs_file WITH KEY name = ld_filename.
IF sy-subrc EQ 0.
IF i_overwrite IS INITIAL.
* Si no podemos sobrescribirlo lanzamos una excepción
RAISE ex_fileexists.
ELSE.
* Si se puede sobreescribir damos una advertencia de ello
MESSAGE s007(zhrx_contratos_bold) WITH ld_filename.
* El fichero & se sobrescribe
ENDIF.
ENDIF.

* Bajamos la tabla al directorio de destino
DATA: ld_filepath TYPE dxfile-filename,
ld_length TYPE i,
ld_outdata TYPE string,
ld_data TYPE string.

FIELD-SYMBOLS: TYPE ANY.
FIELD-SYMBOLS: TYPE ANY.

* Construimos el nombre completo del fichero
CONCATENATE ld_directory ld_filename INTO ld_filepath SEPARATED BY '/'.

* Abrimos el fichero para escitura
OPEN DATASET ld_filepath FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
IF sy-subrc NE 0.
RAISE ex_errordirectory.
ENDIF.

* Para poder grabar cualquier tipo de tabla utilizamos field-symbols. En primer lugar leemos cada línea
* de la tabla asignandola al field symbols . En segundo lugar accedemos a cada uno de los campos
* de la fila mediante la instrucción ASSIGN COMPONENT. De esta forma podemos pasar a la función cualquier
* tipo de tabla independientemente de su estructura.
LOOP AT it_data ASSIGNING .
CLEAR: sy-subrc, ld_outdata.
* Leemos todos los campos de la estructura y los vamos concatenando para formar una línea del fichero
* de texto.
WHILE sy-subrc = 0.
ASSIGN COMPONENT sy-index OF STRUCTURE TO .
IF sy-subrc NE 0.
EXIT.
ENDIF.
CLEAR ld_data.
MOVE TO ld_data.
* El primer campo lo pasamos directamente a la variable de salida, el resto lo concatenamos mediante
* el separador especificado.
IF ld_outdata IS INITIAL.
MOVE ld_data TO ld_outdata.
ELSE.
CONCATENATE ld_outdata ld_data INTO ld_outdata SEPARATED BY i_separator.
ENDIF.
ENDWHILE.

* Añadimos al fichero destino la línea que acabamos de construir.
TRANSFER ld_outdata TO ld_filepath.
ENDLOOP.

* Cerramos el fichero de destino
CLOSE DATASET ld_filepath.

ENDFUNCTION.

No hay comentarios: