Ir al contenido
Programación ABAP

Entrada y salida de datos

Entrada y salida de datos: memoria de usuario, memoria ABAP, clusters y ficheros.

Manual ABAP
7 de 14
Siguiente
Batch input

Antes y ahora

Este capítulo se escribió para SAP R/3 y ABAP clásico. Aquí tienes qué ha cambiado; en cada apartado verás la comparación con código y, plegado, el texto original.

ConceptoEn el manualHoyEstado
Comunicación con otros sistemasCPI-C, RFC y OLE2RFC, servicios OData y APIs RESTSe escribe distinto
Clusters: nombres de los datosEXPORT lt_datos TO …EXPORT datos = lt_datos TO … (forma con nombre)Se escribe distinto
Ficheros del PCUPLOAD, WS_UPLOAD, WS_DOWNLOADCL_GUI_FRONTEND_SERVICES o GUI_UPLOAD / GUI_DOWNLOADSustituido
Ficheros del servidorOPEN DATASET … IN TEXT MODELo mismo, con ENCODING UTF-8 obligatorio y la ruta validadaSe escribe distinto
Compartir datos entre usuariosTablas de base de datos o clustersTambién shared objects (SHMA)Se escribe distinto
En ABAP Cloud—Sin ficheros ni SAP GUI: los datos entran y salen por serviciosSe escribe distinto

Sigue igual: SET PARAMETER y GET PARAMETER, EXPORT / IMPORT a la memoria ABAP, TRANSFER, READ DATASET y CLOSE DATASET.

7.1. E/s elemental

Se escribe distinto

Así se hace hoy

La entrada y la salida básicas siguen siendo la pantalla de selección, el SQL y los listados (hoy, ALV). Para hablar con otros sistemas, CPI-C y OLE2 han quedado atrás: se usan RFC entre sistemas SAP y servicios OData o APIs REST con el resto.

  • Entrada (Input) básica de un programa Abap 4: Se realiza a través de la pantalla de selección (mediante las sentencias PARAMETERS y SELECT-OPTIONS), lectura de información de la base de datos (sentencia GET y las Open SQL), y pantalla (mediante formularios, ...).
  • Salida (Output) elemental: Se realiza mediante escrituras en la base de datos (sentencias Open SQL), pantalla e impresora (sentencias WRITE, SKIP, ULINE, ...).
  • E/S compleja: se consigue mediante comunicaciones CPI-C, RFC y OLE2.

7.2. E/s mediante memoria de usuario

Sigue igual

Así se hace hoy

SET PARAMETER y GET PARAMETER funcionan igual y se siguen usando para rellenar el campo inicial de una transacción antes de llamarla. Los valores que tiene un usuario se mantienen en la SU3 y se guardan en la tabla USR05.

  • GET PARAMETER ID parámetro FIELD campo.
    Se usa GET PARAMETER para leer parámetros de la memoria de usuario. Se indica el parámetro a leer y el campo o variable que va a recoger el valor. Transfiere el valor del parámetro desde memoria SAP a ‘campo’.
  • SET PARAMETER ID parámetro FIELD campo.
    Los parámetros (sus identificadores tienen hasta 20 caracteres) de la memoria de usuario se escriben con SET PARAMETER. Para averiguar cuál es el parámetro predefinido para un campo dado, basta navegar hasta la tabla correspondiente y navegar luego a su elemento de datos En esa pantalla aparece el ID del mismo. En ‘campo’ se pone el valor a escribir en éste, que pasa a la memoria SAP.Estos parámetros se conservan mientras el usuario esté conectado a SAP. Se pueden inicializar usando los perfiles de usuario.
Sesión de usuario (conexión al sistema)Memoria SAPSET / GET PARAMETER ID · compartida por todos los modosModo 1 (ventana)Memoria ABAPEXPORT / IMPORT MEMORY IDProg. AProg. BModo 2 (ventana)Memoria ABAPseparada del modo 1SUBMIT … AND RETURN yCALL TRANSACTION compartenla memoria ABAP del modoShared memorytodos los usuarios del servidorBase de datosEXPORT … TO DATABASE (INDX)FicherosOPEN DATASET (servidor)
Dónde se pueden guardar datos temporales. La memoria SAP la comparten todos los modos de la sesión; la memoria ABAP solo los programas del mismo modo.

7.3. E/s mediante clusters

Sigue igual

Así se hace hoy

Los clusters siguen existiendo en sus dos formas: en memoria y en tablas de base de datos de tipo INDX.

Hay 2 tipos de clusters: Clusters en memoria (de programa) o ‘data clusters’, y clusters en fichero de base de datos.

