30 de julio de 2002

1001 Things You Wanted to Know About Visual FoxPro

1001 Things You Wanted to Know About Visual FoxPro
by Andy Kramek, Marcia Akins & Rick Schummer.



Title: 1001 Things You Wanted to Know About Visual FoxPro
Author: Andy Kramek, Marcia Akins & Rick Schummer
Editor: John Hosier
ISBN: 0-96550-933-8
Length: 600 pages
Press date: June, 2000
Ebook format: .CHM

Table of Contents

Chapter 1: Controlling the VFP Environment
Chapter 2: Functions and Procedures
Chapter 3: Design, Design and Nothing Else
Chapter 4: Basic Controls
Chapter 5: Combos and Lists
Chapter 6: Grids: The Misunderstood Controls
Chapter 7: Working with Data
Chapter 8: Data Buffering and Transactions
Chapter 9: Views in Particular, SQL in General
Chapter 10: Non-Visual Classes
Chapter 11: Forms and Other Visual Classes
Chapter 12: Developer Productivity Tools
Chapter 13: Miscellaneous Things
Chapter 14: Project Management
Chapter 15: Project Objects and Projecthooks
Chapter 16: Creating Reports
Chapter 17: Managing Reports

Para mas información: http://www.hentzenwerke.com/catalog/kilofox.htm

29 de julio de 2002

Como saber que usuarios estan conectados a una base de datos SQL Server

Cuando necesitemos saber que usuarios estan conectados a una base de datos de MS SQL Server 2000 podemos usar este procedmiento almacenado.
create procedure @base_de_datos nchar(128) as
begin
set nocount on
if exists (select name from sysobjects
   where name = 'tbl_usuarios_conectados')
   drop table tbl_usuarios_conectados
   
create table tbl_usuarios_conectados (spid smallint,
   /* esta columna se puede borrar si se desea utilizar en SQL Server 7*/
   ecid smallint, status nchar(30), loginname nchar(128),
   hostname nchar(128), blk char(5), dbname nchar(128), cmd nchar(16))

INSERT tbl_usuarios_conectados
exec sp_who

select distinct loginname, hostname
   from tbl_usuarios_conectados
   where dbname = @base_de_datos and hostname <> ' '
return
end
Fernando España

Como saber que usuarios estan conectados a una base de datos SQL server

Cuando necesitemos saber que usuarios estan conectados a una base de datos de MS SQL Server 2000 podemos usar este procedmiento almacenado.

create procedure @base_de_datos nchar(128) as
begin
set nocount on
if exists (select name from sysobjects
   where name = 'tbl_usuarios_conectados')
   drop table tbl_usuarios_conectados
   
create table tbl_usuarios_conectados (spid smallint,
   /* esta columna se puede borrar si se desea utilizar en SQL Server 7*/
   ecid smallint, status nchar(30), loginname nchar(128),
   hostname nchar(128), blk char(5), dbname nchar(128), cmd nchar(16))

INSERT tbl_usuarios_conectados
exec sp_who

select distinct loginname, hostname
   from tbl_usuarios_conectados
   where dbname = @base_de_datos and hostname <> ' '
return
end

Fernando España

23 de julio de 2002

Verificar y Cerrar Tablas Una Linea

A veces, lo mas sencillo y elegante del código de VFP viene en una sola linea.

Usualmente, cuando tenemos que cerrar una tabla, vista o cursor de VFP antes verificamos que efectivamente dicha tabla esté abierta (para evitar el error 13 - No se encuentra el Alias -), con un código como este:
IF USED("MiTabla")
     USE IN "Mitabla"
ENDIF

Puede ser sustituido por:
USE IN (SELECT("MiTabla"))

Esta información la encontré revisando en los foros de microsoft.public.fox.vfp.language-menus (09/Julio/2002) lo cual me pareció bastante interesante y quisiera compartir.


Louis, mientras esperas para una solución a tu problema, aqui esta una pequeña joya para ahorrar algo de código:

*!* CREATE CURSOR Test (Field1 C(10))
*!* SELECT 0    && Note que Test no esta en el area de trabajo actual
*!* Cerrar Test en una sola linea de código
USE IN (SELECT("Test"))
*!* OtroTest no existe, no ocurre error!
USE IN (SELECT("OtroTest"))

