Problema Actualización de datos en Red Visual FoxPro

Trabajo con Visual Fox Pro7 y he hecho muchas aplicaciones monousuario, apenas estoy empezando a hacer aplicaciones en Red. Tengo un problema de actualización de datos en una aplicación que estoy desarrollando en Red.
Cuando dos usuarios están trabajando al mismo tiempo y actualizando tablas... Por ejemplo el usuario 1 actualiza una tabla y confirma con tableupdate() y el usuario 2 consulta un campo de la tabla no aparece actualizada con la información del usuario1.
Doy ejemplo del Código que utilizo (no es todo porque es un Form) es solo para que vea que comandos y funciones utilizo:
Utilizo en el entorno:
set exclusive off
set reprocess to 1
set multilocks on
FORM: TRANSAC
Tabla:OBRAS BufferMode:2 (pesimista de Filas en Buffer)
Cuando Actualizo: (Boton Poner Obra en Ejecucion)
=RLOCK("OBRAS")
SELECT obras
REPLACE estado WITH "E"
=TABLEUPDATE(0)
UNLOCK ALL
Proceso que Valida el estado de la Obra: (Boton Agregar Presupuesto)
Mestado=Obras.estado
DO CASE
CASE MEstado="P"
   ... CODIGO
CASE MEstado="E"
   ... CÓDIGO
Endcase
Descripción del Problema: El Usuario 1 y 2 abren el FORM OBRAS al mismo tiempo y cuando lo abren el estado de la obra es "P"
El usuario 1 cambia el estado de la Obra a través del formulario a "E" (Botón Poner Obra en Ejecución)
El Usuario2 en su pantalla obviamente le esta mostrando el estado de la obra es "P" y ejecuta el botón (Agregar Presupuesto) que valida el estado de la Obra: y el problema es que para el usuario 2 el estado de la obra sigue siendo "P" y ejecuta el código correspondiente al MEstado="P" y debería ejecutar el código correspondiente al MEstado="E"
He intentado con todo, he revisado el codigo, he investigado y no se porque se presenta este problema, es obvio que en la pantalla del usuario2 muestre que el estado de la Obra es "P" porque no ha refrescado, pero cuando consulta directamente el campo de la tabla (Mestado=Obras.estado) deberia asignar el valor correcto.
Lo único que me sirvió fue hacer un SELECT SQL para sacar el dato actualizado del campo de la tabla:
DECLARE AEstaObra(1)
AEstaObra(1)=""
SELECT estado FROM obras WHERE cod_obra==MCodigo INTO ARRAY AEstaObra
XEstado=AEstaObra(1)
XEstado si muestra el estado correcto de la obra, o sea "E"
Pero me parece que no es lo correcto y es más vueltas para todas las validaciones que tengo que hacer... Ademas lo ideal seria poder hacer las validaciones en tiempo real, por ejemplo:
CASE Obras.estado="P" ... Codigo...
De todos modos dime si sabes de comandos que me pueden ayudar a resolver este problema. O quisiera saber si es un problema del Visual FoxPro. Y si me puedes ayudar con otras sugerencias, ejemplos y comandos que me sirvan para mejorar mi desarrollo de aplicaciones en Red.
Espero haber sido totalmente claro en la pregunta.
Aclaro que en el form hay otras tablas y la tabla que generalmente aparece seleccionada y mostrando información es la tabla de Presupuesto a través de un grid. Ademas aclaro que no tengo relaciones establecidas entre la tabla Obras y Presupuesto ni en el Form ni en la Base de Datos.

1 Respuesta

Respuesta
1
Esa no es la forma de corregir ese tipo de errores, es sencillo creas el formulario, estableces la propiedad Datassesion y BufferMode a valor 2, luego agregas las tablas al entorno de datos del formulario luego agregas los respectivos controles de inserción de datos, aquí estableces la propiedad ControlSource de cada uno de esos controles a nombre del campo de la tabla respectivo.
En el evento init del formulario escribes Set Multilocks On
Agregas un botón de comando para guardar cambios y en el evento click de ese botón de comando escribes lo siguiente:
Local lcError, lcArrayError[AERRORARRAY]
lcError = !Tableupdate(.T.)
If lcError Then
  If Aerror(lcArrayError) > 0
    Thisform.Error(lcArrayError[1])
  Endif
  Else
     Go (Recno()) && Forzar la actualización de cualquier relación.
Endif
Return !lcError
Ahora en el evento Error del formulario puedes escribir lo siguiente:
Local lcRespuesta
Case nError = 1585 && Conflicto de actualización de datos otro usuario está modificando el registro actual o varios registros.
lcRespuesta =Messagebox("Falló la actualización de datos, otro usuario está modificado el registro," + Chr(13) + "¿Desea forzar la actualización de los datos?", 32 + 4, "Error de actualización")
If lcResPuesta = 6 Then
  =TableUpdate(.T., .T., "NombreTabla")
  Else
     =TableRevert(.T., "NombreTabla")
Endif
Esto te puede servir de ayuda.
Te aclaro que el problema no es el conflicto que se puede presentar entre los usuarios cuando intentan grabar al mismo tiempo. Para esto tengo mis rutinas de resolución de conflictos que están probadas y están funcionando ok.
El Problema es que cuando un usuario cambia el valor de un campo, el otro usuario pregunta por el valor de ese campo y le sigue apareciendo el mismo valor que tenia antes de que el otro usuario actualizara como si no se hubiera cambiado. Me toca utilizar un select SQL para sacar la información correcta, no puedo preguntar por el valor del campo directamente a la tabla o guardarlo a una variable porque no muestra el valor actualizado sino el valor anterior (solo para el segundo usuario)
Para eso debes colocar las propiedad Datasession del formulario a valor 2 y agregar la tabla al entorno de datos del formulario luego debes llamar al evento Refresh del formulario (Thisform. Refresh()) para actualizar los valores de la tabla en el formulario esa es la solución al problema si obvias cualquiera de estos dos pasos cualquier búsqueda que hagas no te devolverá los valores actualizados, trata con eso.
A manera de información la Consulta SQL te devuelve los valores que deseas es porque actualiza el entorno de datos antes de consultar los valores aún cuando este sea privado, compartido o global.
Ahora si después de todo lo anterior no aparecen actualizados es porque está fallando la llamada a la función TableUpdate() en el formulario del primer usuario y lo mismo puede ocurrir en viceversa (La función TableUpdate devuelve Falso (.F.) Cuando no se han podido grabar los cambios para lo cual debes utilizar la función Aerror() para averiguar por qué no se grabaron los cambios examina el código que te escribí arriba y para mayor información sobre la función AError consulta el manual del programador de Visual FoxPro).

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas