*---------------------------------------------- * FUNCTION EsFechaValida(tnAnio, tnMes, tnDia) *---------------------------------------------- * Retorna: .T. si la fecha es válida * Parametros: Año, Mes y Día (todos numéricos) * Uso: EsFechaValida(2000,2,30) && .F. *---------------------------------------------- FUNCTION EsFechaValida(tnAnio, tnMes, tnDia) RETURN ; VARTYPE(tnAnio) = "N" AND ; VARTYPE(tnMes) = "N" AND ; VARTYPE(tnDia) = "N" AND ; BETWEEN(tnAnio, 100, 9999) AND ; BETWEEN(tnMes, 1, 12) AND ; BETWEEN(tnDia, 1, 31) AND ; NOT EMPTY(DATE(tnAnio, tnMes, tnDia)) ENDFUNC *----------------------------------------------Luis María Guayán
27 de octubre de 2003
Validar una fecha
¿El 29 de Febrero de 2004 es una fecha válida? ¿Existe el 31 de Abril de 2010? Con esta función podemos saber si una fecha es válida o no.
23 de octubre de 2003
Enviar y leer correo con Outlook desde Visual FoxPro
El modelo de objetos de Outlook es muy rico y poderoso. Esta interfaz está disponible como un servidor de automatización, o sea, que todo lo podemos automatizar mediante programación desde Visual FoxPro.
Un breve ejemplo
Una de las tareas más fácil de automatizar en Outlook es el envío de un correo. Veremos un ejemplo de solamente unas pocas líneas.
Lo primero que debemos hacer para automatizar Outlook, es crear un objeto Outlook. 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 métodos Logon y Logoff.
Un breve ejemplo
Una de las tareas más fácil de automatizar en Outlook es el envío de un correo. Veremos un ejemplo de solamente unas pocas líneas.
Lo primero que debemos hacer para automatizar Outlook, es crear un objeto Outlook. 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 métodos Logon y Logoff.
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 Mail lcPerfil = "Prueba" lcContrasenia = "prueba" lcDestinatario = "prueba@portalfox.com" lcTema = "Prueba: " + TTOC(DATETIME()) lcCuerpo = "Prueba enviando un mail desde Visual FoxPro." + LF_CR lcCuerpo = lcCuerpo + "Saludos." + LF_CR *-- Creo objetos Outlook y NameSpace loOutlook = CREATEOBJECT("Outlook.Application") loNameSpace = loOutlook.GetNameSpace("MAPI") *-- Ejecuto los métodos 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.
21 de octubre de 2003
Combinar correspondencia con Word desde Visual FoxPro
En este ejemplo vamos realizar la tarea de Combinar Correspondencia con Microsoft Word desde Visual FoxPro. Para ello vamos a crear el documento y vamos a utilizar la herramienta "Mail Merge" de Word. Los datos a combinar los tomaremos de la base de datos "Northwind" que viene en los ejemplos de Visual FoxPro 8.
Definición de la clase cWord
Para combinar correspondencia definimos de una clase llamada cWord con los métodos necesarios para esta tarea. El código de la clase es el siguiente:
El siguiente es el código de nuestro programa "Combinar.prg" donde creamos una instancia de la clase cWord y comenzamos a ejecutar los métodos de esa clase.
En primer lugar invocamos el método CrearServidor() que nos retorna el objeto oWord que será nuestro servidor de automatización.
Abrir y/o crear la carta
El método AbrirCarta(), abre la carta de Word si esta existe o crea una nueva carta con el método CrearCarta(). Ambos métodos retornan un objeto Document de Word.
Crear la carta
En el caso de crear o abrir una carta ya existente de Word, estas deben contener los nombres de los campos para su reemplazo en la combinación. Estas cartas serán los documentos principales para la combinación.
La fuente de los datos
También debemos crear o abrir los documentos con los datos a combinar. En este ejemplo creamos un archivo del tipo CSV (Valores Separados por Comas) desde una cláusula SELECT a la tabla "Customers" de la base de datos "Northwind"
Obtener los datos a combinar
Crear la fuente de datos (archivo .CSV)
Para esta tarea tenemos el método GenerarDataSource() que crea el archivo con los datos y establece la propiedad cDataSource de la clase cWord.
Combinar la carta
En el método CombinarCarta() ejecutamos las siguientes sentencias para:
Ejecutar la combinación
Guardar la carta
Para finalizar tenemos el método GuardarCarta() que guarda el documento principal, con la posibilidad mediante un parámetro de cerrar el documento.
En este ejemplo el documento combinado que se genera quedará abierto, entonces hacemos la aplicación visible para que el usuario lo guarde o imprima directamente desde la ventana de Word. También establecemos la carpeta donde están los documentos de este ejemplo, para que Word por defecto la seleccione en la ventana de "Guardar...".
Pueden descargar el código fuente de los programas desde el siguiente vínculo: combinar.zip
Hasta la próxima.
Luis María Guayán
Definición de la clase cWord
Para combinar correspondencia definimos de una clase llamada cWord con los métodos necesarios para esta tarea. El código de la clase es el siguiente:
*-------------------------------------------------- * Clase cWord *-------------------------------------------------- DEFINE CLASS cWord AS CUSTOM *-- * Propiedades *-- oWord = .NULL. && Objeto Word cDirApp = ADDBS(SYS(5) + SYS(2003)) cDirDat = ADDBS(HOME(2) + 'Northwind') cDataSource = '' *-------------------------------------------------- * Creo el servidor de automatización *-------------------------------------------------- PROCEDURE CrearServidor() *-- Creo el objeto THIS.oWord = CREATEOBJECT('Word.Application') RETURN VARTYPE(THIS.oWord) = 'O' ENDPROC *-------------------------------------------------- * Cierro el servidor de automatización *-------------------------------------------------- PROCEDURE CerrarServidor() *-- Cierro Word THIS.oWord.QUIT() THIS.oWord = .NULL. RETURN ENDPROC *-------------------------------------------------- * Abro la Carta, si no existe la creo *-------------------------------------------------- PROCEDURE AbrirCarta(tcArchivo) LOCAL loDoc AS 'Word.Document' tcArchivo = FORCEEXT(tcArchivo,'DOC') IF NOT FILE(THIS.cDirApp + tcArchivo) *-- Si no existe la carta, la creo loDoc = THIS.CrearCarta(tcArchivo) ELSE *-- Si existe la carta, la abro loDoc = THIS.oWord.Documents.OPEN(THIS.cDirApp + tcArchivo) *-- y me aseguro que no tiene un documento asociado loDoc.MailMerge.MainDocumentType = -1 && wdNotAMergeDocument ENDIF *-- Retorno un objeto Document RETURN loDoc ENDPROC *-------------------------------------------------- * Creo la Carta *-------------------------------------------------- PROCEDURE CrearCarta(tcArchivo) LOCAL loDoc AS 'Word.Document' *-- Creo un nuevo documento loDoc = THIS.oWord.Documents.ADD(,,0) *-- Guardo el documento como ... loDoc.SAVEAS(THIS.cDirApp + tcArchivo) *-- Activo el documento loDoc.ACTIVATE *-- Comienzo a 'escribir' el documento WITH THIS.oWord.SELECTION .FONT.NAME = 'Tahoma' .FONT.SIZE = 10 .ParagraphFormat.ALIGNMENT = 2 && wdAlignParagraphRight .TypeText('San Miguel de Tucumán, ' + DTOC(DATE())) .TypeParagraph .ParagraphFormat.ALIGNMENT = 0 && wdAlignParagraphLeft .TypeParagraph .TypeParagraph .TypeParagraph .TypeParagraph .TypeParagraph .TypeParagraph .TypeText('Señores: ') .FONT.Bold = .T. .FIELDS.ADD(.RANGE, -1, 'MERGEFIELD CompanyName ') .FONT.Bold = .F. .TypeParagraph .TypeText('At: ') .FIELDS.ADD(.RANGE, -1, 'MERGEFIELD ContactName ') .TypeParagraph .FIELDS.ADD(.RANGE, -1, 'MERGEFIELD Address ') .TypeParagraph .FIELDS.ADD(.RANGE, -1, 'MERGEFIELD PostalCode') .TypeText(' - ') .FIELDS.ADD(.RANGE, -1, 'MERGEFIELD City ') .TypeParagraph .FONT.Underline = 1 && wdUnderlineSingle .FIELDS.ADD(.RANGE, -1, 'MERGEFIELD Country ') .FONT.Underline = 0 && wdUnderlineSingle .TypeParagraph .TypeParagraph .TypeParagraph .TypeParagraph .TypeText(CHR(9) + 'Estimado/a ') .FIELDS.ADD(.RANGE, -1, 'MERGEFIELD ContactName ') .TypeParagraph .TypeParagraph .TypeText(CHR(9) + 'Nos dirigimos a Ud. con el objeto de comunicarle ' + ; 'la nueva dirección de nuestra empresa') .TypeParagraph .TypeParagraph .FONT.Bold = .T. .TypeText('Informática del Tucumán') .FONT.Bold = .F. .TypeParagraph .TypeText('9 de Julio 123, 1° Piso') .TypeParagraph .TypeText('4000 - San Miguel de Tucumán') .TypeParagraph .TypeText('Tucumán, Argentina') .TypeParagraph .TypeText('Teléfono (+54) (381) 681-4521') .TypeParagraph .TypeParagraph .TypeText(CHR(9) + 'Sin otro particular lo saludamos atte.') .TypeParagraph .TypeParagraph .TypeParagraph .TypeParagraph .TypeParagraph .TypeParagraph .TypeText('Manuel Belgrano') .TypeParagraph .TypeText('Socio Gerente') .TypeParagraph .TypeText('Informática del Tucumán') .TypeParagraph ENDWITH *-- Retorno un objeto Document RETURN loDoc ENDPROC *-------------------------------------------------- * Creo archivo DataSource *-------------------------------------------------- PROCEDURE GenerarDataSource LOCAL lcArchivo AS CHARACTER IF NOT DBUSED('Northwind') OPEN DATABASE (THIS.cDirDat + 'Northwind') SHARED ENDIF SET DATABASE TO 'Northwind' *-- Consulta a los Clientes de Northwind SELECT CompanyName, ContactName, ; Address, PostalCode, City, Country ; FROM Customers ; INTO CURSOR Clientes *-- Copio el cursor al archivo para combinar lcArchivo = SYS(2015) COPY TO (THIS.cDirApp + lcArchivo) TYPE CSV USE IN Clientes THIS.cDataSource = THIS.cDirApp + FORCEEXT(lcArchivo,'CSV') RETURN ENDPROC *-------------------------------------------------- * Combino la Carta *-------------------------------------------------- PROCEDURE CombinarCarta(toDoc) WITH toDoc.MailMerge .MainDocumentType = 0 && wdFormLetters .OpenDataSource(THIS.cDataSource) .Execute() ENDWITH WITH THIS.oWord *-- Cambio la Carpeta del cuadro de diálogo 'Guardar...' .ChangeFileOpenDirectory(THIS.cDirApp) *-- Maximizo y hago visible .WINDOWSTATE = 1 && wdWindowStateMaximize .VISIBLE = .T. && True ENDWITH RETURN ENDPROC *-------------------------------------------------- * Guardo el Documento, si tlCierra = .T. lo cierra *-------------------------------------------------- PROCEDURE GuardarCarta(toDoc, tlCierra) *-- Guardo el documento toDoc.SAVE() IF tlCierra *-- Cierro el documento toDoc.CLOSE() ENDIF ENDPROC ENDDEFINE *-------------------------------------------------- * Fin Clase cWord *--------------------------------------------------El programa Combinar.prg
El siguiente es el código de nuestro programa "Combinar.prg" donde creamos una instancia de la clase cWord y comenzamos a ejecutar los métodos de esa clase.
*------------------------------------------------- * Combinar.prg *------------------------------------------------- LOCAL lo AS OBJECT, loDoc AS OBJECT lo = NEWOBJECT('cWord','cWord.prg') IF lo.CrearServidor() *-- Ejecuto métodos de la clase loDoc = lo.AbrirCarta('MiCarta') lo.GenerarDataSource() lo.CombinarCarta(loDoc) lo.GuardarCarta(loDoc, .T.) ELSE MESSAGEBOX('No se pudo instanciar el servidor', 16, 'Error!') ENDIF lo = .NULL. RETURN *------------------------------------------------- * Fin Combinar.prg *-------------------------------------------------Ejecutando los métodos en la clase cWord
En primer lugar invocamos el método CrearServidor() que nos retorna el objeto oWord que será nuestro servidor de automatización.
Abrir y/o crear la carta
El método AbrirCarta(), abre la carta de Word si esta existe o crea una nueva carta con el método CrearCarta(). Ambos métodos retornan un objeto Document de Word.
Crear la carta
En el caso de crear o abrir una carta ya existente de Word, estas deben contener los nombres de los campos para su reemplazo en la combinación. Estas cartas serán los documentos principales para la combinación.
La fuente de los datos
También debemos crear o abrir los documentos con los datos a combinar. En este ejemplo creamos un archivo del tipo CSV (Valores Separados por Comas) desde una cláusula SELECT a la tabla "Customers" de la base de datos "Northwind"
Obtener los datos a combinar
Crear la fuente de datos (archivo .CSV)
Para esta tarea tenemos el método GenerarDataSource() que crea el archivo con los datos y establece la propiedad cDataSource de la clase cWord.
Combinar la carta
En el método CombinarCarta() ejecutamos las siguientes sentencias para:
- Hacer la carta del tipo Documento Principal.
- Abrir el archivo con la fuente de datos.
- Ejecutar la combinación
Ejecutar la combinación
Guardar la carta
Para finalizar tenemos el método GuardarCarta() que guarda el documento principal, con la posibilidad mediante un parámetro de cerrar el documento.
En este ejemplo el documento combinado que se genera quedará abierto, entonces hacemos la aplicación visible para que el usuario lo guarde o imprima directamente desde la ventana de Word. También establecemos la carpeta donde están los documentos de este ejemplo, para que Word por defecto la seleccione en la ventana de "Guardar...".
Pueden descargar el código fuente de los programas desde el siguiente vínculo: combinar.zip
Hasta la próxima.
Luis María Guayán
17 de octubre de 2003
SimpleChart revisitado
Autor: Mike Lewis
Texto original: Simple Chart Revisited
http://www.ml-consult.co.uk/foxst-27.htm
Traducido por: Ana María Bisbé York
Sus comentarios, preguntas y sugerencias sobre nuestro control para graficar.
Nuestro agradecimiento a todos ustedes que nos han enviado sus opiniones sobre nuestro control SimpleChart. Desde que nosotros publicamos el control en Marzo 2002, se ha convertido en el elemento más bajado del sitio Foxstuff, y nos da mucho gusto que muchos programadores de FoxPro lo hayan encontrado útil.
En este artículo vamos a contestar algunas de sus preguntas más frecuentes sobre este control y también pasarles algunos consejos útiles de sus usuarios.
Para aquellos que no han visto el control SimpleChart SimpleChart es en esencia una envoltura del control ActiveX Microsoft's MSChart. Su objetivo es simplificar el trabajo en la elaboración de gráficos, histogramas, y otros diagramas bidimensionales y tridimensionales. Para encontrar más información sobre él y para obtener su copia gratis, vea el artículo Add graphs and charts to your VFP applications.
¿Tiene que estar mi gráfico solo en un formulario o puedo colocarlo junto a otros controles?
Es su decisión. El control trabaja exactamente igual en ambas situaciones.
Estoy tratando de crear un gráfico bidimensional de barra horizontal; pero me aparece un error OLE, ‘Invalid property value’ (Valor de propiedad no válido). ¿Por qué?
SimpleChart admite tipos de gráficos del 0 al 9 y 14 y 16. Puede asignarle solo estos valores a la propiedad. Los otros 16 valores que se ve en la Ventana de propiedades no funcionan en VFP (el gráfico bidimensional de barra horizontal sería el 11). Esta es una limitación del MS Chart, no del SimpleChart.
He seguido cuidadosamente las instrucciones en la creación del gráfico; pero no ocurre nada. No hay mensaje de error. El gráfico simplemente falla y no aparece.
La explicación más probable es que el gráfico no ha podido encontrar la tabla o cursor. Es necesario asegurarse de que la tabla o cursor está abierta en la sesión de datos actual y el alias correcto ha sido guardado en la propiedad cAlias. Verifique también que la propiedad cData contiene una lista válida de nombres de campos numéricos. El método CreateChart retornará .F. si se detecta un problema con cAlias o cData.
¿Qué ficheros adicionales necesito para distribuir mi aplicación?
Es necesario distribuir el control ActiveX MS Chart, que es el MSCHRT20.OCX. Este OCX debe ser instalado en la carpeta System del usuario y registrarlo como un Control ActiveX. Si no está seguro de cómo hacerlo, verifique la ayuda del Asistente de Instalación (si utiliza VFP 6.0) o InstallShield Express (VFP 7.0 y VFP 8.0)
¿Cómo puedo imprimir mi gráfico?
Ni MS Chart ni SimpleChart respalda la impresión. Sin embargo, existe un método EditCopy, que permite copiar el gráfico al Portapapeles. Posteriormente se puede pegar el gráfico en otra aplicación y luego imprimirlo desde allí (vea también las dos preguntas siguientes.)
Traté de utilizar el Método EditCopy para copiar mi gráfico a MS Word, pero todo lo que logré ver fue un bloque de figuras.
Lo que vio fueron los datos subyacentes en los que se basa el gráfico. Para ver el gráfico seleccione Pegado Especial del Menú Edición de Word, luego seleccione Imagen. Lo mismo ocurrirá en Excel y algunas otras aplicaciones.
Dado que es posible pegar un gráfico en un documento de Word y después imprimirlo, ¿existe una vía para hacerlo programáticamente, sin intervención del usuario?
Si. La técnica siguiente utiliza ActiveX Automation para hacer eso justamente (nuestro agradecimiento a Ben Hambigde por sugerir la idea y a Jon Barker por su ayuda en la validación)
Primero, crear un formulario con las propiedades del usuario. Le llamaremos oWord. Inicializamos como Null, por ejemplo, para ejecutar este código en el INIT del formulario colocar:
Finalmente, adicione este código en el evento Destroy de este formulario.
¿Cómo puedo mostrar un cursor de rotación para que los usuarios puedan rotar mi gráfico tridimensional?
En teoría, usted puede hacer esto fijando la propiedad AllowDynamicRotation en .T. Se supone que mostrará un cursor de rotación cuando el usuario presione la tecla Control (el cursor de rotación aparece como una flecha de cuatro puntas y permite al usuario rotar el gráfico 3D interactivamente.) En la práctica, nunca lo hemos logrado obtenere en VFP (recibiremos gustosos sugerencias de alguien que sepa como hacer esto).
¿Es posible rotar un gráfico 3D programáticamente?
Si, existen las propiedades disponibles para ajustar tanto la rotación como la elevación de los gráficos. Para ver esta acción, adicione dos controles spinner a su formulario. Coloque este código en el Evento InteractiveChange del primer spinner
¿Existe alguna vía para cambiar el Formato de letra utilizado en las etiquetas?
Este código va a cambiar la etiqueta del eje X a Fuente = Arial Narrow y su tamaño 14
¿Es posible mostrar títulos para los tres ejes?
Si. SimpleChart puede mostrar un título para ele eje X y para ambos ejes Y Aquí mostramos como su código pudiera ser escrito:
El objeto AxisTitle tiene un conjunto de otras propiedades que usted puede utilizar para personalizar el título -- TextLayout.Orientation, por ejemplo, le permite escoger la orientación (1 = horizontal, 2 = vertical). Además el objeto VFont tiene propiedades para Style (1 = negrita, 2 = cursiva, 3 = negritaCursiva) y Effect (256 = tachar, 512 = subrayar)
Mike Lewis, Consultants Ltd. Julio 2002. Revisado Septiembre 2002
Texto original: Simple Chart Revisited
http://www.ml-consult.co.uk/foxst-27.htm
Traducido por: Ana María Bisbé York
Sus comentarios, preguntas y sugerencias sobre nuestro control para graficar.
Nuestro agradecimiento a todos ustedes que nos han enviado sus opiniones sobre nuestro control SimpleChart. Desde que nosotros publicamos el control en Marzo 2002, se ha convertido en el elemento más bajado del sitio Foxstuff, y nos da mucho gusto que muchos programadores de FoxPro lo hayan encontrado útil.
En este artículo vamos a contestar algunas de sus preguntas más frecuentes sobre este control y también pasarles algunos consejos útiles de sus usuarios.
Para aquellos que no han visto el control SimpleChart SimpleChart es en esencia una envoltura del control ActiveX Microsoft's MSChart. Su objetivo es simplificar el trabajo en la elaboración de gráficos, histogramas, y otros diagramas bidimensionales y tridimensionales. Para encontrar más información sobre él y para obtener su copia gratis, vea el artículo Add graphs and charts to your VFP applications.
¿Tiene que estar mi gráfico solo en un formulario o puedo colocarlo junto a otros controles?
Es su decisión. El control trabaja exactamente igual en ambas situaciones.
Estoy tratando de crear un gráfico bidimensional de barra horizontal; pero me aparece un error OLE, ‘Invalid property value’ (Valor de propiedad no válido). ¿Por qué?
SimpleChart admite tipos de gráficos del 0 al 9 y 14 y 16. Puede asignarle solo estos valores a la propiedad. Los otros 16 valores que se ve en la Ventana de propiedades no funcionan en VFP (el gráfico bidimensional de barra horizontal sería el 11). Esta es una limitación del MS Chart, no del SimpleChart.
He seguido cuidadosamente las instrucciones en la creación del gráfico; pero no ocurre nada. No hay mensaje de error. El gráfico simplemente falla y no aparece.
La explicación más probable es que el gráfico no ha podido encontrar la tabla o cursor. Es necesario asegurarse de que la tabla o cursor está abierta en la sesión de datos actual y el alias correcto ha sido guardado en la propiedad cAlias. Verifique también que la propiedad cData contiene una lista válida de nombres de campos numéricos. El método CreateChart retornará .F. si se detecta un problema con cAlias o cData.
¿Qué ficheros adicionales necesito para distribuir mi aplicación?
Es necesario distribuir el control ActiveX MS Chart, que es el MSCHRT20.OCX. Este OCX debe ser instalado en la carpeta System del usuario y registrarlo como un Control ActiveX. Si no está seguro de cómo hacerlo, verifique la ayuda del Asistente de Instalación (si utiliza VFP 6.0) o InstallShield Express (VFP 7.0 y VFP 8.0)
¿Cómo puedo imprimir mi gráfico?
Ni MS Chart ni SimpleChart respalda la impresión. Sin embargo, existe un método EditCopy, que permite copiar el gráfico al Portapapeles. Posteriormente se puede pegar el gráfico en otra aplicación y luego imprimirlo desde allí (vea también las dos preguntas siguientes.)
Traté de utilizar el Método EditCopy para copiar mi gráfico a MS Word, pero todo lo que logré ver fue un bloque de figuras.
Lo que vio fueron los datos subyacentes en los que se basa el gráfico. Para ver el gráfico seleccione Pegado Especial del Menú Edición de Word, luego seleccione Imagen. Lo mismo ocurrirá en Excel y algunas otras aplicaciones.
Dado que es posible pegar un gráfico en un documento de Word y después imprimirlo, ¿existe una vía para hacerlo programáticamente, sin intervención del usuario?
Si. La técnica siguiente utiliza ActiveX Automation para hacer eso justamente (nuestro agradecimiento a Ben Hambigde por sugerir la idea y a Jon Barker por su ayuda en la validación)
Primero, crear un formulario con las propiedades del usuario. Le llamaremos oWord. Inicializamos como Null, por ejemplo, para ejecutar este código en el INIT del formulario colocar:
THISFORM.oWord = NULLLuego, ejecute el siguiente código en el momento en que usted desea imprimir el gráfico. Puede ser el Evento Clic del comando Imprimir
IF ISNULL(THISFORM.oWord) THISFORM.oWord=CREATEOBJECT("Word.Application") ENDIF oDoc=THISFORM.oWord.Documents.Add() THISFORM.MyChart.EditCopy() THISFORM.oWord.Selection.PasteSpecial(.F., .F., 0, .F., 3) oDoc.PrintOut oDoc.Close(0)Fundamentalmente, este código va a instanciar Microsoft Word como un servidor de Automatización (a no ser que haya sido instanciado antes), copia el gráfico en el Portapapeles, pega la imagen del gráfico (no los valores) en un nuevo documento de Word, imprime el documento y cierra el documento sin salvar. (En la quinta línea del código que se muestra arriba, MYChart es el nombre del objeto SimpleChart)
Finalmente, adicione este código en el evento Destroy de este formulario.
IF NOT ISNULL(THISFORM.oWord) THISFORM.oWord.Quit ENDIF
¿Cómo puedo mostrar un cursor de rotación para que los usuarios puedan rotar mi gráfico tridimensional?
En teoría, usted puede hacer esto fijando la propiedad AllowDynamicRotation en .T. Se supone que mostrará un cursor de rotación cuando el usuario presione la tecla Control (el cursor de rotación aparece como una flecha de cuatro puntas y permite al usuario rotar el gráfico 3D interactivamente.) En la práctica, nunca lo hemos logrado obtenere en VFP (recibiremos gustosos sugerencias de alguien que sepa como hacer esto).
¿Es posible rotar un gráfico 3D programáticamente?
Si, existen las propiedades disponibles para ajustar tanto la rotación como la elevación de los gráficos. Para ver esta acción, adicione dos controles spinner a su formulario. Coloque este código en el Evento InteractiveChange del primer spinner
THISFORM.MyChart.Plot.View3d.Rotation=this.ValueY en el evento InteractiveChange del Segundo control spinner:
THISFORM.MyChart.Plot.View3d.Elevation = this.ValueCuando usted ejecute el formulario y ajuste los valores de los controles spinner, verá algunos efectos interesantes (Nuestro agradecimiento a Kirk Kelly por suministrar esta información)
¿Existe alguna vía para cambiar el Formato de letra utilizado en las etiquetas?
Este código va a cambiar la etiqueta del eje X a Fuente = Arial Narrow y su tamaño 14
WITH THISFORM.MyChart.Plot.Axis(0) FOR EACH olabel IN .Labels olabel.VtFont.Name = "Arial Narrow" oLabel.vtFont.Size = 14 ENDFOR ENDWITHAlternativamente referencie Axis(1) o Axis(2) en lugar de Axis(0) en la primera línea. Esto le permitirá cambiar la fuente en los ejes verticales izquierdo y derecho respectivamente
¿Es posible mostrar títulos para los tres ejes?
Si. SimpleChart puede mostrar un título para ele eje X y para ambos ejes Y Aquí mostramos como su código pudiera ser escrito:
WITH THISFORM.MyChart.Plot.Axis(0) .AxisTitle.Text = "This is the X-axis" .AxisTitle.vtFont.Name = "Arial" .AxisTitle.VtFont.Size = 12 ENDWITHEsto mostrará un título horizontal para el eje X. Al igual que las etiquetas, usted puede referenciar Axis(1) o Axis(2) para los ejes Y (izquierdo y derecho respectivamente)
El objeto AxisTitle tiene un conjunto de otras propiedades que usted puede utilizar para personalizar el título -- TextLayout.Orientation, por ejemplo, le permite escoger la orientación (1 = horizontal, 2 = vertical). Además el objeto VFont tiene propiedades para Style (1 = negrita, 2 = cursiva, 3 = negritaCursiva) y Effect (256 = tachar, 512 = subrayar)
Mike Lewis, Consultants Ltd. Julio 2002. Revisado Septiembre 2002
6 de octubre de 2003
Contadores (punteros) Alternativa SQL
Pues eso, aqui teneis un ejemplo de como obtener nuevos codigos (disponibles) en una tabla cuyo indice principal sea numerico. P.E. Clientes, proveedores, etc.
Nos permite decidir el valor minimo por el que realizar la busqueda de un 'hueco'
Nos permite decidir el valor minimo por el que realizar la busqueda de un 'hueco'
PARAMETERS pcTabla, pcCampo, pnCodigo * pcTabla : Tabla en la que buscar * pcCampo : Campo en el que buscar * pnCodigo : Opcional, indica el minimo para buscar * AHORA VARIABLES LOCALES LOCAL lnCodigoMin IF PCOUNT()>2 * se ha pasado codigo minimo lnCodigoMin = pnCodigo ELSE * No se ha pasado lnCodigoMin = 0 ENDIF * a) Nos aseguramos de tener la tabla abierta IF !USED(pcTabla) USE (pcTabla) IN 0 SHARED ENDIF * ahora montamos la consulta SELECT MIN(&pcCampo+1) AS NuevoCod ; FROM &pcTabla ; WHERE &pcCampo>lnCodigoMin .and.; !deleted() .and. ; !&pcCampo+1 IN ; (SELECT DISTINC &pcCampo FROM &pcTabla) ; INTO CURSOR oNew * Comentar las dos siguientes lineas, * es solo para chequeo. ? 'Valor Obtenido : ' ?? oNew.NuevoCod * devolvemos nuevo codigo return oNew.NuevoCod *********** FIN *******Javier Amoros
1 de octubre de 2003
Codificar y decodificar claves fácilmente
Muy simple y lo codifica en base 64 binario. Para VFP 7/8
tupass = "PEPE" pass_encoded = STRCONV(tupass,13) ? pass_encoded pass_decoded = STRCONV(pass_encoded,14) ? pass_decodedJosé Temporini
Ejecutar sentencias de Fox puestas en un campo memo
Es algo un poco raro, pero imaginaros que tenemos un campo memo con código a ejecutar, como lo haríamos?
Pablo Roca
StrToFile(tabla.campomemo, 'temp.prg') compile temp.prg do temp
Pablo Roca
Suscribirse a:
Entradas
(
Atom
)