7.3.1. Data Clusters

Sigue igual

Así se hace hoy

EXPORT … TO MEMORY ID e IMPORT … FROM MEMORY ID siguen funcionando, pero conviene usar la forma con nombre (datos = lt_datos), que no depende de cómo se llamen las variables en cada programa.

Pasar datos «por detrás» a través de la memoria hace difícil seguir el programa. Si controlas los dos lados, mejor un parámetro de método o de función. En ABAP Cloud la memoria ABAP no está disponible.

Un Data Cluster es un conjunto de datos agrupados por la misma clave. Puede contener variables, field-strings y/o tablas internas. Los datos guardados en memoria sólo pueden usarse durante la ‘vida’ del programa que realiza la sentencia EXPORT (exporta clusters), pero no se pierden al usar CALL TRANSACTION o SUBMIT. Sentencias relacionadas con los data clusters:

  • IMPORT campo1a [ TO campo1b ] campo2a [ TO campo2b ] ... FROM MEMORY ID clv.
    Sentencia de entrada. Se usa IMPORT para importar clusters de programa, con un campoNa para cada elemento a importar (variable, field string o tabla interna); se pueden usar otros tantos campos para guardar los valores leídos (TO campoNb). La clave que identifica al cluster es ‘clv’.
  • EXPORT campo1a [ FROM campo1b ] campo2a [ FROM campo2b ] ... TO MEMORY ID clv.
    Sentencia de salida. EXPORT se usa para exportar clusters, usando un campoNa por cada elemento a exportar. Con FROM se indica que se exporta un elemento con el contenido de otro elemento (el campoNb especificado en FROM) . La clave del cluster es ‘clv’.
  • FREE MEMORY [ ID clave ].
    Borra de memoria el cluster de clave especificada. Si no se indica una clave se borran todos los clusters asociados al programa.

7.3.2. Ficheros Cluster

Se escribe distinto

Así se hace hoy

Antes
EXPORT it_datos TO DATABASE indx(zz) ID 'CLAVE1'.

IMPORT it_datos FROM DATABASE indx(zz) ID 'CLAVE1'.
Ahora
EXPORT datos = lt_datos
  TO DATABASE indx(zz) ID lv_clave.

IMPORT datos = lt_datos
  FROM DATABASE indx(zz) ID lv_clave.

Para datos que deben consultarse o modificarse con SQL, una tabla propia es mejor que un cluster: el contenido de un cluster no se puede leer con SELECT.

Texto original del manual: sintaxis clásica

Los ficheros cluster de base de datos son ficheros especiales del Diccionario de Datos. Sentencias:

  • IMPORT campo1a [ TO campo1b ] … FROM DATABASE tabla_BD (área)[ CLIENT mandante ] ID clv | MAJOR-ID c1 MINOR-ID c2.
    Sentencia de entrada. Sirve para importar clusters de un fichero BD (especificado en ‘tabla_BD’, con el ‘área’ dada), con un campoNa para cada elemento a importar (variable, field string o tabla interna). Se puede especificar mandante con la opción CLIENT. Para indicar la clave del cluster se puede usar toda ella, con ID clv, o bien sólo parte de ella usando MAJOR-ID y MINOR-ID.
  • EXPORT campo1a [ FROM campo1b ] … TO DATABASE tabla_BD (área)[ CLIENT mandante] ID clv.
    Sentencia de salida. Se usa para exportar clusters a un fichero BD, usando un campoNa por cada elemento a exportar. Con FROM se indica que se exporta un elemento con el contenido de otro elemento (el campo1b especificado en FROM). Con CLIENT se especifica el mandante. La clave del cluster es ‘clv’.
  • IMPORT DIRECTORY INTO tabla FROM DATABASE tabla_BD (área)[ CLIENT mandante] ID clv.
    Se usa para crear una tabla (el ‘directorio’ del cluster) con el contenido de un cluster de un fichero de BD. El resto de las opciones son análogas a las sentencias IMPORT y EXPORT.
  • DELETE FROM DATABASE tabla (área)[ CLIENT mandante] ID clv.
    Borra un cluster de un fichero cluster. El resto de las opciones son análogas.

7.4. E/s mediante ficheros externos

Sustituido

Así se hace hoy

Las funciones WS_*, UPLOAD y DOWNLOAD son obsoletas. Para el PC del usuario se usan GUI_UPLOAD / GUI_DOWNLOAD o los métodos de CL_GUI_FRONTEND_SERVICES:

