Trazar la ejecución

Tengo el siguiente código:
...
'Abro un ADODB.Recordset cn es una ADODB.Connection
tAntes.ActiveConnection = cn
tAntes.CursorType = adOpenStatic
tAntes.LockType = adLockReadOnly
tAntes.Source="SELECT * FROM Trabajos WHERE Cliente = 5 AND (Factura ='' OR Factura IS NULL)"
tAntes.Open
'Mensaje 1
MsgBox tAntes.RecordCount
'Modifico registros
cn.Execute "UPDATE Trabajos SET Factura = 9 WHERE Cliente = 5 AND (Factura ='' OR Factura IS NULL)"
'Mensaje 2
MsgBox tAntes.RecordCount
...
El problema es el que:
El cliente 5 tiene 2 trabajos sin datos en Factura ('' OR IS NULL).
Si muestro el mensaje 1 tAntes.RecordCount es 2
Si anulo (marco como comentario) el mensaje 1 en el mensaje 2 tAntes.RecordCount es 1, como si con.execute hubiese actualizado uno de los dos registros antes de abrirse tAntes, ya que si accedo a la BD (Access 2000) en el momento en el que mensaje 2 está visible, los dos registros han sido actualizados.
Lógicamente si ejecuto paso a paso (F8) todo va bien.
¿La ejecución del código no es lineal?
¿Qué hago mal?
¿Alguien me puede ayudar?
Gracias.
1

1 respuesta

