Ejemplo de Guardar con FoxyDB para MariaDb (Mysql)

1,483 views
Skip to first unread message

Antonio Meza

unread,
Oct 11, 2017, 12:44:15 PM10/11/17
to Comunidad de Visual Foxpro en Español
Me han estado consultando en privado y por aquí como trabajar con FoxyDb, espero les sirva y sea atendible, si no comentan las dudas y sobre este tema las resolvernos y así quede historial para que sirva a todos.

También se puede usar con FireBird solo que hay que tener cuidado con la sintaxis SQL que no es igual en Firebird y MariaDb por ejemplo IFNULL()

Creo que este es uno de los ejemplos mas completos, sencillo pero completo, lo escribí a la viva México!!, es decir puede haber errores de dedo!!! jajajaj


* Consultas Sql
* Facturas (Cursor Vacio)
TEXT TO _sql_facturas TEXTMERGE PRETEXT 7 NOSHOW
SELECT 
    , facturas.idcliente
    , facturas.idmoneda
  , facturas.serie
  , facturas.folio
  , facturas.fecha
  , clientes.cliente
  , monedas.moneda
from facturas
inner join clientes
ON facturas.idcliente = clientes.id
inner join monedas
ON facturas.idmoneda = monedas.id
where 2 = 1
ENDTEXT

* Detalles de Facturas (Cursor Vacio)
TEXT TO _sql_facturas_detalles TEXTMERGE PRETEXT 7 NOSHOW
SELECT 
    , facturas_detalles.idfactura
    , facturas_detalles.idconcepto
    , facturas_detalles.cantidad
  , facturas_detalles.descripcion
  , facturas_detalles.precio_unitario
  , facturas_detalles.descuento
  , facturas_detalles.importe
  , ifnull(conceptos.concepto, '') as concepto
from facturas_detalles
left join conceptos
ON facturas_detalles.idconcepto = conceptos.id
where 2 = 1
ENDTEXT

* Observaciones de Facturas (Cursor Vacio)
TEXT TO _sql_facturas_observaciones TEXTMERGE PRETEXT 7 NOSHOW
SELECT 
    , facturas_observaciones.idfactura
    , facturas_observaciones.idprioridad
    , facturas_observaciones.observacion
    , facturas_observaciones.fecha
    , prioridades.prioridad
from facturas_observaciones
inner join prioridades
ON facturas_observaciones.idprioridad = prioridades.id
where 2 = 1
ENDTEXT

* Obtenemos los catalogo necesarios para el formulario
* Clientes
odb.Sql("Select * from clientes", "clientes")
* Monedas
odb.Sql("Select * from monedas", "monedas")
* Conceptos
odb.Sql("Select * from conceptos", "conceptos")
* prioridades
odb.Sql("Select * from prioridades", "prioridades")
* ect, etc.
* Nota: NUNCA usar Select *, lo pongo para ejemplo
* Obtenemos los cursores que seran administrados por FoxyDb
* tabla Principal
odb.Query(_sql_facturas, "facturas")
* Preparamos para editar
odb.CursorEdit("facturas")
* tabla Secundaria Detalles de Factura
odb.Query(_sql_facturas_detalles, "facturas_detalles")
* Preparamos para editar
odb.CursorEdit("facturas_detalles")
* tabla secundaria Observaciones de Factura
odb.Query(_sql_facturas_observaciones, "facturas_observaciones")
* Preparamos para editar
odb.CursorEdit("facturas_observaciones")
* Agregamos un Registro
* SELECT facturas
* APPEND BLANK
* Se puede usar Insert Into
INSERT INTO facturas (idcliente, cliente, idmoneda, moneda, fecha) ;
VALUES (clientes.id, clientes.cliente, monendas.id, monendas.moneda, DATE())
* Agregamos unas Observaciones
INSERT INTO facturas_observaciones (idfactura, idprioridad, observacion, fecha) ;
VALUES (facturas.id, prioridades.id, prioridades.prioridad, "Proforma de Factura", DATE())
INSERT INTO facturas_observaciones (idfactura, idprioridad, observacion, fecha) ;
VALUES (facturas.id, prioridades.id, prioridades.prioridad, "Faltan documentos", DATE())
* Agregamos Detalles de Facturas
INSERT INTO facturas_detalles (idfactura, idconcepto, concepto, cantidad, descripcion, precio_unitario, descuento, importe) ;
VALUES (facturas.id, conceptos.id, conceptos.concepto, 1, "Concepto Nuevo Uno", 0, 0, 0)
INSERT INTO facturas_detalles (idfactura, idconcepto, concepto, cantidad, descripcion, precio_unitario, descuento, importe) ;
VALUES (facturas.id, conceptos.id, conceptos.concepto, 1, "Concepto Nuevo Dos", 0, 0, 0)
INSERT INTO facturas_detalles (idfactura, idconcepto, concepto, cantidad, descripcion, precio_unitario, descuento, importe) ;
VALUES (facturas.id, conceptos.id, conceptos.concepto, 1, "Concepto Nuevo Tres", 0, 0, 0)
* Vamos a Guardar 
* Revisar si hay cambios en algún cursor
If odb.Changes()
  LOCAL _idRegistroNuevo as Integer, _hayCambios as Boolean, _errorSql as Boolean
  _idRegistroNuevo = 0
  _hayCambios = .f.
  _errorSql = .f.
  * Tabla Principal
       if odb.CursorChanges("facturas")
             _hayCambios = .t.
             * Obtener Folio unico de Factura
