FoxPress – Enero 2004

 

      Sustituye en Word

http://www.fpress.com/

 

Por Francisco San Pablo

 

Una de las problemáticas más frecuentes que se suelen presentar es la necesidad de mezclar información que se ha guardado en la Base de Datos de tu aplicación con documentos externos realizados en Word u OpenOffice. Este problema se suele plantear cuando los usuario quieren redactar en Word u OpenOffice los documentos y después determinados campos que han sido marcados de una forma específica sean traducidos a la información de la Base de Datos. Este tipo de cosas se suele plantear con los mailings, contratos, etc...

 

   Desde el principio Microsoft ha promocionado lo que se llama el  MailMerge. El MailMerge ha funcionado durante bastante tiempo pero tiene una serie de limitaciones bastante engorrosas como la necesidad de configurar un DSN por ODBC. Este tipo de operaciones las puedes hacer por código pero te complican bastante la vida.

 

   Un código que hace precisamente eso y sacado de la documentación de Microsoft sería el siguiente:

 

             DECLARE Integer SQLConfigDataSource in odbccp32.dll Integer, ;
         Integer, String, String
 
      ***
      * Create a string containing the settings appropriate to the driver.
      * The following is an example for the Microsoft VFP ODBC driver
      * accessing the Customer.dbf file.
      ***
 
      *** Change the path below to point to the Customer table ***
      *** in the \Samples\Data folder.                      ***
      settings="DSN=visual foxpro tables"+chr(0)+;
                "Description=VFP ODBC Driver"+chr(0)+;
                "SourceDB=d:\vfp5a\samples\data"+chr(0)+;
                "SourceType=DBF"
      =SQLConfigDataSource(0,1,"Microsoft Visual FoxPro Driver",settings)
 
      * NOTE: Ensure there are no spaces on either side of the equal sign (=).
 
      ON ERROR DO errhand WITH ERROR(), MESSAGE(),  MESSAGE(1), PROGRAM( ),
      LINENO( ) && Trap OLE & other errors.
 
      * Initialize variables passed to Word to create form letter.
      intro1="Congratulations! You are one of our best customers since you
      purchase $"
      intro2=" each month from us. "
      intro3="As a result, your maximum order amount has been increased by
      $2500.00. If you have any questions, please feel free to contact us."
 
      oWord = CREATEOBJECT("Word.Application")
         WITH oWord
            * Assign values to variables
            dsname="D:\VFP\SAMPLES\DATA\customer.DBF"
            wformat=0
            wconfirmconv=0
            wreadonly=0
            wlinktosource=0
            waddtofilelist=0
            wpassworddoc=""
            wpasswordtemp=""
            wrevert=0
            wprotectdoc=""
            wprotecttemp=""
            wconn="DSN=visual foxpro tables;uid=;pwd=;"+;
               "sourcedb=d:\vfp\samples\data;sourcetype=dbf"+;
               "exclusive=no;backgroundfetch=yes;collate=machine;"
            wsqlstatement="SELECT contact,company,title,address,city,;
               postalcode,STR(maxordamt,12,2) as maxordamt FROM customer ;
               WHERE (customer.maxordamt>$100000)"
 
            .Visible=.T.      && Make Word visible.
            .WindowState = 2   && Minimize Word.
 
            .Documents.Add      && Add new document.
            .Selection.InsertParagraphAfter
 
            .ActiveDocument.MailMerge.OpenDataSource;
               (dsname,wformat,wconfirmconv,wreadonly,wlinktosource,;
                waddtofilelist,wpassworddoc,wpasswordtemp,wrevert,;
                wprotectdoc,wprotecttemp,wconn,wsqlstatement)
            .ActiveDocument.MailMerge.EditMainDocument
            .Selection.InsertDateTime("dddd, MMMM dd, yyyy", 1)
            .Selection.MoveRight
            .Selection.InsertParagraphAfter
            .Selection.MoveDown
            .ActiveDocument.MailMerge.Fields.Add;
               (oWord.Selection.Range,"contact")

            .Selection.InsertParagraphAfter

           .Selection.MoveDown

            .ActiveDocument.MailMerge.Fields.Add;

               (oWord.Selection.Range,"company")

            .Selection.InsertParagraphAfter

            .Selection.MoveDown

            .ActiveDocument.MailMerge.Fields.Add;

                (oWord.Selection.Range,"title")

            .Selection.InsertParagraphAfter

            

           

 

   (Nota: el código está incompleto. Este código se ha tomado del documento KB181926)

 

   Una alternativa, que es la que propongo aquí, es usar la propia tecnología OLE que nos facilita Word para buscar y reemplazar las cadenas.  Es parecido a la opción de combinar correspondencia de Word, pero sin las limitaciones del mismo (Tener que crear un origen de datos, vincularlo al documento maestro etc.).

 

    Usando la rutina que te mando, puedes tener una plantilla y usar fox para crear un documento nuevo con los valores apropiados.

 

  IMPORTANTE: Este código sólo funcionará con Fox 8.

 