Si Test existe este será seleccionado y cerrado. Si Test no existe se seleccionará y cerrará el área 0, lo cual, no produce error alguno.

Cindy Winegarden MCSD, Microsoft Visual FoxPro MVP
cindy.winegarden@mvps.org http://cindywinegarden.adsl.duke.edu



Espero les sea de utilidad.

Espartaco Palma Martinez

15 de julio de 2002

COM+ con VFP 7.0 - Parte 1

Publicado originalmente en FoxTalk.
Traducción de Jorge Espinosa.


Cuando COM+ debutó en Windows 2000, introdujo varias nuevas capacidades para mejorar las aplicaciones en n-capas. Ahora con VFP 7, puede usar estas mejoras para hacer sus aplicaciones más robustas. En esta primera parte, Craig Berntson hace una revisión acerca de COMMTS para después introducirnos en COM+.

Introducción a COM+

Por muchos años hemos escuchado acerca de la importancia de separar las aplicaciones en múltiples capas o servicios. Mediante la separación de la interfaz de usuario, las reglas de negocios y el acceso a datos, podemos fácilmente modificar o reemplazar completamente un servicio sin afectar a los demás.

Históricamente, las soluciones desarrolladas en Visual FoxPro han sido soluciones de una sola capa, aún si la base de datos residiera en un servidor externo. Esto es así porque los desarrolladores mezclaban la interfaz de usuario, las reglas de negocio y el acceso a datos dentro de una aplicación o aun más, en el mismo formulario.

Con la aparición y uso de SQL Server, hemos arribado a un escenario de dos capas. El dato es accedido normalmente vía ODBC, ya sea, a través de Vistas Remotas o SQL Pass Trough. Los Stored Procedures son a menudo ejecutados sobre el Server, y la sentencia SQL Select es resuelta del lado del servidor antes de enviar el resultado a través del cable. Esta separación del proceso dentro del servidor y las estaciones de trabajo, es lo que hace de esto un diseño en dos capas.
En una solución de tres capas, la interfaz de usuario solamente muestra datos y acepta ingresos de parte de los usuarios. Puede llegar a tener alguna validación menor, como el chequeo de que el usuario haya llenado los campos requeridos o la limitación de ingresos a través de un combo box. Mientras que todos los procesos de datos deben tener lugar en un componente separado que contenga todas las reglas de negocio. Cálculos de totales o tasas, validación de datos o la generación de reportes son ejemplos de lógica de negocios que deben estar encerrados en la capa intermedia. Finalmente, la tercer capa es responsable de la lectura y escritura dentro del repositorio de datos. La interfaz de usuario nunca debe tener acceso directo al repositorio de datos, debe llevar adelante esto a través de la capa de negocios para que esta haga el pedido al servidor de datos.

La separación de múltiples capas es lo que Microsoft ha nombrado como Distributed interNetworking Architecture o DNA. Los diferentes componentes de cada servicio pueden residir en una misma máquina, haciendo una separación lógica de cada servicio o en múltiples máquinas llevando adelante así una separación física de cada capa. Típicamente, la interfaz de usuario reside en una computadora cliente, mientras que los componentes de negocios y acceso a datos residen en un servidor de aplicaciones, y el repositorio de datos en un segundo servidor. Cuando el acceso es vía Web, un servidor adicional para IIS (Internet Information Server).

La vía para el acceso a estos componentes se realiza a través de Component Objetc ModelCOM es la especificación que permite escribir componentes en diferentes lenguajes y que estos interactúen con cualquier otro. Por lo tanto, nosotros podemos crear componentes en VFPque pueden ser accedidos desde aplicaciones desarrolladas en VB o Delphi, así como también desde Word o Excel. Los controles ActiveX son un ejemplo de un objeto COM. Cuando usted controla Word o Excel desde su aplicación VFP, lo esta haciendo vía COM.

Lo primero a considerar cuando se va a crear un componente COM, es como este va a encajar con las demás partes de su aplicación. En otras palabras, usted necesita determinar si este será un objeto que correrá in-process o out-of-process.

