26 de julio de 2009

Usando formatos de archivos de Excel 2007 en VFP 9.0

Artículo original: Using Excel 2007 File Formats in VFP 9.0
http://www.sweetpotatosoftware.com/SPSBlog/PermaLink,guid,6b9d4c6f-76bb-4444-8d5b-9e321c605534.aspx
Autor: Craig Boyd
Traducido por: Luis María Guayán

Los Problemas

Los comandos APPEND FROM y COPY TO de Visual FoxPro 9.0 son incompatibles con los nuevos formatos de archivo de Excel 2007 (XLS, XLSX, xlsb, y XLSM). Habrá notado que incluí XLS y usted cree que es soportado, pero sólo intente guardar su libro XLS Excel 97-2003 en el modo de compatibilidad de Excel 2007 y, a continuación, utilice el comando APPEND FROM sobre éste. VFP se quejará de la validez del archivo, en resumen, no funciona. Y, el comando COPY TO esta simplemente atascado en los oscuros años del XLS y XL5 disponibles. Bien, entonces todo esto es el primer problema.

El segundo problema con los comandos APPEND FROM y COPY TO es que no permiten especificar las columnas o los campos; una cláusula WHERE o FOR; o especificar un rango o área de impresión. Estamos bastante atascados con especificar un libro, APPEND FROM permite un parámetro opcional para la Hoja, pero eso no es adecuado ni super atractivo.

El tercer problema es que la solución habitualmente sugerida para los problemas de arriba, es utilizar automatización, y la automatización es super lenta debido al consumo efectuado por COM. Esto también introduce una dependencia adicional de tener instalado Excel 2007 en la máquina en la que el código se ejecuta. Lo "lento" nunca es aceptable (las aplicaciones VFP puede tener sus cosas, pero la lentitud no es una de ellas) y la dependencia adicional, aceptable en algunos casos, es un freno si se están ejecutando estos tipos de operaciones sobre un servidor web que no tiene instalado Excel 2007.

La Solución

Yo estaba trabajando en una solución para un cliente mío, que requería que consuma y cree archivos XLS, XLSX, xLSB y XLSM, sin que el usuario necesite tener instalado Excel 2007. Después de lanzar unas pruebas conjuntamente, yo incluí la ayuda de mi amigo Bo Durban. El código proporcionado en un archivo .ZIP al final de este artículo, es lo que surgió después de un par de intensas sesiones de codificación. Un agradecimiento especial a mi cliente por permitir compartirlo.

El Código

El código incluye 2 funciones principales: AppendFromExcel() y CopyToExcel(). También hay 4 funciones de ayuda: AWorkSheets(), AWorkSheetColumns(), CreateExcelTemplate(), y EmptyFieldToNull() que le puede resultar útil o interesante. El código:
  • No requiere de Office 2007
  • Pueden añadir de formatos de archivo xls, xlsx, xlsm, y xlsb
  • Puede crear y copiar a los formatos de archivo xls, xlsx, xlsm, y xlsb
  • Soporta todas las tablas de Excel (hojas de trabajo, rangos, áreas de impresión)
  • Permite que las columnas de la hoja de cálculo y los campos de las tablas puedan ser especificados
  • Permite que la cabecera de la fila en la hoja de trabajo pueda contener espacios en los nombres de las columnas, encerrándolos entre corchetes, por ejemplo [Mi Columna # 1]
  • Proporciona soporte para expresiones con cláusulas WHERE de SQL o cláusula FOR de VFP
  • Es super rápido
  • Probablemente hace algunas otras cosas que no estoy pensando ahora :)
De todas formas, descargue y descomprima el PRG, descomente y/o modifique el código del ejemplo de uso de la parte superior del PRG a su gusto, y diviértase!

Originalmente incluí el código en la parte inferior de este artículo, pero el código hacía locuras con el ancho de este blog, porque contiene algunas líneas muy largas con binarios. Por lo tanto, aquí está el vínculo para la descarga del archivo PRG que contiene las cosas que necesita:

Nota: Adicionalmente una reestructuración del código (refactoring) es necesaria, y definitivamente esto clama por una clase que se deba construir, pero el código funciona completamente como está.
Si tienen algún problema ejecutando el código (especialmente si aparece el diálogo de Seleccionar un origen de datos) es posible que deba comprobar el proveedor OLEDB y observar las alternativas proporcionadas en el código.

11 de julio de 2009

¿Es una variable o propiedad un array?

Entrada original: Is variable or property an array?
http://www.berezniker.com/content/pages/visual-foxpro/-varable-or-property-array
Autor: Sergey Berezniker
Traductor: Luis María Guayán

Cuando validamos un parámetro en una función o procedimiento, a veces es necesario determinar si el parámetro pasado es una matriz (array). Hasta VFP 9.0 no había una manera evidente de hacerlo.

En VFP 9.0 la función TYPE() acepta un segundo parámetro adicional: 1, para determinar si se la expresión pasada es una matriz, una colección o ninguno de los dos. En versiones anteriores de VFP podemos usar la función TYPE() en combinación con la función ALEN().

Este es el código de ejemplo:

&& VFP 9.0
IF TYPE("AlgunaVariableOrPropiedad",1) = "A"
  && Es un array
ENDIF
 
&& VFP 8.0 y anteriores
IF TYPE("ALEN(AlgunaVariableOrPropiedad)")) = "N"
  && Es un array
ENDIF

Comprobar que TYPE("AlgunaVariableOrPropiedad[1]") = "N" no funciona para propiedades intrínsecas de VFP. Retornando "N" para estas.

loForm = CreateObject ( "Form") 
? TYPE("loForm.Top[1]") && Retorna N

9 de julio de 2009

Como generar el numero de nuestros comprobantes sin morir en el intento

Artículo de Maximiliano Accotto (Buenos Aires, Argentina) publicado en su Blog.

Como generar el numero de nuestros comprobantes sin morir en el intento

Maxi AccottoEn muchas de nuestras aplicaciones (por no decir en casi todas) nos vemos en la necesidad de generar números auto incrementales, por ejemplo para la numeración de facturas, remitos, órdenes de compra u otro tipo de documentos.

La solución a esta tarea se puede hacer de distintas maneras. La idea de este artículo es mostrar en SQL Server cómo podemos resolver este problema, y poder analizar sus pros y contras...

Para leer el artículo completo haz click Aquí

5 de julio de 2009

Conocer si tu aplicación ya está en ejecución

He visto algunos ejemplos usando la API de Windows para determinar si tu aplicación ya está en ejecución. Muchos de esos ejemplos utilizan el "caption" de una ventana y con ello puedes tomar acciones en cuanto a permitir la ejecución simultánea de varias instancias o no.

En lugar de permitir varias instancias, mejor permítele hacer varias tareas a la vez dentro de la aplicación.

El ejemplo que les expongo hace uso de WMI de Windows y es bastante sencillo.

En esencia es una consulta sql que nos devuelve los nombres de los procesos que están en ejecución. He dejado los comentarios para explicar que en mi caso muy particular, yo pregunto si la cantidad de procesos es mayor que o igual a 3 (y usando un like en el sql) porque hago uso de dos programas: uno que será el "launcher" el cual buscará el ejecutable compilado más reciente y éste será el que se ejecute (Así no tengo que interrumpir las labores de otros usuarios cuando tenga que hacer alguna correción en otras pantallas)

FUNCTION MyProcessName  
 *.* Determina si el programa de recibo bodega ya está en ejecución.
 *.* De ser así, devuelve un valor lógico que será usado para terminar o continuar con el programa.
 *-* Se debe tomar en cuenta que ReciboBodega es ejecutado usando dos programas: 
 *-* recibo_bodega.exe y recibo_bodegannn.exe
 LOCAL lcComputer as String

 lcComputer = '.'
 loWMIService = Getobject('winmgmts:'+'{impersonationLevel=impersonate}!\\' + lcComputer + '\root\cimv2')
 colProcessList = loWMIService.ExecQuery('Select * from Win32_Process where name like "recibo_bodega%"')
 IF colProcessList.count>=3
  RETURN .T.
 ELSE
  RETURN .F. 
 ENDIF 
ENDFUNC 

Pero en su caso puede preguntar directamente por el nombre de su ejecutable y cuando "count" sea igual a uno, su función regresará un valor Cierto.

Por último, en el su prg principal, en sus primeras líneas deberás poner:

IF MyProcessName()
   RETURN .F.
ENDIF  

Saludos,

Jorge Luis Vejerano, Panamá