*- En la siguiente línea deberás poner el path y en nombre del documento sobre el que    

*- vas a trabajar.

 

#DEFINE _DOCUMENTO    "<Path del documento> + “NOVED1203.doc"

 

LOCAL loWord, loDocument

 

*- Crea referencia a Word

TRY

  loWord = GETOBJECT(,'Word.Application')

CATCH

  loWord = CREATEOBJECT('Word.Application')

ENDTRY

 

IF VARTYPE(loWord) <> 'O'

  ERROR 'No se ha podido crear una referencia a WORD'

  RETURN .F.

ENDIF

 

*---------------------------------

* Abre el documento como ReadOnly

*---------------------------------

TRY

  loDocument = loWord.Documents.Open(_DOCUMENTO,,.T.)

 

CATCH

  *- Cierra instancia de Word

  IF VARTYPE(loWord) = 'O'

         loWord.Application.Quit(0) && Sale sin salvar y sin preguntar

         loWord = .NULL.

  ENDIF

 

  ERROR 'No se ha podido abrir el documento "' + _DOCUMENTO + '".'

ENDTRY

 

IF lfBuscaReplaCadena(loWord.Selection, "¡¡MUY IMPORTANTE!!", "¡¡Importantísimo!!")

  MESSAGEBOX('Cambio realizado', 64, 'Atención')

ELSE

  MESSAGEBOX('Cambio NO realizado', 16, 'Atención')

ENDIF

 

loWord.Visible = .t.

 

RETURN

 

 

FUNCTION lfBuscaReplaCadena

LPARAMETERS poSelection, pcValueToFind, pcValueToReplace

 

*--------------------------------------------------------

*- Busca una cadena y la reemplaza por otra

*-

*- Parametros:

*-       poSelection          Referencia a la selección a buscar.  Ej. oWord.Selection

*-       pcValueToFind        Valor a buscar

*-       pcValueToReplace     Valor a reemplazar

*-

*- Devuelve:

*-             .t.           Si ha podido reemplazar todo

*-             .f.           Si NO ha podido reemplazar

*-

*--------------------------------------------------------

 

LOCAL llReturn

 

llReturn = .t.

 

TRY

 

  WITH poSelection.Find

         .ClearFormatting

         .Replacement.ClearFormatting

         .Text = pcValueToFind

         .Replacement.Text = pcValueToReplace

         .Forward = .T.

         .Wrap= 1

         .Execute(,,,,,,,,,,2)

  ENDWITH

 

CATCH TO nError

 

  llReturn = .f.

  THIS.cDescUltError = 'Ha ocurrido un error en el proceso de reemplazo de texto'

 

ENDTRY

 

RETURN (llReturn)

 
 

   Como ves, la esencia del código en realidad, es realizar tu mismo las operaciones de búsqueda y reemplazo. En este caso, estamos buscando la palabra "¡¡MUY IMPORTANTE!!" y sustituyéndola por "¡¡Importantísimo!!".

 

   Ya ves que el código es simple y lo puedes incorporar fácilmente en tus aplicaciones.

 

 

 

FoxPress – Enero de 2004

© 2004 FoxPress. All rights reserved