Antes
CALL FUNCTION 'WS_DOWNLOAD'
  EXPORTING
    filename = 'C:\pedidos.txt'
    filetype = 'ASC'
  TABLES
    data_tab = lt_lineas.
Ahora
cl_gui_frontend_services=>gui_download(
  EXPORTING
    filename = 'C:\pedidos.txt'
    filetype = 'ASC'
    codepage = '4110'          " UTF-8
  CHANGING
    data_tab = lt_lineas
  EXCEPTIONS
    OTHERS   = 1 ).
Texto original del manual: sintaxis clásica

Las funciones WS_DOWNLOAD, WS_UPLOAD, DOWNLOAD, UPLOAD y WS_QUERY están obsoletas desde hace años. Usa GUI_DOWNLOAD y GUI_UPLOAD, o los métodos de la clase CL_GUI_FRONTEND_SERVICES (por ejemplo FILE_EXIST para saber si existe un fichero). En segundo plano no hay PC al que bajar ficheros: usa ficheros del servidor (OPEN DATASET).

Los ficheros externos pueden residir en el servidor de aplicación, o bien en el servidor de presentación (el de usuario). En este caso se usan las funciones: WS_DOWNLOAD (Baja una tabla interna a fichero. Llama a DOWNLOAD), WS_UPLOAD (Carga un fichero en una tabla interna. Llama a UPLOAD), WS_QUERY (consulta información acerca de un fichero, como saber si existe o no).

7.4.1. Ficheros del servidor de aplicación (UNIX)

Se escribe distinto

Así se hace hoy

Las sentencias son las mismas, pero desde Unicode hay que indicar la codificación, y conviene comprobar que el fichero se ha abierto y que la ruta está permitida:

Antes
OPEN DATASET p_fich FOR OUTPUT IN TEXT MODE.
LOOP AT it_lineas.
  TRANSFER it_lineas TO p_fich.
ENDLOOP.
CLOSE DATASET p_fich.
Ahora
OPEN DATASET lv_fichero FOR OUTPUT
  IN TEXT MODE ENCODING UTF-8.
IF sy-subrc <> 0.
  MESSAGE |No se puede abrir { lv_fichero }| TYPE 'E'.
ENDIF.
LOOP AT lt_lineas INTO DATA(lv_linea).
  TRANSFER lv_linea TO lv_fichero.
ENDLOOP.
CLOSE DATASET lv_fichero.
  • No escribas las rutas en el programa: usa nombres de fichero lógicos (transacción FILE) y FILE_GET_NAME.
  • Valida las rutas que vengan del usuario con FILE_VALIDATE_NAME para no dar acceso a carpetas del servidor no permitidas.
  • En un job no hay PC del usuario: los ficheros en fondo siempre son del servidor.
Texto original del manual: sintaxis clásica

Desde los sistemas Unicode, en modo texto es obligatorio indicar la codificación: OPEN DATASET fichero FOR INPUT IN TEXT MODE ENCODING DEFAULT.

  • OPEN DATASET dns [ MESSAGE msg ] [ FOR INPUT | FOR OUTPUT | FOR APPENDING ] [ IN BINARY MODE | IN TEXT MODE ENCODING DEFAULT ] [ AT POSITION pos ].
    Abre
    un fichero secuencial sobre el servidor de aplicación.
  • CLOSE DATASET dns.
    Cierra
    un fichero secuencial sobre el servidor de aplicación.
  • DELETE DATASET dns.
    Borra
    un fichero secuencial sobre el servidor de aplicación.
  • TRANSFER registro TO dns [ LENGTH longitud ].
    Escribe
    o transfiere datos a un fichero secuencial del servidor de aplicación.
  • READ DATASET dns INTO registro [ LENGTH longitud ].
    Lee
    datos de un fichero secuencial del servidor de aplicación.

7.4.2. Ficheros del servidor de presentación (usuario windows)

Sustituido

Así se hace hoy

Antes
CALL FUNCTION 'UPLOAD'
  EXPORTING
    filename = 'C:\datos.txt'
    filetype = 'ASC'
  TABLES
    data_tab = it_lineas.
Ahora
DATA: lt_ficheros TYPE filetable,
      lv_rc       TYPE i.

cl_gui_frontend_services=>file_open_dialog(
  CHANGING file_table = lt_ficheros
           rc         = lv_rc ).
CHECK lv_rc = 1.

cl_gui_frontend_services=>gui_upload(
  EXPORTING filename = CONV string( lt_ficheros[ 1 ]-filename )
            filetype = 'ASC'
  CHANGING  data_tab = lt_lineas
  EXCEPTIONS OTHERS  = 1 ).

Fichas con todos los parámetros: GUI_UPLOAD y GUI_DOWNLOAD.

Texto original del manual: sintaxis clásica
  • UPLOAD (obsoleto)

    ABAP
    CALL FUNCTION 'UPLOAD'
    * EXPORTING                            "internamente llama a ws_upload
    *   CODEPAGE                = ' '      "valor
    *   FILENAME                = ' '      "nombre del fichero por defecto
    *   FILETYPE                = ' '      "bin | asc | dat | wk1
    *   ITEM                    = ' '      "texto de cabecera
    * IMPORTING
    *   FILESIZE                =          "tamaño en bytes
    *   ACT_FILENAME            =          "nombre fichero
    *   ACT_FILETYPE            =          "tipo de fichero
      TABLES
        data_tab                =          "tabla donde se cargan los datos
    * EXCEPTIONS
    *   CONVERSION_ERROR        = 1        "error de conversión
    *   INVALID_TABLE_WIDTH     = 2        "estructura de la tabla  incorrecta
    *   INVALID_TYPE            = 3        "tipo de fichero inválido
              .
  • Ws_upload (obsoleto)

    ABAP
    CALL FUNCTION 'WS_UPLOAD'
    * EXPORTING                            "Llamada por UPLOAD
    *   CODEPAGE                = ' '      "valor
    *   FILENAME                = ' '      "nombre del fichero por defecto
    *   FILETYPE                = ' '      "bin | asc | dat | wk1
    * IMPORTING
    *   FILELENGTH              =          "tamaño en bytes
      TABLES
        data_tab                =          "tabla donde se cargan los datos
    * EXCEPTIONS
    *   CONVERSION_ERROR        = 1        "error de conversión
    *   FILE_OPEN_ERROR         = 2        "error de apertura del fichero
    *   FILE_READ_ERROR         = 3        "error de lectura
    *   INVALID_TABLE_WIDTH     = 4        "estructura de la tabla  incorrecta
    *   INVALID_TYPE            = 5        "tipo de fichero inválido
              .
  • DOWNLOAD (obsoleto)

    ABAP
    CALL FUNCTION 'DOWNLOAD'           "Internamente llama a WS_DOWNLOAD
    * EXPORTING
    *   BIN_FILESIZE          = ' '    "longitud del fichero en binario
    *   CODEPAGE              = ' '    "valor
    *   FILENAME              = ' '    "nombre del fichero por defecto
    *   FILETYPE              = ' '    "BIN | ASC | DAT | WK1
    *   ITEM                  = ' '    "texto de cabecera
    *   MODE                  = ' '    " ' ' | A
    * IMPORTING
    *   ACT_FILENAME          =        "nombre del fichero
    *   ACT_FILETYPE          =        "tipo de fichero
    *   FILESIZE              =        "tamaño en bytes
      TABLES
        data_tab              =        "tabla a bajar a fichero
    * EXCEPTIONS
    *   INVALID_FILESIZE      = 1      "tamaño de fichero inválido
    *   INVALID_TABLE_WIDTH   = 2      "estructura de la tabla incorrecta
    *   INVALID_TYPE          = 3      "tipo de fichero inválido
              .
  • Ws_download (obsoleto)

    ABAP
    CALL FUNCTION 'WS_DOWNLOAD'        " Llamada por DOWNLOAD
    * EXPORTING
    *   BIN_FILESIZE          = ' '    "longitud del fichero en binario
    *   CODEPAGE              = ' '    "valor
    *   FILENAME              = ' '    "nombre del fichero por defecto
    *   FILETYPE              = ' '    "BIN | ASC | DAT | WK1
    *   MODE                  = ' '    " ' ' | A
    * IMPORTING
    *   FILELENGTH            =        "tamaño en bytes
      TABLES
        data_tab              =        "tabla a bajar a fichero
    * EXCEPTIONS
    *   FILE_OPEN_ERROR       = 1      "error de apertura del fichero
    *   FILE_WRITE_ERROR      = 2      "error de escritura
    *   INVALID_FILESIZE      = 3      "tamaño del fichero inválido
    *   INVALID_TYPE          = 4      "tipo de fichero inválido
    *   INVALID_TABLE_WIDTH   = 5      "estructura de la tabla incorrecta
              .
  • WS_QUERY. Función útil para saber si existe un fichero, si está vacío, sus atributos,...

Para seguir

  • Leer un fichero del servidor paso a paso: truco del fichero UNIX.
  • Excel sin OLE: exportación del ALV o la librería abap2xlsx.
  • En ABAP Cloud, los datos se intercambian con servicios: RAP y BTP.