Un componente in-process es compilado como una DLL y debe ser llamada por un programa ejecutable. Este corre en el mismo espacio de memoria de la aplicación -de allí su nombre in-process- lo que hace que la instanciación del mismo sea más rápida. El dato es enviado a través de COM. Como el componente corre en el mismo espacio de memoria que la aplicación, si este falla es muy probable que cause un fallo también en la aplicación. Otro dato a tener en cuenta, los servidores in-process escritos en VFP no pueden exponer ninguna interfaz de usuario.

Un servidor out-of-process es compilado como un EXE y corre en su propio espacio de memoria. Cuando este es instanciado, requiere de mas carga de trabajo, como la asignación de memoria, process id, etc. Esto lleva tiempo, lo que hace que el método del out-of-process sea bastante mas lento que el de in-process. Además es mas pesado el manejo de datos entre los componentes y la aplicación, por lo tanto es más lenta su ejecución. Por otro lado, al estar el componente corriendo en un espacio separado de memoria, si este fallara, la aplicación no sería alcanzada por este error y probablemente se mantuviera corriendo.

Creación de un componente COM

La creación de un componente COM en Visual FoxPro es muy fácil. La palabra clave OLEPUBLIC en la creación de una clase, le dice a VFPque compile el código con la información COM necesaria para poder ser accedido desde otras aplicaciones.

Ejemplo:
DEFINE CLASS Math AS SESSION OLEPUBLIC
FUNCTION Multiply(tnNum1, tnNum2)
LOCAL lnResult
lnResult = tnNum1*tnNum2
RETURN lnResult
ENDFUNC
ENDDEFINE
Cuando usted crea el componente (Figura 1), puede elegir "Win32 executable/COM Server(exe)" para crear un componente out-of-process. Para crear un componente in-process, seleccione "Single-Threaded COM server (dll)" o "Muti-threaded COM server (dll)". Veremos mas acerca de la diferencia entre estos dos tipos de DLLs mas adelante. El componente quedará automáticamente registrado después de la compilación del mismo; de esta forma podrá instanciar el mismo mediante la función CREATEOBJECT().


Figura 1.

Ejemplo:
ox=CREATEOBJECT("MyProject.Math")
? ox.Multiply(3,4) && Retornara 12
ox=NULL
Muchas de las reglas de COM son automáticamente manejadas por VFP. Sin embargo, debemos seguir una regla manualmente. Esta regla define que nunca debemos cambiar la interfaz de un componente. Si lo hacemos, necesitaremos crear un nuevo ID para el componente. Por interfaz, no debemos entender que nos referimos a interfaz de usuario, sino a los métodos públicos y parámetros del componente. Veamos esto sobre el ejemplo anterior. Si agregáramos un tercer parámetro al método Multiply, cambiaríamos la interfaz del componente y necesitaríamos generar un nuevo ID para el mismo. Esto lo podemos hacer desde el cuadro de diálogo Build. La última opción en el cuadro de diálogo es "Regenerate Component Ids". Marcando esta opción se genera una nueva interfaz para el componente.

Cuando comienza un desarrollo de componente COM que se ejecute en un servidor remoto, usted debe tener en cuenta que el acceso a este servicio lo hará a través de Distributed COM (DCOM). Históricamente, en DCOM, usted distribuía un servidor del tipo out-of-process y seteaba la información de acceso al mismo desde la computadora cliente. El capitulo 16 de la Guía del Programador de Visual FoxProdetalla como llevar adelante este procedimiento. Cuando se instala el componente en un servidor remoto, el código se ejecuta del lado del servidor, no en el cliente. Es importante tener en cuenta no poner ningún tipo de interfaz gráfica de usuario en el código del componente, ya que esta se ejecutará en el servidor y no en la terminal del cliente.

MTS

Microsoft vio la necesidad de tener una mejor vía para ejecutar componentes remotos, entonces fue creado Microsoft Transaction Server (MTS). Originalmente disponible para Windows NT y Windows 9x a través de NT 4.0 Option Pack, MTS resolvió varios problemas ofreciendo un servidor para componentes COM DLLs. Este proveía un asistente para realizar la configuración de los componentes DCOMllamados desde el cliente por usted. Algunas otras características de MTS son:
  • Just-In.Time Activation: El componente permanece guardado en el disco y es cargado en memoria y activado solo cuando se necesita.
  • Object Request Broker (ORB): MTS puede manejar múltiples llamadas al mismo componente desde múltiples clientes.
  • Transaction Services: Commit y Aborts son manejados por el Distributed Transaction Coordinator (DTC) de la aplicación. Este hace posible tener transacciones que involucren a múltiples bases de datos.
  • Role-based Security: El esquema de seguridad le permite determinar quien puede acceder sus componentes basado en los logins y grupos de NT. Si un usuario no tiene autorización para acceder un componente, un mensaje de error retornará al cliente indicando que el componente no pudo ser instanciado.
  • Connection Pooling: Típicamente, una aplicación hace una conexión al repositorio de datos y la mantiene viva mientras la aplicación esté ejecutando. MTS permite a múltiples clientes utilizar una misma conexión.
