FoxPress – Diciembre 2004

 

      Mantenimiento navegacional de tabla simple con MySQL

 

 

Por la Redacción de Foxpress                                                                              mysql.zip

 

 

 

            Los mantenimientos son quizás una de las mejores herramientas para el aprendizaje y solventan algunos de los primeros problemas que se le suelen presentar al programador ‘nuevo’ en un lenguaje.

 

      En este caso va a ser un mantenimiento C/S Cliente/Servidor desde Fox contra MySQL mediante el uso de SQLExplícito.

 

            El mantenimiento contempla todas las opciones de añadir/borrar, etc...

 

            La estructura de la tabla con la que vamos a trabajar es la siguiente:

 

            articulos  CREATE TABLE `articulos`

(`ArticulosNombre` varchar(40) NOT NULL default '',

`ArticulosPrecio` decimal(10,0) NOT NULL default '0',

`ArticuloID` int(6) NOT NULL auto_increment,

PRIMARY KEY  (`ArticuloID`))

TYPE=MyISAM                                                                                                                                                                                                                     

 

 

El Movimiento Navegacional

 

            Para poder implementar los botones navegacionales (adelante, atrás, último, primero) se ha dotado a la tabla Artículos de MySQL de un campo auto_increment para dotar de un identificador único a cada registro.

 

            Para poder realizar los movimientos navegacionales se toma primero el valor del registro actual y se pide el siguiente/anterior/ultimo/primero.

 

            Para, por ejemplo, ver el siguiente registro se ha usado:

 

           SELECT * FROM articulos WHERE ArticuloID  > ((_Registro_Actual))  LIMIT 1

 

            Para poder ver el registro siguiente:

 

                SELECT * FROM articulos WHERE ArticuloID  > ((_Registro_Actual)) order by ;

ArticuloID Desc LIMIT 1

 

            Fijate la opción LIMIT 1 que hará que sólo nos traiga un registro.

 

Para poder ir al último es algo más sencillo:

 

SELECT ArticuloID, ArticulosNombre,ArticulosPrecio FROM articulos Order by ;

ArticuloID DESC Limit 1

 

Las Conexiones

 

            Para las conexiones tenemos diversas opciones como son que cada vez que hacemos una operación nos conectamos/desconectamos lo que tendría una penalización de tiempo o al abrir, en este caso, el formulario conectarse y al cerrarlo desconectarse. El handle de la conexión lo guardo en una propiedad con lo que lo tenemos siempre disponible en todas nuestras operaciones.

 

            El código que se usa es el siguiente que está en el INIT de la Clase Base del Formulario:

 

Wait Wind "conectándose..." NOWAIT

This.nHandle = SQLCONN('mante','root','')

 

*- Comprobamos la Conexión

 

IF This.nHandle > 0

  Wait Wind "conectados..." TIME 0.01

Else

   =MESSAGEBOX("Error al Conectar",16,"Atención")

   RETURN

ENDIF

 

El Inicio

 

Entiendo por inicio, las operaciones que realiza el formulario nada más iniciarse. Lo primero que hace usando el código anterior es conectarse al servidor.

 

Una vez conectado se trae el primer registro de la Base de Datos. En buen puridad es un poco absurdo siempre traerse el primer registro al conectarse, pero de cara al ejemplo puede ser instructivo. Por eso en el INIT pongo el siguiente código:

 

DODEFAULT()

 

SQLEXEC(This.nHandle,'SELECT * FROM articulos Order by ArticuloID LIMIT 1','miCursor')

 

This.miText1.controlsource = 'miCursor.ArticuloID'

This.miText2.controlsource = 'miCursor.ArticulosNombre'

This.miText3.controlsource = 'miCursor.ArticulosPrecio'

 

Como se ve nos traemos un registro que queda guardado en un cursor llamado miCursor. A continuación para cada uno de los TextBox que tengo en el Formulario le asigno el controlsource correspondiente y con esto ya habríamos conseguido traernos el primer registro y mostrarlo.

 

 

Modificaciones de Registros

 

            La modificación de los registros conlleva dos problemas: en primer lugar la propia modificación en el servidor del dato pero además, el interfaz ha de detectar que se ha producido un cambio en un registro y entonces tiene que cambiarlo.

 

            La primera parte es un mero update que basado en la referencia del artículo (en este caso el Identity) realiza la modificación correspondiente. El código es algo parecido a esto:

 

IF Thisform.lmodificado

 

       lcArticulosNombre = Alltrim(Thisform.miText2.value)

       lcArticulosPrecio = alltrim(str(Thisform.miText3.value))

       lcCadena = "UPDATE Articulos SET aRTICULOSPRECIO = " + LCaRTICULOSPrecio

       lcCadena = lcCadena + " ,ArticulosNombre= '" + alltrim(lcArticulosNombre)

       lcCadena = lcCadena + "' where ArticuloID=" + alltrim(str(Thisform.miText1.Value))

 

       lnREsultado = SQLEXEC(Thisform.nHandle,lcCadena)

       select miCursor

       TAbleupdate(.T.)

ENDIF

 

            Coge los datos de los campos, construye una cadena SQL y la ejecuta. Pero observa como es necesario realizar un tableupdate para que el interfaz no nos diga que hay cambios pendientes de grabación.

 

            Tan pronto esta función detecta que hay registros con un campo cambiado el valor de This.lmodificado se pone a .T. y entonces el refresh hace que se desactiven todos los botones dejando únicamente activos los botones de guardar o deshacer los cambios. El código que hay puesto en el Refresh es el siguiente:

 

*- Si está en modo nuevo, ó ya está modificado ó hay alguna modificación

If this.lNuevo .OR. this.lmodificado OR this.modificado()

       With This

              .cmdNuevo.Enabled = .F.

              .cmdGuardar.Enabled = .T.

              .cmdBorrar.Enabled = .F.

              .cmdDeshacer.Enabled = .T.

              .cmdPrimero.Enabled = .F.

              .cmdAnterior.Enabled = .F.

              .cmdSiguiente.Enabled = .F.

              .cmdUltimo.Enabled = .F.

              .cmdSalir.Enabled = .F.

       EndWith             

Else

       With This

              .cmdNuevo.Enabled = .T.

              .cmdGuardar.Enabled = .F.

              .cmdBorrar.Enabled = .T.

              .cmdDeshacer.Enabled = .F.

              .cmdPrimero.Enabled = .T.

              .cmdAnterior.Enabled = .T.

              .cmdSiguiente.Enabled = .T.

              .cmdUltimo.Enabled = .T.

              .cmdSalir.Enabled = .T.

       EndWith

EndIf

 

Por último para el caso de que el usuario intente salir del formulario sin hacer caso de los botones pulsando en las aspas del formulario tenemos el método QueryUnload que se dispara en esos casos y este código nos forzará a realizar los cambios o detectarlos:

 

IF this.lNuevo .OR. this.lmodificado

    Thisform.confirmar()

ENDIF

 

El método confirmar nos invoca un messagebox y según eso se graba o se descarta el cambio:

 

LOCAL lnResp, lResult

 

lResult = .F.

lnResp = MessageBox("Los datos han sido modificados."+chr(10)+" ¿Desea guardar los cambios?",4+32,"Aviso")

If lnResp = 6

       lResult = thisform.cmdGuardar.click()

Else

       lResult = thisform.cmdDeshacer.click()

EndIf

Return lResult

 

Como siempre, lo mejor es mirar y ejecutar el fuente.

 

 

FoxPress – Diciembre de 2004

© 2004 FoxPress. All rights reserved