Post on 25-Jul-2015
Ing. Russvell Jesús Soto Gamarra
Asesor de Computación y Sistemas
San Juan del Rio, Querétaro - México
Tel. Oficina.: 1(427)2746184
Tel. Celular.: 1(427)109996
Email.: rycjesusrj@hotmail.com
Framework para Visual FoxPro, Utiliza SQLServer,
MySQL, PostgreSQL y Oracle como su Motor de Base
de Datos.
Por medio de la presente quiero hacerles llegar mis más
cordiales saludos y a la ves darles a conocer de mi nueva versión
Framework para Visual Fox Pro, Totalmente fácil y
sencillo.
Somos muchos los programadores que hemos venido
desarrollando aplicación con la base nativa de Visual FoxPro; a mi
particularmente nunca me gusto Visual FoxPro como motor de
base de datos ya que es limitado pero como interfaz de usuario
es excelente, si uno quiere orientarse a realizar aplicación remotas
o de entorno web es allí donde surgen los inconvenientes de
limitación, no se si este equivocado pero eso es mi punto de
vista.
La gran interrogante a todo esto es. Si migro mi base de datos
de VFP a otro motor de base de datos como (SQLServer, MySQL,
PostgreSQL y Oracle), tendré que cambiar la forma de
programar, déjame decirte que no lo harás. Porque he
desarrollado un Framework que permite trabajar con cualquier
base de datos, lo más importante es que no vas a tener que
modificar ni una línea de tu código.
La nueva versión no ha cambio a simple vista. El Framework trae
muchas mejoras, entre una de ellas y la que más interesa a todos
los desarrolladores es el control de la desconexión a la base de
datos, el motivo puede ser como la falla de la red interna o si se
está trabajando remotamente la caída del internet. El Framework
intentara conectarse en hasta en 3 intentos, de esta manera
impediremos que el usuario pierda la información y/o el proceso
que esta realizando.
Bueno se ha creado 8 propiedades fundamentales y un método
que hay que tener en cuenta
PROPIEDADES:
- UTILIZARTRANSA
Valor ha utilizar .T. o .F.; Si el valor es .T., se abre la
transacción en Visual FoxPro y en el motor de la base de
datos, cuando se utiliza el método SQLCOMANDO.
Inicialmente la propiedad esta en .F.
- CLAVE PRIMARIA
Aquí ponemos la llave primaria de nuestra tabla que
queremos trabajar o el campo que hará referencia para la
actualización de los datos.
- VALIDACAMPOTABLASQL
Valor ha utilizar .T. o .F.; Compara la tabla del SQL con el
cursor que se ha utilizado. Ejemplo si tengo un cursor con
más campos de la tabla principal solo toma los campos que
corresponde a la tabla que se quiere actualizar.
- VALIDAIMG
Valor ha utilizar .T. o .F.; Si la tabla tiene imágenes, esto es
muy importante para MySQL y PostgreSQL.
- VALIDARFECHA
Valor a utilizar .T. o .F.; Cuando queremos guardar fechas
vacía en MySQL no permite enviar error como si
estuviéramos mandando valores .null. a un campo de tipo
fecha, pero para SQL Server no hay problema.
- LGENERARCADENASQL
Valor a utilizar .T. o .F. Esta propiedad ayudar a que el FW
sea más rápido o lento si la propiedad esta en .T., el FW
armara la cadena SQL registro por registro; si esta en .F. el
FW solo armara la cadena SQL una sola vez así existan 100
o más registro en la tabla al momento que se desea
guardar.
- LVALNSTATUS
Valor a utilizar .T. o .F. Esta propiedad esta propiedad nos
ayudara a mejorar el armado de la cadena SQL ya que si nosotros
queremos podemos mandar todas las columnas de la tabla que
tenemos denominado cursor a la tabla SQL que deseamos
actualizar si esta en .F. pero si esta en .T. solo envía los campos
que se usan en el cursor. Esto sucede cuando se hace un insert o
update.
- OTHERCN
Esta propiedad nos ayudara a trabajar con diferentes
conexiones simultáneamente en un formulario o ambiente de
trabajo, si la propiedad OTHERCN está vacía, el framework
trabajara con la conexión por defecto que es la varia CN.
Ejemplo:
Para poder usar tenemos que crear conexiones a diferente base
de datos como veremos en el siguiente código MySQL FUNCTION RECONECCION &&conexion predeterminada para el framework CN=SQLSTRINGCONNECT( "DRIVER={MySQL ODBC 3.51 Driver};OPTION=0;SERVER=localhost;UID=root;PWD=1234 56;DATABASE=malkasoftadpi;PORT=3306;" ) RETURN CN ENDFUNC FUNCTION OTHERCN &&otra conexion que deseamos realizar OCN=SQLSTRINGCONNECT( "DRIVER={MySQL ODBC 3.51 Driver};OPTION=0;SERVER=localhost;UID=root;PWD=1234 56;DATABASE=digital;PORT=3306;" ) RETURN OCN ENDFUNC
Es importante declarar las variables públicas en nuestro sistema
principal. PUBLIC CN, OCN SET PROCEDURE TO funciones . prg CN = RECONECCION() &&Conexión predeterminada IF CN<1 MESSAGEBOX( "Fallo de conexion con el servidor" , 16, "Error..." ) ENDIF OCN=OTHERCN() &&otra conexion IF OCN<1 MESSAGEBOX( "Fallo de conexion con el servidor en la segunda ba se de datos" , 16, "Error..." ) ENDIF
Forma de usarlo &&POR DEFECTO Thisform . sqlconector1 . execute ( "SELECT * FROM TbTabla" , "TmpTabla" ) &&OTRA CONEXION Thisform . sqlconector1 . othercn = "OCN" Thisform . sqlconector1 . execute ( "SELECT * FROM horarios" , "TmpOCNHorario" ) Thisform . sqlconector1 . othercn = ""
Nota: Al usar otra conexión es preferible dejarla vacía la propiedad othercn para
que el framewrok trabaja con la conexión por defecto, sin la necesidad de
volver a nómbralo.
MÉTODO:
- SQLCOMANDO
Sus parámetros (cAccion, cTablaSqlCur, cTablaSql,
CondUpdate) cAccion = “N” nuevo; “A” Actualiza; “E” Eliminar.
Thisform.sqlconector1.Execute(”Select * from Tabla
”,”TablaCursor”); el segundo parámetro es el nombre del cursor y
se le puede dar el nombre que mejor haga referencia a nuestra
tabla SQL.
Ahora veremos como funciona el Framework. Tratare de ser lo
mas explicito posible, para que ustedes lo puedan aplicar en su
sistema de la manera sencilla y fácil. Quiero remarcar que la
idea de todo esto es no modificar el código de nuestros
Sistemas.
Las tablas que utilizaremos para nuestro ejemplo son las
siguientes
- CabeceraDoc
- DetalleDoc
- Productos
Antes de comenzar quiero recordarles que cuando utilizamos
nuestros controles (TextBox, ComboBox, ListBox, Etc). En el la
propiedad ControlSource va en lazado la tabla y el campo.
CabeceraDoc
NumeroDoc Fecha CodCli CodVen FPago Total
En el Load de formulario cargamos nuestro cursor, que vamos a
trabajar
Thisform.sqlconector1.Execute(“Select * From
CabeceraDoc”,”TmpCabecerado”)
Si lo quieren hacer más interesante podemos manejar los buffer
de almacenamiento de la siguiente manera.
CURSORSETPROP("Buffering",5," TmpCabecerado")
Agregar un nuevo Registro.
Botón Nuevo.
Select TmpCabecerado
APPEND BLANK
Después que hacer todo nuestro proceso y de escribir los valores
correspondientes en nuestros controles. Pasamos a guardarlo
Botón Grabar.
Select TmpCabecerado
=TABLEUPDATE(.T.)
Thisform.sqlconector1.Validarfecha = .T. &&Valido la fecha si no se
escribo nada
Thisform.sqlconector1.sqlcomando(“N”,”TmpCabecerado”,”Cabecer
aDoc”)
Botón Eliminar.
Primer paso cuando uno quiere eliminar un registro es ubicarse
en la posición del registro que se desea eliminar.
Select TmpCabecerado
Delete
Thisform.sqlconector1.cLlavePrimaria = “NumeroDoc”
Thisform.sqlconector1.sqlcomando(“E”,”TmpCabecerado”,”Cabecer
aDoc”)
Como pueden observar todo el código es de VFP no hay nada
nuevo y de seguro mucho de ustedes lo tienen así.
En este ejemplo veremos como se utiliza la propiedad
validacampotablasql, y como guardamos nuestro detalle.
DetalleDoc
NumeroDoc CodProd Cantidad Precio Importe
Producto
CodProd Descripcion Unidad Stock PCosto StockMin
Nota: los nombres de las tablas pueden ser diferente y los
campos pueden ser mucho más o diferentes solo lo utilice para el
ejemplo. Hay muchas formas de determinar nuestras tablas y que
campos deben llevar cada uno de ellos, a si que todo es valido
según que sistema queramos desarrollar.
Consultando nuestra tabla y poder mostrarlo en nuestra
Grilla y darles una presentación a nuestros usuarios.
Thisform.Execute(“Select d.*, p.Descripcion, p.Unidad From
DetalleDoc d Inner Join Productos p On d.CodPro = p.CodPro
”,”TmpDetalle”)
Nuestra nueva tabla quedaría de la siguiente manera.
TmpDetalle
Numero
Doc
CodPr
od
Descripci
on
Cantid
ad
Preci
o
Unid
ad
Preci
o
Impor
te
Aquí vemos que no todo los campos pertenecen a la tabla
DetalleDoc, particularmente nunca la descripción del producto o
algunos campos en mi tabla detalle, ya que todo eso lo tengo en
la tabla maestra Producto, por forma de normalización no puedo
repetir datos en mi base de datos en mas de dos tablas.
Botón Agregar Detalle
Select TmpCabecerado
APPEND BLANK
Quiero aclara que hay varias cosas que hacer aquí, para obtener
el producto con una busqueda o ya sea la forma de llenado con
un insert into o un appen blank la forma como se programa no
me voy a centrar ahí. Continuando guardamos el número del
documento que hemos creado
Replace NumDoc With Thisform.TxtNumeroDoc.Value
Así agregamos las líneas que necesitamos para nuestro detalle.
Ahora nuestro Botón Guardar quedaría de la siguiente manera.
Botón Grabar.
&&Guardando la cabecera
Select TmpCabecerado
=TABLEUPDATE(.T.)
Thisform.sqlconector1.Validarfecha = .T. &&Valido la fecha si no se
escribo nada
Thisform.sqlconector1.sqlcomando(“N”,”TmpCabecerado”,”Cabecer
aDoc”)
&&Guardando el Detalle
Thisform. sqlconector1.Validacampotablasql = .T. &&Verifico si los
campos son iguales
Select TmpDetalle
Scan TmpDetalle.cantidad >0 && me aseguro que tenga cantidad
= Thisform.sqlconector1.sqlcomando(“N”,” TmpDetalle”,”
DetalleDoc”)
Endscan
Para la actualización de los registro seria todo igual, con la única
diferencia que esta vez debemos de determinar quien es la llave
principal y poder hacer los cambios sobre ello.
Thisform.sqlconector1.cllaveprimaria = “NumeroDoc”
Thisform.sqlconector1.sqlcomando
(“A”,”TmpCabecerado”,”CabeceraDoc”)
El Framework no tiene limitación cuando se quiere utilizar para
inserte y/o actualizar registro de una tabla. Ejemplo para insertar
campos a una tabla.
Select TablaVFP
Go Top
Scan
Thisform.sqlconector1.sqlcomando(“N”,”TablaVFP”,”TablaSQL
Almacenar”)
EndScan
Nota: CondUpdate se utiliza si quiero seguir restringiendo la
actualización.
También se tiene que tomar en cuenta, si se utiliza el Framework
para la actualización de los datos forzosamente tiene que declarar
un campo como llave primaria, teniendo en cuenta que este
campo sea o no llave primaria en su tabla.
Ejemplo:
Thisform.sqlconector1.sqlcomando
(“A”,”TmpCabecerado”,”CabeceraDoc”,” CodCli=’RUSS’ ”)
La verdad que no van a cambiar nada de sus código todo será
igual, espero estar en contacto con ustedes y poder ayudarles a
los interesados. Me pueden contactar en el siguiente correo
rycjesusrj@hotmail.com
Migrar Datos a de la Base de Datos de Visual Fox Pro a
MySQL
Otro punto que quiero aclarar, he visto en las paginas web a
terceros que ofrecen programas para migrar de VFP a SQLServer,
pero déjeme decirle que eso no es necesario porque el mismo
SQLServer te permite hacer la migración y se que muchos de
ustedes lo saben. Lo no pude migrar la data de VFP a Mysql es
utilizando las propias herramientas de mysql. Para ello he
desarrollado un software que permite migrar con mucha facilidad.
Puedes obtener un demo de la siguiente dirección.
Espero haber sido lo mas explicito posible. Críticas sugerencias
serán bien recibidas y aquellos que quieran dar mayor énfasis al
tema, podemos hacer algo diferente.
VEREMOS UN JEMPLO CLASICO DE MANTENIMIENTO
Parte de Presentación de Datos.
Entrada de Datos.
El Botón Nuevo
El Botón Cancelar
El Botón Grabar
El Botón Editar
El Botón Eliminar