IF facturas.id = 0
              odb.Code("facturas_folios","folio")
              replace facturas.folio WITH PADL(odb.id_Code, 10, '0') IN facturas
              ENDIF
             IF odb.update(facturas, .t.)
             _idRegistroNuevo = odb.id_last
         ELSE
          * Hay un error
         _errorSql = .t.
         ENDIF
       ENDIF
  * Tabla de Detalles de Facturas
       if odb.CursorChanges("facturas_detalles") AND _errorSql = .f.
             _hayCambios = .t.
             * Verificar si es registro nuevo el Principal
                  IF _idRegistroNuevo <> 0
                      * Asignar Ultimo ID a los registros del detalle de facturas
                      replace facturas_detalles.idfactura WITH _idRegistroNuevo ALL IN facturas_detalles
                  ENDIF
             IF odb.update(facturas_detalles)
              * Vamos bien!!!
             ELSE
          * Hay un error
         _errorSql = .t.
             ENDIF
       ENDIF
  * Tabla de Observaciones de Facturas
       if odb.CursorChanges("facturas_observaciones") AND _errorSql = .f.
             _hayCambios = .t.
             * Verificar si es registro nuevo el Principal
                  IF _idRegistroNuevo <> 0
                      * Asignar Ultimo ID a los registros del detalle de facturas
                      replace facturas_observaciones.idfactura WITH _idRegistroNuevo ALL IN facturas_observaciones
                  ENDIF
             IF odb.update(facturas_observaciones)
              * Vamos bien!!!
             ELSE
          * Hay un error
         _errorSql = .t.
             ENDIF
       ENDIF

   * Guardar Cambios
    IF _errorSql = .t.
    * Algo salio mal
    odb.Rollback()
    ELSE
    * Veamos si hay cambios para guardar
       IF _hayCambios = .t.
           if odb.Commit()
               MessageBox("Perfecto!!, Datos Guardados")
           else
              odb.RollBack()
              MessageBox("No se pudieron guardar los datos")
           endif
       ENDIF
ENDIF
else
   * No se ha hecho ningún cambio
endif


Nota: Como pueden ver es muy fácil controlar un servidor de base de datos con FoxyDb sin hacer tanto código Manual, sin preocuparse de las transacciones, de obtener códigos únicos (correlativos), el manejo de los Autoincrementables, armar el código SQL para enviar al servidor, saber que tablas se modificaron, que registros cambiaron que campos cambiaron, si el campo pertenece o no a la tabla, etc, etc y otras yerbas mas jejej

saludos
Antonio Meza

Fernando Mauricio Romero Jones

unread,
Aug 6, 2019, 3:35:36 PM8/6/19
to Comunidad de Visual Foxpro en Español
Hola Antonio.
Estoy empezando a migrar las Tablas de VFP a MariaDB para un nuevo proyecto. Tengo poca experiencia en mariaDB.
Decidí utilizar tu librería de FOXYDB para la conexión y gestión de datos.
Puedo conectarme desde VFP a la tabla que cree en MDB.
Estaba tratando de hacer una rutina para pasar los datos de los clientes desde VFP a MDB siguiendo los pasos de esta rutina que publicaste hace un tiempo. Obviamente es más sencilla porque no tiene tablas madre-hija sino simplemente una madre.
Te copio un trozo de la rutina que estoy generando para tomar los datos:
    OPEN DATABASE .\DBFS\VFFLEBO.DBC SHARED
