domingo, 16 de diciembre de 2012

Crear tabla interna dinámicamente

Hace poco me surgió un desarrollo en el que tenía que cargar un fichero. Hasta aquí no hay nada raro, el problema en este caso es que la estructura del fichero a cargar era variable y además dependía de los datos introducidos en una tabla Z que también podía variar en el tiempo. Es decir, hoy podía tener 10 campos, mañana 20 o tener 10 pero que se llamasen diferente, así que no podía guardar los datos mediante estructuras del diccionario ni crear una estructura fija en mi programa Abap.

La única opción que se me ocurrió para solucionar esto fué crear una tabla interna dinámicamente. Para esto encontre que algún método de los ALV orientados a objetos me podía ayudar.

Vamos con la parte interesante ahora. Lo primero que necesito es definir mis variables. Obviamente no todo puede ser estático y en este caso sé la tabla que contiene mis campos y necesito definir una tabla "fieldcat" que contendrá la estructura:

DATA: gs_estructura LIKE zTabla,
      gt_tabla LIKE STANDAR TABLE OF gs_estructura,
      gs_fielcat TYPE lvc_t_fcat,
      gt_fieldcat TYPE lvc_s_fcat.

A continuación leemos la tabla del diccionario que tiene la estructura de nuestra tabla interna a crear.

SELECT * INTO TABLE gt_tabla
  FROM zTabla
  WHERE condiciones.

Y ahora debemos recorrer nuestra tabla y asignar el campo a la estructura del fieldcat.

LOOP AT gt_tabla INTO gs_estructura.
  gs_fieldcat-col_pos = sy-tabix.

  gs_fieldcat-fieldname = gs_estructura-field.
  APPEND gs_fieldcat TO gt_fieldcat.

  CLEAR GS_FIELDCAT.
ENDLOOP.


A continuación llamamos al método que crea la tabla interna a partir del fieldcat.

CALL METHOD cl_alv_table_create=>create_dynamic_table
  EXPORTING
   it_fieldcatalog = gt_fieldcat
  IMPORTING
   ep_table = gt_tabla
  EXCEPTIONS
   generate_subpool_dir_full = 1
  OTHERS = 2.

Y por último utilizamos field symbols (no podría ser de otra forma) para asignar los datos de la tabla y las posiciones.

ASSIGN gt_tabla->* TO <fs_table>.
CREATE DATA ep_line LIKE LINE OF <fs_table>.
ASSIGN ep_line->* TO <fs_line>.
 
Con esto hemos creado una tabla en tiempo de ejecucíón con los datos definidos por una tabla interna.

4 comentarios:

  1. Lo primero muchas gracias por este articulo, lo segundo tengo una dudilla la tabla Ztabla como está definida en el diccionario ????? Es decir por lo que veo por ejemplo hoy defines 20 campos y mañana la cambias y le añades 10 más por lo que tendrá 30 campos ?????

    Muchas gracias y un saludo

    ResponderEliminar
    Respuestas
    1. Lo básico de ZTabla es que tenga el nombre de los campos a crear.
      Por ejemplo, puedes tener un fichero de nombres y apellidos. La estructura básica de ZTabla es un solo campo llamado Field y los datos serían:
      Nº Entrada - Field(char30)
      1 - Nombre
      2 - Apellido

      Si en un momento determinado tu fichero empieza a tener el segundo apellido añadirías una nueva entrada en la tabla:
      3 - Apellido2

      El resto de campos son para hacer la selección de datos, nombre del fichero de carga, fecha, usuario... no se cualquier cosa que puedas necesitar para que la tabla sea útil para una carga o para varias.

      Saludos

      Eliminar
  2. Hola, verificando tu código, en la línea gs_fieldcat-fieldname = gs_estructura-field.
    no me reconoce el -field, ztabla debe tener algo mas en especial.
    Gracias por el aporte.

    ResponderEliminar
    Respuestas
    1. Ztabla es una tabla definida en el diccionario de datos con un sólo campo. Si defines la tabla en el diccionario sólo con un campo y llamado de esa forma no deberías tener problemas

      Eliminar