visual uso openrecordset ejemplo dbopendynaset currentdb vba ms-access access-vba dao

vba - uso - La transferencia de paso pierde los cambios realizados en SQL



recordset vba excel (1)

La razón por la que esto sucede es que el objeto Db persistente está almacenando en caché una copia de QueryDef y sus propiedades (para incluir la propiedad .SQL). Si llama a MyPassThruSetDates , luego realiza un cambio en el SQL para MyPassThru y luego llama a MyPassThruSetDates nuevamente, el SQL original sobrescribe cualquier cambio realizado desde la llamada original a MyPassThruDates .

La solución es actualizar la colección QueryDefs para garantizar que esté utilizando los valores más actuales:

Sub MyPassThruSetDates(FromDate As Date, ThruDate As Date) Const FromPattern As String = "(@FromDate datetime = '')([/d/]+)''" Const ThruPattern As String = "(@ThruDate datetime = '')([/d/]+)''" Dim qd As DAO.QueryDef Db.QueryDefs.Refresh '' <--- This is the key!!! Set qd = Db.QueryDefs("MyPassThru") qd.SQL = RegExReplace(FromPattern, qd.SQL, "$1" & Format(FromDate, "m/d/yyyy") & "''") qd.SQL = RegExReplace(ThruPattern, qd.SQL, "$1" & Format(ThruDate, "m/d/yyyy") & "''") Set qd = Nothing End Sub

Para obtener una explicación más detallada de por qué sucede esto, consulte la siguiente rutina de prueba altamente comentada:

Sub TestDbCache() Const QName As String = "TempQry" Dim qd As DAO.QueryDef, db As DAO.Database ''First, we create a querydef Set db = CurrentDb Set qd = db.CreateQueryDef(QName, "SELECT ''original''") Debug.Print qd.SQL ''--> SELECT ''original''; ''Next, we update the querydef''s .SQL outside the scope of our db object CurrentDb.QueryDefs(QName).SQL = "SELECT ''changed''" ''The querydef and db objects are unaware of the change to .SQL Debug.Print qd.SQL ''--> SELECT ''original''; Debug.Print db.QueryDefs(QName).SQL ''--> SELECT ''original''; Debug.Print CurrentDb.QueryDefs(QName).SQL ''--> SELECT ''changed''; ''Refreshing the collection updates both the db and qd objects db.QueryDefs.Refresh Debug.Print qd.SQL ''--> SELECT ''changed''; Debug.Print db.QueryDefs(QName).SQL ''--> SELECT ''changed''; ''Note that the .SQL is "SELECT ''changed''" when we set the NewDb object Dim NewDb As DAO.Database Set NewDb = CurrentDb ''We change the .SQL without refreshing the NewDb''s QueryDefs collection CurrentDb.QueryDefs(QName).SQL = "SELECT ''changed again''" ''Since the NewDb object never cached the contents of the query, '' it returns the correct current value of .SQL Debug.Print NewDb.QueryDefs(QName).SQL ''--> SELECT ''changed again''; ''The other db object has not refreshed its QueryDefs collection, '' so it is wrong once again Debug.Print qd.SQL ''--> SELECT ''changed''; Debug.Print db.QueryDefs(QName).SQL ''--> SELECT ''changed''; End Sub

Tengo una consulta de paso MyPassThru . Esta es una versión simplificada del SQL de la consulta:

SET NOCOUNT ON DECLARE @FromDate datetime = ''1/25/2014'' DECLARE @ThruDate datetime = ''3/1/2014'' SELECT * FROM MtgDailyTrans M WHERE M.TransDate >= @FromDate AND M.TransDate <= @ThruDate

Necesito hacer cambios a los parámetros @FromDate y @ThruDate. Escribí la siguiente función para hacer esto ( fuente para RegExReplace ):

Private gDb As DAO.Database Function Db() As DAO.Database If gDb Is Nothing Then Set gDb = CurrentDb Set Db = gDb End Function Sub MyPassThruSetDates(FromDate As Date, ThruDate As Date) Const FromPattern As String = "(@FromDate datetime = '')([/d/]+)''" Const ThruPattern As String = "(@ThruDate datetime = '')([/d/]+)''" Dim qd As DAO.QueryDef Set qd = Db.QueryDefs("MyPassThru") qd.SQL = RegExReplace(FromPattern, qd.SQL, "$1" & Format(FromDate, "m/d/yyyy") & "''") qd.SQL = RegExReplace(ThruPattern, qd.SQL, "$1" & Format(ThruDate, "m/d/yyyy") & "''") Set qd = Nothing End Sub

El problema es que cuando realizo cambios en el SQL para MyPassThru y luego ejecuto el procedimiento MyPassThruSetDates() , los cambios que realicé en el SQL se retrotraen. ¿Por qué?