USE .\DBFS\afiliado IN 0 ALIAS Afiliado INDEX .\DBFS\Afiliado.CDX SHARED 
TEXT TO _sql_pacientes TEXTMERGE PRETEXT 7 NOSHOW
SELECT 
  pacientes.grupo
    , pacientes.nombre
    , pacientes.dircob
  , pacientes.codpos
  , pacientes.dirpart
from pacientes
ENDTEXT

* tabla Principal
odb.Query(_sql_pacientes, "sqlpacientes")
* Preparamos para editar
odb.CursorEdit("sqlpacientes") <---------------- ACA ESTÁ EL ERROR
SELECT afiliado
SCAN 
....
ENDSCAN

Te adjunto la imagen del error que me está dando cuando quiero utilizar .CursorEdit
Desde ya agradecido por cualquier sugerencia.

Fernando M. Romero
Santa Fe - Argentina
error_buffering.png

Antonio Meza

unread,
Aug 6, 2019, 5:29:32 PM8/6/19
to Comunidad de Visual Foxpro en Español
Hay que ver primero si el cursor se esta creando, también no se si estas manejando transacciones manuales o automáticas? 

Es decir antes de entrar al SCAN, debes estar seguro que el cursor si fue creado y ya después hacerlo editable.

saludos

HernanCano

unread,
Aug 8, 2019, 12:02:32 PM8/8/19
to Comunidad de Visual Foxpro en Español
Fernando:
Basándonos en la recomendación de Antonio, te propongo los sgtes ajustes a los comandos que nos pones....

open database .\DBFS\VFFLEBO.DBC shared
** use .\DBFS\AFILIADO in 0 alias AFILIADO index .\DBFS\AFILIADO.CDX shared 
text to _SQL_Pacientes textmerge pretext 7 noshow
  select 
      PACIENTES.GRUPO
    , PACIENTES.NOMBRE
    , PACIENTES.DIRCOB
    , PACIENTES.CODPOS
    , PACIENTES.DIRPART
   from PACIENTES
endtext

** tabla principal
oDb.Query(_SQL_Pacientes, "SQLPacientes")

if used("SQLPacientes")
   =MessageBox("El cursor sí está en uso")
else
   =MessageBox("El cursor NO está en uso")
endif

** preparamos para editar
oDb.CursorEdit("SQLPacientes") && <---- aca está el error
** select AFILIADO
select SQLPacientes
scan 
  wait window "Procesando SQLPacientes "+chr(13)+transform(recno()) nowait
  ** 
  ** Proceso...
  ** ....
  ** 
endscan

**

Ejecútalos y nos cuentas....

Fernando Mauricio Romero Jones

unread,
Aug 12, 2019, 2:52:13 PM8/12/19
to publice...@googlegroups.com
Hola. Gracias por la ayuda de Hernán y Antonio.
Les comento que superé el error por el cual comencé el hilo. Demoré en contestar porque estaba haciendo las pruebas, logré conectarme e incluso guardar 1(uno) solo registro en la tabla de MariaDB, pero obviando la sentencia odb.update() porque cuando la incorporo me da un error que les voy a pasar a describir.
Mi idea es leer una tabla en VFP e incorporar en la tabla Mdb. Les paso el código completo. Adjunto: el error que me da es VARIABLE 'ID' IS NOT FOUND y como está armada la estructura de la tabla pacientes en MDB. (gracias)
*----
Public oDb
oDb = NEWOBJECT("foxydb_class","foxydb_class.prg")
IF oDb.Connection("{MariaDB ODBC 3.1 Driver}","localhost","root","union1989","clinica","3306")
     WAIT WINDOWS "Conectado al Servidor" TIMEOUT 1
    OPEN DATABASE .\DBFS\VFFLEBO.DBC SHARED
