Professional Documents
Culture Documents
Luis Mara Guayn es programador en lenguajes xBase desde el ao 1990. En 1994 comenz a desarrollar en Microsoft FoxPro 2.6 para Windows. Desde all transit por todas las versiones de FoxPro, hasta la actualidad con la ltima versin de Visual FoxPro. Es el Responsable del rea de Desarrollo Informtico de Vicente Trapani S.A., un establecimiento citrcola industrial en la provincia de Tucumn, en la Repblica Argentina. Es cofundador en el ao 2000, y SysOp de PortalFox, el mayor portal gratuito para todos los desarrolladores en Visual FoxPro de habla hispana. En los aos 2002 y 2003 fue nombrado por Microsoft como MVP (Most Valuable Professional) en Visual FoxPro, por su colaboracin en las distintas comunidades en lnea.
Pgina 2
Pgina 3
Introduccin
Visual FoxPro es una poderosa herramienta, pero hay tareas que no las puede realizar l solo. Por ejemplo si tenemos una aplicacin en la cual queremos enviar un correo, realizar un grfico, escribir un documento, formatear un texto, etc., necesitamos de otras herramientas. Para automatizar estas tareas desde Microsoft Visual FoxPro, elegimos la herramienta Microsoft Office. En este documento vamos a ver como podemos Automatizar Office desde Visual FoxPro, vamos a conocer las distintas herramientas que disponemos y veremos algunos ejemplos de cdigo. Todos los ejemplos descriptos fueron realizados con Microsoft Visual FoxPro 8 y Microsoft Office XP.
Cmo comenzar?
Lo primero que debemos preguntarnos es cmo comenzar la tarea de automatizacin? Esta pregunta pareciera que tiene una respuesta difcil, pero veremos... La mayora de la informacin disponible en: la Ayuda de Office, los artculos de la Base de Conocimientos de Microsoft (MSKB) o en la Red de Desarrolladores de Microsoft (MSDN) esta escrita en Visual Basic y Visual Basic for Application. Como una desventaja ms para los desarrolladores en Visual FoxPro de habla hispana, la informacin disponible en Internet esta generalmente en ingls. En espaol, existen varios artculos, ideas y trucos disponibles en los siguientes sitios de la Web: Sitio de MSDN Latinoamrica: http://www.microsoft.com/latam/msdn Sitio de MSDN Espaa: http://www.microsoft.com/spain/msdn Sitio de MSDN en Espaol: http://www.microsoft.com/spanish/msdn PortalFox: http://www.portalfox.com Revista FoxPress: http://www.fpress.com Revista UTMag (edicin en espaol): http://www.universalthread.com/spanish/magazine
En ingls existe un excelente libro para tener en cuenta a la hora de automatizar Office: "Microsoft Office Automation with Visual FoxPro" escrito por Tamar E. Granor y Della Martin, editado en el mes de Junio de 2000. Est disponible para su compra en formato impreso y electrnico en el sitio de Hentzenwerke: http://www.hentzenwerke.com
Pgina 4
loOutlook = CREATEOBJECT('Outlook.Application') Con GETOBJECT() se instancia al servidor de la siguiente forma: loExcel = GETOBJECT( , 'Excel.Application') Si no existe una instancia disponible del servidor, el comando fallar y aparecer el Error OLE 1426. Para evitar este error sin importar si existe o no una instancia del servidor, pasamos como parmetro el nombre del archivo. loExcel = GETOBJECT('C:\MiPlanilla.xls', 'Excel.Application') Por defecto, la instancia del servidor estar oculta. Podemos hacer visible la instancia con la propiedad Visible = .T. Esto lo haremos solo para ver los cambios que producimos, generalmente en la etapa de desarrollo, ya que esto har ms lento el proceso de automatizacin.
Figura 1: El Explorador de Objetos de Visual FoxPro Con el Explorador de Objetos, podemos recorrer las distintas propiedades, eventos y mtodos (PEMs), con la sintaxis correspondiente a cada caso (Figura 2).
Pgina 5
Figura 2: Los mtodos y su sintaxis Con el Examinador de Objetos tambin podemos tener acceso a los valores de las distintas constantes de cada aplicacin (Figura 3).
Pgina 6
Una vez instanciado el objeto desde la "Ventana de Comandos" o declarado desde el "Editor", con solo escribir el nombre del objeto nos aparecern sus propiedades y mtodos (Figura 4) y la sintaxis correspondiente (Figura 5).
Pgina 7
Figura 7: Cdigo VBA generado automticamente Podemos fcilmente traducir el cdigo generado en VBA a Visual FoxPro: ChangeFileOpenDirectory 'D:\Espana\Automation\Documentos\' Documents.Open FileName:='Automation.doc', ConfirmConversions:=False, _ ReadOnly:=False, AddToRecentFiles:=False, PasswordDocument:='', _ PasswordTemplate:='', Revert:=False, WritePasswordDocument:='', _ WritePasswordTemplate:='', Format:=wdOpenFormatAuto El cdigo en Visual FoxPro quedara: loWord.Documents.Open('D:\Espana\Automation\Documentos\Automation.doc', ; .F., .F., .F., '', '', .F., '', '',wdOpenFormatAuto) Los pasos a seguir para esta traduccin son los siguientes: Encerrar con parntesis la lista de parmetros Observar una llamada tipo del mtodo y ordenar los parmetros en el orden que estos aparecen. Quitar los nombres de los parmetros y los smbolos ':=' Reemplazar los nombres de constantes por sus valores, como por ejemplo "True" con .T. 1. Una alternativa (como en el ejemplo) es definir estos valores con: #DEFINE wdOpenFormatAuto 0 #DEFINE true .T.
Pgina 8
#INCLUDE 'Archivo.h' Para la creacin de estos archivos disponemos al menos de dos herramientas: Cdigo en VFP de Trevor Hancock (Base de Conocimientos de Microsoft, Artculo 285396) disponible en: http://support.microsoft.com/?scid=285396 Programa de utilidades de Rick Strahl (GetConstants) disponible libremente en: http://www.west-wind.com/webtools.asp
Pgina 9
El programa MailMerge.prg
Este es el cdigo de nuestro programa "MailMerge.prg", en donde creamos una instancia de la clase cWord y comenzamos a ejecutar sus mtodos. LOCAL lo AS OBJECT, loDoc AS OBJECT lo = NEWOBJECT('cWord','cWord.prg') IF lo.CrearServidor() *-- Vinculo los eventos de Word a mtodos del objeto 'lo' IF NOT EVENTHANDLER(lo.oWord, lo) MESSAGEBOX('No se pudo vincular a los eventos de Word', 16, 'Error!' ) ENDIF *-- Maximizo y hago visible lo.oWord.WINDOWSTATE = 1 && wdWindowStateMaximize lo.oWord.VISIBLE = .T. loDoc = lo.AbrirCarta('Carta') lo.GenerarDataSource('CSV') *lo.GenerarDataSource('ODC') lo.CombinarCarta(loDoc) lo.GuardarCarta(loDoc, .T.) *-- Desvinculo los eventos de Word IF NOT EVENTHANDLER(lo.oWord, lo, .T.) MESSAGEBOX('No se pudo desvincular a los eventos de Word', 16, 'Error!' ) ENDIF ELSE MESSAGEBOX('No se pudo instanciar el servidor', 16, 'Error!') ENDIF lo = .NULL. RETURN
Pgina 10
*-- Creo el objeto THIS.oWord = CREATEOBJECT('Word.Application') WAIT WINDOW 'Nueva instancia de Word...' TIMEOUT 2 CATCH MESSAGEBOX('Microsoft Word no est instalado.', 16, 'Problemas!!!') FINALLY ENDTRY FINALLY ENDTRY RETURN VARTYPE(THIS.oWord) = 'O' Para que este ejemplo sea ms descriptivo, vamos a hacer visible a la aplicacin Word para ver paso a paso como se ejecutan los distintos mtodos. Esto lo hacemos en la sentencia: lo.oword.VISIBLE = .T.
Pgina 11
Combinar la carta
En el mtodo CombinarCarta() ejecutamos las siguientes sentencias para: Hacer la carta del tipo Documento Principal. Abrir el archivo con la fuente de datos. Ejecutar la combinacin WITH toDoc.MailMerge .MainDocumentType = 0 && wdFormLetters .OpenDataSource(THIS.cDataSource) .Execute() ENDWITH
Guardar la carta
Para finalizar tenemos el mtodo GuardarCarta() que guarda el documento principal, con la posibilidad mediante un parmetro de cerrar el documento. PROCEDURE GuardarCarta(toDoc, tlCierra) *-- Guardo el documento toDoc.SAVE() IF tlCierra *-- Cierro el documento toDoc.CLOSE() ENDIF ENDPROC En este ejemplo el documento combinado que se genera quedar abierto, entonces hacemos la aplicacin visible para que el usuario lo guardar directamente de la ventana de Word. Tambin establecemos la carpeta donde estn los documentos de este ejemplo, para que Word por defecto la seleccione en la ventana de "Guardar...". WITH THIS.oWord .ChangeFileOpenDirectory(THIS.cDirDoc) .VISIBLE = .T. ENDWITH
Pgina 12
Antes de comenzar a analizar el ejemplo en Visual FoxPro vamos a comprender algunos conceptos para poder hacer ms fcil la automatizacin de Excel desde Visual FoxPro, esto siempre lo logramos con los archivos de ayuda. Tambin vamos a conocer distintas formas que disponemos para pasar los datos de Visual FoxPro a Excel.
Pgina 13
Una vez que tenemos los datos en el Portapapeles, creamos una instancia de Excel desde Visual FoxPro, creamos un nuevo Libro y pegamos los datos desde el Portapapeles con el mtodo Paste(). loExcel = CREATEOBJECT('Excel.Application') loLibro = loExcel.Workbooks.Add() WITH loLibro .Activate() .ActiveSheet.Paste() .SaveAs('C:\Planilla3.xls') ENDWITH loExcel.Visible = .T. STORE .NULL. TO loLibro, loExcel Otra forma de pasar los datos de Visual FoxPro a Excel, es tener ambas aplicaciones activas y recorrer los datos de nuestra tabla y escribirlos directamente en una Hoja de Excel celda por celda. Esta opcin es mucho ms lenta que las anteriores, pero es til cuando la hoja de Excel ya tiene un formato establecido o cuando queremos escribir frmulas en la hoja de Excel. SELECT 'MiCursor' loExcel = CREATEOBJECT('Excel.Application') loLibro = loExcel.Workbooks.Add() loHoja = loLibro.ActiveSheet() lnFil = 1 && Nombres de campos FOR lnCol = 1 TO FCOUNT() loHoja.Cells(1,lnCol).VALUE = FIELD(lnCol) ENDFOR lnFil = lnFil + 1 && Resto de las filas SCAN ALL FOR lnCol = 1 TO FCOUNT() loHoja.Cells(lnFil,lnCol).VALUE = EVALUATE(FIELD(lnCol)) ENDFOR lnFil = lnFil + 1 ENDSCAN loLibro.SaveAs('C:\Planilla4.xls') loExcel.Visible = .T. STORE .NULL. TO loHoja, loLibro, loExcel
Pgina 14
Generar un grfico
A partir de los resultados de una consulta a las tablas de la base de datos "Northwind", generaremos un grfico del tipo de columnas en 3 dimensiones (xl3DColumnStacked) como lo vemos en la Figura 9, y daremos formato a algunos objetos del grfico, como los ttulos, los ejes y las barras.
Pgina 15
El programa Grafico.prg
En este programa vamos a crear un objeto cExcel y ejecutaremos los mtodos vistos anteriormente para la creacin del grfico. LOCAL lo AS OBJECT, loLibro AS OBJECT lo = NEWOBJECT('cExcel','cExcel.prg') *-- Genero cursor y exporto datos lo.VtaAnualEmpleado(1997, 'VtaAnualEmpleado') lo.ExportarDatos('VtaAnualEmpleado') IF lo.CrearServidor() *-- Maximizo y hago visible lo.oExcel.WINDOWSTATE = -4137 && xlMaximized lo.oExcel.VISIBLE = .T. *-- Abro el libro copiado loLibro = lo.AbrirLibro('VtaAnualEmpleado') *-- Genero grfico lo.GenerarGrafico(loLibro, 'Ventas Anuales por Empleado (AO 1997)') *--- Grabo planilla y cierro lo.GuardarLibro(loLibro, .T.) *-- Cierro el servidor lo.CerrarServidor() ELSE MESSAGEBOX('No se pudo instanciar el servidor', 16, 'Error!') ENDIF lo = .NULL. RETURN El mtodo GenerarGrafico() de la clase cExcel, es el que hace la tarea propiamente dicha. PROCEDURE GenerarGrafico(toLibro, tcTitulo) LOCAL lcRango AS CHARACTER, oGrafico AS 'Excel.Chart', ; loHoja AS 'Excel.WorkSheet' loHoja = toLibro.ActiveSheet lcRango = 'A1:' + CHR(loHoja.UsedRange.COLUMNS.COUNT + 64) + ; ALLTRIM(STR(loHoja.UsedRange.ROWS.COUNT)) loGrafico = THIS.oExcel.Charts.ADD WITH loGrafico
Pgina 16
*-- Tipo, rango y localizacin .ChartType = 55 && xl3DColumnStacked .SetSourceData(loHoja.RANGE(lcRango), 2) .Location(1, 'Ventas Anuales') && xlLocationAsNewSheet = 1 *-- Titulo .HasTitle = .T. .ChartTitle.TEXT = tcTitulo WITH .ChartTitle.FONT .NAME = 'Arial' .SIZE = 14 .Bold = .T. ENDWITH *-- Ejes WITH .Axes(1,1) .HasTitle = .T. .AxisTitle.TEXT = 'Empleado' ENDWITH WITH .Axes(2,1) .HasTitle = .T. .AxisTitle.TEXT = '$' ENDWITH *-- Sin Leyendas .HasLegend = .F. *-- Formato 3D .RightAngleAxes = .T. .AutoScaling = .T. *-- Grupo de grfico WITH .ChartGroups(1) *-- Ancho separacin barras .GapWidth = 50 ENDWITH ENDWITH RETURN ENDPROC
Pgina 17
Con anterioridad a la programacin de los mtodos debemos disear la forma de la tabla dinmica que deseamos generar. El diseo elegido lo observamos en la Figura 10.
Programa TablaDinamica.prg
Este es el cdigo de nuestro programa: LOCAL lo AS OBJECT, loLibro AS OBJECT lo = NEWOBJECT('cExcel','cExcel.prg') *-- Genero cursor y exporto datos lo.VtaAnualPais('VtaAnualPais') lo.ExportarDatos('VtaAnualPais') IF lo.CrearServidor() *-- Maximizo y hago visible lo.oExcel.WINDOWSTATE = -4137 && xlMaximized lo.oExcel.VISIBLE = .T. *-- Abro el libro copiado loLibro = lo.AbrirLibro('VtaAnualPais') *-- Genero tabla dinmica lo.GenerarTablaDinamica(loLibro) *--- Grabo planilla y cierro lo.GuardarLibro(loLibro, .T.) *-- Cierro el servidor lo.CerrarServidor() ELSE MESSAGEBOX('No se pudo instanciar el servidor', 16, 'Error!') ENDIF lo = .NULL. RETURN Para generar la tabla dinmica ejecutamos el mtodo GenerarTablaDinamica() de la clase cExcel. Este mtodo nos genera la tabla dinmica (Figura 11) ordenada descendentemente por las Ventas por Pas. PROCEDURE GenerarTablaDinamica(toLibro) LOCAL laPagina(1), laFilas(2), laColumnas(1), lcRango *--- Arrays con los datos de la tabla dinmica laPagina(1)='Anio' laFilas(1)='Pais' laFilas(2)='Empleado' laColumnas(1)='TipoProd' lcRango = 'A1:E1275' WITH THIS.oExcel *--- Formato de los datos hoja principal .Cells.SELECT .SELECTION.COLUMNS.AUTOFIT .COLUMNS('E:E').SELECT .SELECTION.NumberFormat = '$ #,##0.00' .RANGE('A2').SELECT *--- Llamo al generador de Tablas Dinmicas .ActiveSheet.PivotTableWizard(1, lcRango, '', 'TablaDinamica') *--- Armo la Tabla dinmica WITH .ActiveSheet.PivotTables('TablaDinamica') .AddFields(@laFilas, @laColumnas, @laPagina) WITH .PivotFields('Ventas') .ORIENTATION = 4 && xlDataField .NumberFormat = '$ #,##0.00' ENDWITH .PivotFields('Pais').AutoSort(2,'Suma de ventas') && xlDescending = 2
Pgina 18
ENDWITH *--- Formato de los datos hoja tabla dinmica .Cells.SELECT .SELECTION.COLUMNS.AUTOFIT .ActiveSheet.NAME = 'Ventas Anuales' .RANGE('A2').SELECT ENDWITH RETURN ENDPROC
Pgina 19
Lo primero que debemos hacer para automatizar Outlook, es crear un objeto Outlook, similar a como vimos anteriormente con las otras herramientas de Office. Una vez creado el objeto, debemos acceder al origen de los datos, pero esto no lo logramos en forma directa, debemos crear un objeto "NameSpace" apropiado que actuar como entrada (en este ejemplo MAPI). El objeto NameSpace proporciona entre otros, los mtodos Logon y Logoff.
Versiones de Outlook
Seguramente conocemos varias versiones de Outlook, solo daremos las principales caractersticas de cada uno. Outlook Express: No es Outlook, es un programa completamente diferente y no es servidor de automatizacin. Outlook 97 y 2000: Existen dos versiones, Internet Mail Only (IMO) y Corporate Workgroup (C/W). Ambas trabajan con Internet Mail, pero solo Corporate Workgroup trabaja con la interfaz MAPI. Outlook XP: Combina las versiones Internet Mail y Corporate Workgroup.
Un breve ejemplo
Una de las tareas ms fcil de automatizar en Outlook es el envo de un correo. Veremos un ejemplo de solamente unas pocas lneas. LOCAL lcPerfil AS CHARACTER, lcContrasenia AS CHARACTER , ; lcDestinatario AS CHARACTER, lcTema AS CHARACTER , ; lcCuerpo AS CHARACTER LOCAL loOutlook AS "Outlook.Application", ; loNameSpace AS OBJECT, loMailItem AS OBJECT #DEFINE LF_CR CHR(10)+CHR(13) *-- Datos del correo lcPerfil = "Prueba" lcContrasenia = "prueba" lcDestinatario = "luismaria@portalfox.com" lcTema = "Prueba" lcCuerpo = "Prueba desde la Conferencia Visual FoxPro Espaa 2003." + LF_CR lcCuerpo = lcCuerpo + "Saludos desde A Corua." + LF_CR *-- Creo objetoa Outlook y NameSpace loOutlook = CREATEOBJECT("Outlook.Application") loNameSpace = loOutlook.GetNameSpace("MAPI") *-- Ejecuto los mtodos loNameSpace.Logon(lcPerfil , lcContrasenia) loMailItem = loOutlook.CreateItem(0) loMailItem.Recipients.ADD(lcDestinatario) loMailItem.Subject = lcTema loMailItem.Body = lcCuerpo loMailItem.SEND loNameSpace.Logoff loNameSpace = .NULL. loOutlook = .NULL.
Problemas de seguridad
Outlook XP y Outlook 2000 SP2, incluyen los parches de seguridad de Microsoft. Estos parches restringen, entre otras cosas, el acceso a la libreta de direcciones y el envo de correo mediante automatizacin, con el fin de evitar cdigos maliciosos que toman los datos de nuestra libreta de direcciones y envan correo sin nuestro consentimiento.
Pgina 20
Cuando intentamos enviar un correo desde Visual FoxPro, se nos presenta el siguiente cuadro de dialogo, que luego de 5 segundos habilita el botn "Si" (Figura 13).
Figura 13: "...intentando enviar correo..." Cuando intentamos acceder a la libreta de direcciones aparece el cuadro de dialogo el cual nos permitir un acceso inmediato, o de 1, 2, 5, 10 minutos que debemos seleccionar (Figuras 14).
Y ahora que?
Estas son algunas de las opciones disponemos nosotros para trabajar con estos parches de seguridad: Mantener la versin de Office 2000 SR-1 y no actualizarla ni instalarle parches de seguridad, con los peligros que esto significa. Si se tienen Outlook y Exchange instalados, el administrador de Exchange, puede disminuir las alertas o registrar algunas aplicaciones como seguras. Outlook Redemption: Es un objeto COM que se adapta fcilmente a la automatizacin y utiliza la MAPI extendida. Esta DLL fue escrita por Dmitry Streblechenko (MS Outlook MVP) y esta disponible en http://www.dimastr.com/redemption. Este es un producto comercial con un valor de U$S 200 aproximadamente. Existe para descarga una versin libre con fines de desarrollo. Express ClickYes: Es un pequeo programa residente que se maneja mediante la API de Windows. Este "presionar" el botn "Si" antes de que el dialogo aparezca. Este programa es gratis y esta disponible en http://www.express-soft.com/mailmate/clickyes.html. En el mismo sitio existe un ejemplo para Visual FoxPro.
Pgina 21
*-- Propiedades oOutlook = .NULL. oNameSpace = .NULL. ... ... Como vimos anteriormente en la definicin de la clase cWord, la sentencia IMPLEMENTS nos permitir interactuar con los eventos de Outlook desde Visual FoxPro. Solo pondremos cdigo para interactuar ApplicationEvents_10_Quit(): WITH THIS .oNameSpace = .NULL. .oOutlook = .NULL. ENDWITH con el evento Quit de Outlook en el mtodo
El formulario de ejemplo
En este ejemplo utilizaremos un formulario con un objeto PageFrame con dos Pginas, una para enviar correo y la otra para leer los correos desde la Bandeja de Entrada. En el mtodo Init() creamos una instancia de la clase cOutlook y vinculamos los eventos de Outlook: THISFORM.oCorreo = NEWOBJECT('cOutlook','cOutlook.prg') IF THISFORM.oCorreo.CrearServidor() *-- Vinculo los eventos de Outlook a mtodos del objeto oCorreo IF NOT EVENTHANDLER(THISFORM.oCorreo.oOutlook, THISFORM.oCorreo) MESSAGEBOX('No se pudo vincular a los eventos de Outllok', 16, 'Error!' ) ENDIF ENDIF Tambin en el mtodo Init() llamamos a un formulario para el inicio de sesin: DO FORM Inicio WITH THISFORM.oCorreo TO llAceptar IF NOT (llAceptar AND THISFORM.oCorreo.IniciarSesion()) MESSAGEBOX('Fall el inicio sesin', 48, 'Inicio de sesin') RETURN .F. ENDIF
Pgina 22
Enviar un correo
Antes de invocar el mtodo EnviarCorreo(), configuramos todas las propiedades necesarias para el envo de correo. Esto lo hacemos en el mtodo Click() del botn "Enviar". WITH THISFORM.oCorreo .CargarVector(THIS.PARENT.txtTo.VALUE, 'aTO') .CargarVector(THIS.PARENT.txtCC.VALUE, 'aCC') .CargarVector(THIS.PARENT.txtAdjunto.VALUE, 'aAdjuntos') .cTema = ALLTRIM(THIS.PARENT.txtTema.VALUE) .cCuerpo = ALLTRIM(THIS.PARENT.edtCuerpo.VALUE) IF .EnviarCorreo() MESSAGEBOX('Mensaje enviado con xito.', 64, 'Aviso') THISFORM.LimpiarPagina() ELSE MESSAGEBOX('No se pudo enviar el mensaje.', 48, 'Problemas') ENDIF ENDWITH RETURN En el mtodo EnviarCorreo() de la clase cOutlook creo un nuevo mensaje y lo armo segn las propiedades anteriormente configuradas. PROCEDURE EnviarCorreo() LOCAL loMensaje AS OBJECT, llRet AS Logical LOCAL lnI AS INTEGER, lnIndex AS INTEGER *-- Creo un nuevo mensaje WITH THIS loMensaje = .oOutlook.CreateItem(0) IF VARTYPE(loMensaje) = 'O' loMensaje.Subject = .cTema loMensaje.Body = .cCuerpo *-- Recipientes lnIndex = 0 *-- TO lnLen = ALEN(.aTO) FOR lnI = 1 TO lnLen IF NOT EMPTY(.aTO(lnI)) lnIndex = lnIndex + 1 loMensaje.Recipients.ADD(.aTO(lnI)) loMensaje.Recipients(lnIndex).TYPE = 1 ENDIF ENDFOR *-- CC lnLen = ALEN(.aCC) FOR lnI = 1 TO lnLen IF NOT EMPTY(.aCC(lnI)) lnIndex = lnIndex + 1 loMensaje.Recipients.ADD(.aCC(lnI)) loMensaje.Recipients(lnIndex).TYPE = 2 ENDIF ENDFOR *-- BCC lnLen = ALEN(.aBCC) FOR lnI = 1 TO lnLen IF NOT EMPTY(.aBCC(lnI)) lnIndex = lnIndex + 1 loMensaje.Recipients.ADD(.aBCC(lnI)) loMensaje.Recipients(lnIndex).TYPE = 3 ENDIF
Pgina 23
ENDFOR *-- Adjuntos lnLen = ALEN(.aAdjuntos) FOR lnI = 1 TO lnLen IF NOT EMPTY(.aAdjuntos(lnI)) AND FILE(.aAdjuntos(lnI)) loMensaje.Attachments.ADD(.aAdjuntos(lnI)) ENDIF ENDFOR llRet = loMensaje.SEND ELSE llRet = .F. ENDIF ENDWITH RETURN llRet ENDPROC
Pgina 24
llRet = .T. ELSE llRet = .F. ENDIF ENDWITH ELSE llRet = .F. ENDIF RETURN llRet ENDPROC
Resumen
En este documento vimos solo algunos ejemplos de automatizacin de Office. Las posibilidades son muchas y cada una depende de la solucin que debemos implementar en nuestras aplicaciones. Recuerden que todo el poder que nos brindan las distintas herramientas de Office, pueden ser manejadas desde Visual FoxPro. Solo es cuestin de adoptar alguna de las tcnicas vistas y ponerse a trabajar...
Pgina 25