Respuesta
1
A mi ver el problema es que tienes un cursor estático, el cual al haber un cambio en la BD directamente a la conexión la consulta debería ser igual, creo que si vuelves a hacer la consulta antes del mensaje 2 debes verse los resultados como deben estar en la BD, esto es, cambiar estas lineas
'Mensaje 2
MsgBox tAntes.RecordCount
Por estas
'Mensaje 2
TAntes. Close
TAntes. Open
MsgBox tAntes.RecordCount
Intentalo a ver que resulta.
Quiero que el cursor sea estático, para que en tAntes se guarde el estado del recordset antes de los cambios y poder crear un segundo recordset con el estdo posterior.
Todo esto es para poder "regitrar" las modificaciones realizadas en la tabla, me explico, paso los dos estados del recordset a una función que guarda los datos antes/despues y la fecha del cambio.
Sub Registro (Fecha As String, Optional RegAntes, Optional RegDespues)
¿Cómo lo hago si el recordset estático no guarda el estado y se refresca, o la actualización se efectúa antes de que se abra tAntes?
¿Cuál de las dos opciones es la que ocurre?
Gracias.
Entonces no uses un Execute directo a la BD, te aconsejo uses el objeto recordset para hacer los cambios, algo como:
'Abro un ADODB.Recordset cn es una ADODB.Connection
tAntes.ActiveConnection = cn
tAntes.CursorType = adOpenStatic
tAntes.LockType = adLockReadOnly
tAntes.Source="SELECT * FROM Trabajos WHERE Cliente = 5 AND (Factura ='' OR Factura IS NULL)"
tAntes.Open
if not(tAntes.Eof) Then
Do
ValorAntes= tAntes!Factura
tAntes!Factura = 9
tAntes.Update
ValorDespues=tAntes!Factura
Registro(Now, tAntes!Folio, ValorAntes, ValorDespues)
tAntes.Movenext
Loop Until tAntes.Eof
End If
Checa que la función Registro cambia un poco la cual te permitirá conocer que factura se hizo un cambio, que valor tenia y por cual se actualizo, ademas de la hora y fecha del evento.
Ojala y te ayude.
RegAntes y RegDespues son datos tipo ADODB. Recordset
Sub Registro (Fecha As String, Optional RegAntes, Optional RegDespues)
Alta:
Registro Fecha,, RegDespues
Baja:
Registro Fecha, RegAntes
Modificación:
Registro Fecha, RegAntes, RegDespues
Una vez aclarado esto..., he probado a actualizar los registros de Trabajos sin execute pero tAntes sigue reflejando los cambios, ¡Aun siendo estático!.
Ahora mismo el código es:
sSQL = "SELECT *" & _
" FROM Trabajos" & _
" WHERE ((Trabajos.Factura ='" & "" & "')" & _
" OR (Trabajos.Factura Is Null))" & _
" AND Trabajos.Cliente =" & txt(1)
tAntes.Open sSQL, cn, adOpenStatic, adLockReadOnly
sSQL = "SELECT *" & _
" FROM Trabajos" & _
" WHERE Factura ='" & UltFac & "'"
tDespues.Open sSQL, cn, adOpenDynamic, adLockPessimistic
MsgBox tDespues.RecordCount 'muestra -1 ya que aun no existen (correcto)
MsgBox tAntes.RecordCount 'muestra 2 (correcto)
tTrabajos.Filter = "((Factura ='" & "" & "')" & _
" OR (Factura Is Null))" & _
" AND Cliente = " & txt(1)
tTrabajos.MoveFirst
Do
tTrabajos("Factura") = UltFac
tTrabajos("Fecha Factura") = txt(0)
tTrabajos.Update
tTrabajos.MoveNext
Loop Until tTrabajos.EOF
MsgBox tDespues.RecordCount 'muestra -1 aunque si existen (incorrecto)
MsgBox tAntes.RecordCount 'muestra 2 (correcto)
RegistroDetalles Date, tAntes, tDespues
Aunque abra el tDespues tras las modificaciones de tTrabajos, el 1 y el 3 msgbox no muestran 2 (correcto), sino -1
Si comento los dos primeros msgbox, el 4 msgbox no muestra 2 (correcto), sino 1, por eso creo que el problema es que "no le da tiempo a abrir el recordeset" antes de que se realicen los cambios, ¡¿Es posible?!
Si comento todos los msgbox tAntes pasa a Registro con 1 registro y tDespues con 2
Muchas Gracias.
Ok, solo tengo una duda para ubicarme, ¿lo qué pretendemos con esto es demostrar como funcionan los recordset estáticos y dinámicos O estamos tratando de resolver un problema?
Porque en caso de resolver un problema yo consideraría utilizar varibales en vez de recordsets pues es más rápido y consume menos recursos.
En caso contrario para hacer una BD de ejemplo y hacer mis pruebas.
La idea es poder generar una relación de las modificaciones realizadas en la BD mediante la rutina Registro.
Es muy probable que dicha rutina se pueda optimizar. En estos momentos su funcionamiento es el siguiente + o -:
Tengo una BD igual a la de trabajo pero con los campos duplicados:
Clientes: Cod, Nombre,..., Cod2, Nombre2,..., FechaReg, HoraReg
Alta:
Guarda el recordset completo en la BD de registro en los campos Cod2, Nombre2,... dejando en blanco los campos Cod, Nombre,...
Baja:
Guarda el recordset completo en los campos Cod, Nombre,... dejando en blanco Cod2, Nombre2,...
Modificación:
Guarda el recodrset completo en Cod, Nombre,... y datos en el/los campo/s en el/los que se han realizado cambios en Cod2, Nombre2,...
Para ello quería tener el estado anterior y posterior de los datos en dos recordsets, lógicanmente el primero debería ser estático, pero para mi sorpresa no es "tan estático" como debiera.
Saludos.
PD: Si estoy haciendo alguna barbaridad no dudes en decirlo.
Disculpa mi tardanza, pero salí de vacaciones y soy papa de nuevo.
Bueno, el método que estas utilizando esta muy bien, pero me viene a la mente de como funciona Sql Server cuando hace eso.
Otra forma es hacer una tabla temporal que te sirva como historial el cual se le agregará un nuevo registro cada vez que haya un cambio, de esta manera vas a poder quitar o restablecer los cambios hasta mucho más niveles que los 2 que ofrece tu sistema, claro, en esta tabla vas a poner la hora y fecha cuando ocurrió y cuando vayas a restablecer, reestableces el ultimo cambio y lo borras de esta tabla, si quieres restablecer de nuevo haces lo mismo y así hasta que llegues al principio de todos los cambios.
Espero y te ayude. Buena suerte !

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas