Librería ABAP
WordWind

IMPORTANTE: La última versión que realicé de esta librería data de 2007. Es posible que en la actualidad necesite alguna adaptación.

Introducción

No dudo que, como en mi caso, la mera mención de la transacción SE71 o cualquier cosa relacionada con formularios o SmartForms provoca envejecimiento prematuro en el programador medio.

Hay que reconocer que la relación de SAP con las impresoras es mala. No sólo la dinámica de creación y edición de formularios es obsoleta, limitada y agobiante, sino que muchas veces el hecho nimio de cambiar de impresora hace que el formulario deje de comportarse como se esperaba, alterando sus márgenes, el zoom, etc…

Solución

Es por ello que he creado esta librería para acabar con los formularios de una vez por todas. No sólo es infinitamente más flexible que ellos, sino que el tiempo de programación se reduce más de 10 veces. Asimismo, los posibles cambios pueden ser llevados a cabo por el usuario simplemente modificando el template.

Empleo

La lógica es la siguiente: Se diseña un documento Word con gráficos, disposiciones, tipos de letra deseados, etc… y, en vez de valores fijos, se colocan las variables que deseemos sustituir. En el caso del ejemplo que adjunto:

Estimado/a Cliente:

Figura Usted en nuestros registros bajo el nombre _NAME1_, con residencia en _ORT01_ desde el _ERDAT_.

Asimismo figura usted de alta en las siguientes empresas del grupo:

_TABLA_

Lo grabaremos en formato .mht, que es HTML de mail, para que así quede almacenado como texto.

Después debemos diseñar un programa que tire de la librería que he creado, WordWind, abra este template y realice las sustituciones necesarias, especificando una carpeta de salida para los ficheros generados, en los que se han sustituido las palabras clave por los valores deseados.

Código de ejemplo

*
REPORT  zwordwindexample.

"el motor que tira de esto
INCLUDE zvcwordwind.

"datos para el ejemplo
TABLES kna1.
DATA it_kna1 TYPE TABLE OF kna1 WITH HEADER LINE.
DATA it_knb1 TYPE TABLE OF knb1 WITH HEADER LINE.

" almacenamiento de los ficheros word
DATA: stringtemplate TYPE string.
DATA: stringword TYPE string.

"cliente, sólo para el ejemplo
SELECTION-SCREEN BEGIN OF BLOCK b01 WITH FRAME.
SELECT-OPTIONS pkunnr FOR kna1-kunnr.
SELECTION-SCREEN END OF BLOCK b01.

"template y carpeta de descarga
SELECTION-SCREEN BEGIN OF BLOCK b02 WITH FRAME.
PARAMETERS:  pfile LIKE rlgrap-filename LOWER CASE,
             pcarpeta(80) LOWER CASE.
SELECTION-SCREEN END OF BLOCK b02.

"selección de fichero
AT SELECTION-SCREEN ON VALUE-REQUEST FOR pfile.
  PERFORM ww_getfilename CHANGING pfile.

"selección de carpeta
AT SELECTION-SCREEN ON VALUE-REQUEST FOR pcarpeta.
  PERFORM ww_getfolder CHANGING pcarpeta.

START-OF-SELECTION.

  PERFORM carga_datos.
  PERFORM carga_template.
  PERFORM genera_salida.

* carga datos de ejemplo de clientes
FORM carga_datos.
  SELECT *
    FROM kna1
    INTO TABLE it_kna1
    WHERE kunnr IN pkunnr.

  SELECT *
    FROM knb1
    INTO TABLE it_knb1
    WHERE kunnr IN pkunnr.

ENDFORM.                    "carga_datos

* carga el template word
FORM carga_template.
  ww_localfile2string pfile stringtemplate.
  ww_stripwordcrlf stringtemplate.
ENDFORM.

* genera la salida del word
FORM genera_salida.
  DATA tabla TYPE string.

  LOOP AT it_kna1.
    "creamos una copia local del template como string
    stringword = stringtemplate.

    "hacemos las sustituciones directas
    ww_rep '_KUNNR_' it_kna1-kunnr stringword.
    ww_rep '_NAME1_' it_kna1-name1 stringword.
    ww_rep '_ORT01_' it_kna1-ort01 stringword.

    "fecha
    DATA lfecha1(10).
    WRITE it_kna1-erdat TO lfecha1.
    ww_rep '_ERDAT_' lfecha1 stringword.

    "generación de tabla, en HTML
    CLEAR tabla.

    "estilos CSS (habrá que añadir =3D en vez de =
    "dentro de los atributos del html: fijarse luego)
    concatenate
    '<style>'
    'td{font-family:verdana;font-size:10pt;padding:2pt}'
    '.cabecelda{color:white;background-color:black;'
    'border:1pt solid #000000;border-collapse:collapse}'
    '.fila{font-size:8pt;border:1pt solid #000000;border-collapse:collapse}'
    '.verdana{font-family:verdana;font-size:10pt}'
    '</style>'
    into tabla.

    "cabecera de tabla
    CONCATENATE tabla
    '<table width=3D"100%" cellspacing=3D0>'
    '<tr><td class=3Dcabecelda>SOCIEDAD</td>' &
    '<td class=3Dcabecelda>DESDE FECHA</td></tr>'
    INTO tabla.

    LOOP AT it_knb1 WHERE kunnr = it_kna1-kunnr.
      DATA lfecha2(10).
      WRITE it_knb1-erdat TO lfecha2.

      "filas de tabla
      CONCATENATE
      tabla
      '<tr><td class=3Dfila>'
      it_knb1-bukrs
      '</td><td class=3Dfila">'
      lfecha2
      '</td></tr>'
      INTO tabla.
    ENDLOOP.

    "fin de tabla
    CONCATENATE tabla '</TABLE>' INTO tabla.

    "sustituimos en el template
    ww_rep '_TABLA_' tabla stringword.

    "limpiamos
    ww_ansi2html stringword.
    ww_setprintview stringword.

    "descargamos
    PERFORM download_fichero USING stringword it_kna1-kunnr.

  ENDLOOP.

ENDFORM.


* descargamos el fichero eligiendo un criterio
" para su nombre, en este ejemplo el código de cliente
FORM download_fichero USING pstring pkunnr.

  DATA lfilename LIKE rlgrap-filename.

  "añadimos \ a la carpeta
  ww_slashfolder pcarpeta.

  CONCATENATE pcarpeta 'CLIENTE_' pkunnr '.doc'
    INTO lfilename.

  "almacenamos en disco
  ww_string2localfile pstring lfilename.

ENDFORM.

Observaciones

El código revela rápidamente que muchos de los procesos necesarios, como sustitución de caracteres, selección y apertura de ficheros, etc… están condensados en forma de macros. Esto ayuda a clarificar y compactar el código.

Nada más ejecutar el programa deberemos seleccionar el fichero template que utilizaremos como base para nuestra generación y la carpeta de salida donde se colocarán los ficheros procesados. A continuación, y esto es parte exclusiva del ejemplo, marcaremos un rango de clientes para sacar sus datos.

La sustitución de los datos simples es directa, con la macro ww_rep. Sin embargo, las tablas las deberemos programar como HTML+CSS. La primera vez cuesta: las siguientes serán mucho más sencillas.

Ampliación de funciones

Otras funciones de Word (en realidad, cualquier editor de textos que trabaje con formato .mht) se pueden deducir mediante ingeniería inversa. Por ejemplo, si queremos que una cabecera de tabla se repita de página en página deberemos meterla bajo el tag THEAD. Funciones como el paginado se las delegaremos exclusivamente al editor de texto como se hace en el caso de cualquier documento normal.

Seguridad y confidencialidad

El asunto de la seguridad es fácilmente gestionable. Podemos utilizar los programas generados con distintas variantes no editables según la función y el usuario que las deba ejecutar. Los ficheros template y las carpetas de salida pueden limitarse mediante permisos del SO para que sólo sean accesibles para los usuarios en cuestión.

La librería

La librería, este programa de ejemplo y se pueden descargar desde aquí.

WordWind + ejemplo

Publico esta librería bajo licencia GPL sin limitaciones a la hora de alterar o ampliar el código, respetando siempre su autoría o autorías y conservando la licencia GPL. Su venta está prohibida.

A disfrutar.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

*

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

[c] Alberto Viñuela Miranda / Cranfcom 2013-2014

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.