USE .\DBFS\afiliado IN 0 ALIAS Afiliado INDEX .\DBFS\Afiliado.CDX SHARED 
TEXT TO _sql_pacientes TEXTMERGE PRETEXT 7 NOSHOW
SELECT 
    pacientes.grupo
     , pacientes.nombre
     , pacientes.dircob
   , pacientes.codpos
   , pacientes.dirpart
   , pacientes.zona
   , pacientes.doc
   , pacientes.tele
   , pacientes.fnac
   , pacientes.edad
   , pacientes.fing
   , pacientes.fcar
   , pacientes.nroafi
   , pacientes.empres
   , pacientes.observ
   , pacientes.prexist
   , pacientes.iva
   , pacientes.cuit
   , pacientes.medico
   , pacientes.tipdoc
   , pacientes.plan
      , pacientes.antece
   , pacientes.plan2
   , pacientes.modulo
   , pacientes.cabecera
   , pacientes.mail
   , pacientes.hc
 from pacientes
ENDTEXT

* tabla Principal
 odb.Query(_sql_pacientes, "sqlpacientes")
 * Preparamos para editar
 odb.CursorEdit("sqlpacientes")
SELECT afiliado
SCAN 
* Agregamos un Registro
INSERT INTO sqlpacientes  (grupo,nombre, dircob, codpos, dirpart,doc) ;
     VALUES (0,afiliado.nombre, afiliado.dircob, afiliado.codpos, afiliado.dirpart,afiliado.doc)
If odb.Changes()
  LOCAL _idRegistroNuevo as Integer, _hayCambios as Boolean, _errorSql as Boolean
  _idRegistroNuevo = 0
  _hayCambios = .f.
  _errorSql = .f.
  * Tabla Principal
       if odb.CursorChanges("sqlpacientes")
             _hayCambios = .t.
             odb.Code("pacientes","grupo")
   SELECT sqlpacientes
             replace sqlpacientes.grupo WITH VAL(PADL(odb.id_Code, 10, '0')) IN sqlpacientes 
*************
*---------hasta acá funciona perfecto (lo comprobé con wait windo)
***************
             IF odb.update("sqlpacientes") <--- acá se interrumpe y me da el error en FOXYDB_CLASS.PRG (ajunto el error)
              _idRegistroNuevo = odb.id_last
    IF odb.save()
     WAIT WINDOW "...Registro Guardado..." TIMEOUT 1.5
    endif

          ELSE && Hay un error
           _errorSql = .t.
          ENDIF
       ENDIF
   * Guardar Cambios
     IF _errorSql = .t.
      * Algo salio mal
      odb.Rollback()
     ELSE
      * Veamos si hay cambios para guardar
        IF _hayCambios = .t.
            if odb.Commit()
                MessageBox("Perfecto!!, Datos Guardados")
            else
               odb.RollBack()
               MessageBox("No se pudieron guardar los datos")
            endif
        ENDIF
  ENDIF
else
   * No se ha hecho ningún cambio
ENDIF
SELECT AFILIADO
ENDSCAN
***** FIN GRABADO
*--- DESCONECCION
IF oDb.Disconnect()
 MESSAGEBOX( ;
   "Desconexión del Servidor Mysql Correcta, Handle: " + ALLTRIM(STR(oDb.handle)), ;
   0+64, ;
   "Valor Devuelto por Disconnect(): " + ALLTRIM(STR(oDb.error_Code));
   )
ELSE
 * NOTA: Les recomiendo en desarrollo usar la propiedad ;
  this.error_Show    = .t.  && Mostrar Errores SQL devueltos por Aerror() ;
  Para que puedan ver el error de conexión y errores SQL, ya en producción ;
  la pueden usar .F. y personalizar los errores.
  IF NOT oDb.error_Show
   MESSAGEBOX( ;
     "Mensaje Personalizado: No se puedo Desconectar del Servidor", ;
     0+16, ;
     "Codigo de Error: " + ALLTRIM(STR(oDb.error_Code)) ;
     )
  ENDIF
ENDIF
*--- FIN DESCONECCION
ELSE
   WAIT WINDOWS "Error de Conexión al Servidor, Código de Error:" + str(oDb.error_Code)
ENDIF


Desde ya muchisimas gracias por su interés en ayudar.

--
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/53731461-452b-43fe-8b74-ebc15d70782a%40googlegroups.com.
error_id.png
tabla_pacientes.jpg

Antonio Meza

unread,
Aug 12, 2019, 3:21:58 PM8/12/19
to Comunidad de Visual Foxpro en Español
Hola!! 