La creación de componentes para el uso sobre MTS requiere que usted cambie el pensamiento a la hora del diseño de sus aplicaciones. Primero, su aplicación debe mantenerse libre de estado (stateless). Esto significa que su programa cliente, debe instanciar el componente, hacer la llamada a los métodos y liberar el componente. La conexión al componente debe ser del menor tiempo posible. Usted debe evitar el seteo de propiedades y pasar toda la información necesaria como parámetros. Tenga en cuenta que COM no permite a los parámetros ser pasados en el método INIT.

Usted también necesita pensar en base a la ejecución por hilos (threading). Típicamente pensamos acerca de la ejecución de un sistema como single o multi-threadingVFP solo genera aplicaciones single-threading. Esto significa que solo corre un proceso por vez. Esto es como ir al mercado y solo tener una caja abierta. Todos los clientes deben pasar a través de la misma caja. Solo un cliente a la vez puede ser atendido. Los demás deberán esperar en la cola para poder ser atendidos.
Multi-thread permite a sus aplicaciones separarse para ser procesadas por partes, corriendo todas al mismo tiempo. Tomando el ejemplo del mercado, usted podría descargar partes de su carrito de compras en diferentes cajas y que todos sus artículos comprados sean procesados al mismo tiempo.
MTS utiliza un tercer tipo de threading, apartment model. Tomando nuevamente el ejemplo del mercado, los clientes pueden elegir entre cualquiera de las cajas abiertas, pero solo puede elegir una y siempre deberá usar la misma. Afortunadamente MTS abrirá una nueva línea para usted si todas están en uso.

Entonces, ¿cómo hacemos uso de MTS en nuestros componentes VFP?. Primero, debemos agregar algo de código. Vamos a modificar el código de nuestro ejemplo Multiply para manejar MTS.
DEFINE CLASS Math AS SESSION OLEPUBLIC
FUNCTION Multiply(tnNum1, tnNum2)
LOCAL lnResult, loMtx, loContext 
*Creamos una referencia al Objeto MTS
loMtx=CREATEOBJECT("MTXAS.APPSERVER.1")  
*Creamos la ref. al Contexto
loContext=loMtx.GetObjectContext()
lnResult=tnNum1*tnNum2
*Si hay alguna transacción abierta hacemos el Commit y avisamos al MTS
*que terminamos de usar el objeto.
loContext.SetComplete()
RETURN lnResult
ENDFUNC
ENDDEFINE
El objeto de contexto contiene información acerca de nuestra instancia en particular de nuestro componente COM. También, observe la llamada a SetComplete(). Esto hará un commit de cualquier transacción abierta que exista. Si necesitamos abortar la transacción, deberemos hacer una llamada a SetAbort().

Cuando generamos nuestros componentes, no podremos usar la opción "Win32 executable/COM server (exe)"MTS requiere que los componentes sean .DLLs. Esto nos deja dos opciones: single o multi-threaded.

La DLL single-thread es una buena opción cuando el método a llamar sea verdaderamente rápido o cuando un solo usuario tenga la posibilidad de llamarlo.

La DLL multi-threaded en realidad no es multi-threaded, es un Apartment Model Threaded. Tome esta opción cuando el método sea lento o cuando muchos usuarios vayan a hacer uso de este simultáneamente.

Una vez que haya creado el componente, instálelo en el servidor con las correspondientes bibliotecas. Entonces, debe proceder a crear el paquete MTS e importar su componente usando el MTS Explorer. Utilizando el MTS Explorer, puede configurar la seguridad y soporte transaccional, también generar el programa de instalación cliente.

Windows 2000

Cuando Microsoft introdujo Windows 2000, este vino con muchos servicios nuevos. Uno de estos es COM+. Básicamente, COM+ es la conjunción de COM y MTS, pero además COM+ introdujo nuevas características. Sobre Windows NTMTS corre sobre el sistema operativo. Sobre Windows 2000, este se encuentra integrado al sistema operativo. COM+ se encuentra disponible solamente en Windows 2000. Mientras que, los usuarios de Windows 95, 98, ME y NT pueden usar componentes COM+ corriendo en un servidor Windows 2000COM+, no solamente incluye (y mejora) las características de MTS sino que agrega nuevos servicios como: Queued Components (QC), Loosely Coupled Events (LCE), Object Pooling, y Dynamic Load Balancing. En adelante, iremos profundizando en detalle acerca de estos servicios.

Las aplicaciones COM+ son administradas a través del Component Services Manager (Figura 2). Puede encontrar esta en el grupo de programas Administrative Tools en el Windows Control Panel. Hagamos los pasos para ver que fácil es la registración de un componente.


Figura 2: Component Services Manager.

1.- Expandir el árbol debajo de Component Services hasta tener disponible COM+ Applications.
2.- Clic sobre COM+ Applications para seleccionar el nodo, y clic con botón secundario sobre COM+ Applications.
3.- En el menú contextual, seleccione New Application para lanzar el asistente de COM Applications. Presione el botón Next.
4.- Clic en la opción "Create an empty Application" (Figura 3)


Figura 3.
5.- Ingrese el nombre de su aplicación. En el ejemplo lo hemos nombrado MyFirstCOMApp. Seleccione el tipo de activación; normalmente usted seleccionará Server Application debido a que su componente correrá sobre el servidor. Si desea instalar el componente en una terminal y correrlo en el espacio de memoria de su aplicación, entonces seleccione Library Application (Figura 4). Seleccione Next.


Figura 4.
6.- Seleccione el ID de usuario con el cual el componente correrá. Cuando instale el componente sobre un servidor, es una buena práctica crear un usuario específicamente para instanciar sus componentes. Asegúrese de asignar a este los derechos necesarios, como por ejemplo que pueda tener acceso a todos los discos, directorios y recursos que pueda necesitar (Figura 5). Clic Next para finalizar.


Figura 5.

Ahora tenemos la aplicación instalada, pero todavía no contiene ningún componente. Debemos agregar el componente a la aplicación.

1.- Clic en el signo + en nuestra nueva COM+ Application para expandir el árbol.
2.- Clic derecho sobre Components. Seleccione New Component desde el menú contextual para lanzar el asistente de Component Install. Clic en Next.
3.- El asistente le ofrece tres opciones: Install New Component, Import Component(s) that are already registered, o Install new event class(es). Nosotros tomaremos la tercera opción cuando hablemos acerca de "Loosely Coupled Events". La segunda opción,Import Component(s) that are already registered, es utilizada cuando se tiene el componente previamente instalado en la maquina. Esta opción no es recomendable ya que en su momento tuvo un bug de Windows 2000 que no funcionaba correctamente. Lo que nos deja la opción 1. Clic en el botón Next para esta opción (ver Figura 6)


Figura 6.
4.- Seguidamente le solicitará seleccionar las DLLs a instalar. Si no tiene el runtime de VFP instalado no podrá seleccionar e instalar su componente (Figura 7). Una vez que haya seleccionado su componente, clic Next para finalizar.


Figura 7.

¿Ahora que su componente está instalado, como lo accede?. De la misma manera que lo hacia antes. Utilizando CREATEOBJECT() para instanciar el componente ¡y listo!

Craig Berntson es Microsoft Certified Solution Developer y fue nombrado cuatro veces Microsoft Most Valuable Profesional. Disertante de varias conferencias de FoxPro en todo EEUU y eventos de Microsoft en Salt Lake. Es Presidente del Salt Lake City Fox Users Group y actualmente ingeniero de software senior para 3m Health Information Systems.
Jorge A. Espinosa, Buenos Aires (Capital Federal), Argentina, es Analista Programador y MCP. Dedicado al desarrollo de sistemas desktop desde el año 1987; siempre en el entorno xBase y en Visual Fox Pro desde la version 3.0. Hoy Gerente de Sistemas en Droguería Saporiti SACIFIA.