Veo 2 detalles importantes, el primero, para que foxyDb funcione todas tus tablas en las que quieras que se administren es decir que quieras Insertar, actualizar o Eliminar registros deben si o si tener un campo Autoincrementable, por default el campo se llama "id", en tu caso se llama creo que "grupo", por lo tanto lo debes indicar en el update el nombre de tu campo si no es igual a "id".

odb.Update("sqlpacientes", "grupo", .t.)

El otro detalle es la forma en que estas actualizando, es decir recorres una tabla llamada AFILIADO por medio de un SCAN en la que actualizas los datos del cursor sqlpacientes, ese Scan esta bien, el problema que el UPDATE() debe ser ya al final que hiciste todos los cambios al cursor, al final del scan, ya que en la forma que lo estas haciendo te va a dar muchos problemas.

Debes sacar todo el codigo de FoxyDb del Scan.

saludos
Antonio Meza
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publice...@googlegroups.com.

HernanCano

unread,
Aug 12, 2019, 4:46:14 PM8/12/19
to Comunidad de Visual Foxpro en Español
Antonio:
Si es estrictamente necesario que en FoxyDb las tablas tengan un autoincremental (¿así se dice?), ¿por qué no pones una especie de validación que --mediante quizá un MessageBox-- se indique desde la conexión (--o no sé dónde, pero la idea la pongo así--) se indique que falta el AutoIncremental?

Incluso se podría poner que lo busque, que lo escoja automáticamente ---claro que puede haber dificultad si hubiera dos o más autoincrementales..... aunque...si alguien lo hace...¿qué?......

Puedo apoyarte en validar/buscar el autoincremental en SQLite y en FireBird. En MySQL/MariaDB quizá no necesites, por que es lo que usas... pero si lo indicas... me pongo en ello!!!!..... PostgreSQL?

Antonio Meza

unread,
Aug 12, 2019, 6:40:12 PM8/12/19
to Comunidad de Visual Foxpro en Español
Es correcto es forzosamente necesario, ya que por medio de los campos ID se realizan muchas operaciones en la base de datos y hace que la librería sea automatizada.

En cuanto a buscar los campos autoincrementables no lo veo necesario, ya que cuando creas una tabla lo debes indicar, el detalle es que la mayoría que viene de tablas dbf (me incluyo en la lista negra jajajaja) no usamos los campos AI y se nos hace en un principio algo de mas, pero en realidad es un gran beneficio, y si sienten que no les beneficia pues les comento que tampoco te perjudica en absolutamente nada jejeje !!

Las buenas practicas dicen que al menos debes indicar el prefijo "id" o sufijo en los campos AI, para que cualquiera que vea los nombres de los campos los identifique rápidamente sin conocer la estructura completa de la tabla, entre otras cosas.

En mi caso siempre uso "id" y se que cualquier tabla que tenga ese campo sera el autoincrementable, si veo un campo por ejemplo IdCliente quiere decir que no es un autoincrementable pero hace referencia al ID de la tabla Clientes!!! desde luego ya cada quien su cada cual jajajajaj

saludos
Antonio Meza

Interak

unread,
Jul 27, 2021, 11:40:37 AM7/27/21
to Comunidad de Visual Foxpro en Español
Hola.
Estoy iniciando en el mundo de Foxydb y veo el ejemplo realizado por Antonio. Específicamente en este tema de facturación tengo una duda, tengo que tener una conexión activa durante todo el proceso de facturación o este proceso se realiza al finalizar la misma? Otra duda es que al generar un cursor con Query() si cierro la conexión se pierde? 
Saludos.

Antonio Meza

unread,
Jul 28, 2021, 8:20:14 AM7/28/21
to Comunidad de Visual Foxpro en Español
Hola, el tema de conexión es indiferente, es decir para FoxyDb tu decides si quieres mantener la conexión activa o solo conectarte cuando se requiere, las buenas practicas indican que se debe conectar solo cuando se va a realizar algo al servidor de base de datos, aun cuando el servidor es Local.

En mi caso nunca uso conexión activa, solo cuando requiero hacer algo, por ello FoxyDb tiene 2 propiedades para indicar la forma a trabajar

  • handle_Reconnection – Si se intenta reconectar al servidor
  • handle_Network – Si mantiene permanente la conexión al servidor
Para conexión Permanente (No recomendada)

odb.handle_Reconnection = .f.
odb.handle_Network = .t.

Para conexión y desconexión (Recomendada) la ventaja es que FoxyDb se va a encargar de conectarse y desconectarse automáticamente, por lo que no tienes que preocuparte de nada.

odb.handle_Reconnection = .t.
handle_Network = .f.

Mi recomendación es que no uses conexión permanente y sin importar cual uses cuando vas a guardar una factura con detalle el proceso se realiza de forma transparente, es una de las ventajas de la librería.

Por lo tanto al usar Query() el cursor obtenido no se pierde si te desconectas del servidor.

saludos
Antonio Meza

Ricardo Soldini

unread,
Aug 3, 2021, 2:23:54 AM8/3/21
to Comunidad de Visual Foxpro en Español
Hola Antonio una duda que me surge respecto a la reconexion es que sucede si pasa mucho tiempo antes de grabar?

Te comento que un form de ingreso de registros donde actualizo varias tablas  , me he dado cuenta que si pasa mucho rato en algunas veces no graba
Este form en cuestion tine un esquema de maestro detalle
Mov_bod_enc  
mov_bod_det  articulos articulos_bodega

Entonces el usuario ingresa pone la informacion del maestro 
y en el grid digita la informacion del mov_bod_det donde ingresa informacion del articulo y pueden ser  100 o 200 registros

Antonio Meza

unread,
Aug 3, 2021, 9:19:58 AM8/3/21
to Comunidad de Visual Foxpro en Español
Hola!!

En una actualización de registros no puede haber reconexión, ya que se inicia una transacción si algo falla se cancela todo, si te desconectas a medio proceso entonces fallo la transacción y al reconectar empezarías de nuevo, pero esa parte ya la tienes que controlar, cuando te marque error de conexión durante una actualización para enviar el rollback y la ventaja es que FoxyDb regresa todo a su estado anterior antes de enviar al servidor por lo que solo tienes que iniciar el proceso nuevamente.

Espero te haya entendido!!!

saludos
Antonio Meza

Carlos

unread,
Jun 22, 2022, 9:40:39 AM6/22/22
to Comunidad de Visual Foxpro en Español
Hola, estoy comenzando con FoxyDB, con mariaDb.
Pude conectarme, hacer una consulta, y traer los datos en un cursor. Pero no puedo guardar las modificaciones.
Les paso el codigo para ver si alguien me puede dar una pista de lo que me esta faltando.

codigo del load del formulario( esto anda bien)

this.oDb = NEWOBJECT("foxydb","foxydb.prg")

IF this.oDb.Connect(.t.)             && Aquí estamos indicando que comparta la conexión.
   this.oDb.sql("Select nombre, codigo from tablas where indice ='IVA'","tablas","tablas") &&into cursor tiva
*   brow
   this.oDb.query("Select * from clientes", "clientes", "clientes")
*   BROWSE
   INDEX on codigo TAG codigo ADDITIVE
   
   SET ORDER TO codigo
   IF this.oDb.CursorEdit("clientes")
         WAIT WINDOWS "Cursor Editable" NOWAIT
      ELSE
         WAIT WINDOWS "Cursor No Editable, Error: " + str(this.oDb.error_Code)
      ENDIF
ELSE
   WAIT WINDOWS "Error de Conexión al Servidor, Código de Error:" + str(this.oDb.error_Code)
   RETURN .f.
ENDIF

codigo del boton guardar

IF ! thisform.oDb.CursorChanges("clientes")
   * Confirmar si deseamos guardar
   IF MESSAGEBOX("Desea Guardar los Cambios",4+16,"Hay Cambios") = 6   && SI
      * Actualizar Cambios en el servidor
      IF thisform.oDb.Update("clientes")
         IF thisform.oDb.Commit()
            WAIT WINDOWS "Registro Guardado"
         ELSE
            thisform.oDb.RollBack()
            WAIT WINDOWS "Revirtiendo Cambios"
         ENDIF
      ENDIF
   ELSE
      * Deshacer los cambios
      thisform.oDb.Undo()
   ENDIF
ELSE
   WAIT WINDOWS "Sin Cambios"
ENDIF

Siempre sale por el "Sin Cambios"

Gracias

Octavio Rodriguez

unread,
Jun 22, 2022, 1:13:42 PM6/22/22
to publice...@googlegroups.com

Carlos caccia...@gmail.com


Quita el signo de admiración

IF ! thisform.oDb.CursorChanges("clientes")
--
Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/9f071701-5f8c-415d-b91e-80e01e86b5fen%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages