Buenas tardes a tod@s!!
Tengo un tema en mente y no sé si es posible o cómo hacerlo del todo.
El tema es que tengo un módulo que por los cálculos y registros que mueve se vuelve muy lento, normalmente me deja a access en "no responde". No sé si es buena idea, pero había pensado en que haga el proceso de poco a poco, y ahí está mi duda:
- Es mejor que arranque el módulo desde X punto con el evento "Al cronometro", o puedo programar dicho módulo con algun tipo de pausa?
- Tampoco no sé con la primera opción si pongo un tiempo muy corto, si me puedo encontrar con que el primer arranque no ha acabado y de algun error por intentar arrancar de nuevo. Esto podría pasar o access hasta que no ha acabado no deja arrancarlo de nuevo?
A ver si alguien me puede decir algo....
Cómo siempre, muchísimas gracias.
Bucle en módulo
Re: Bucle en módulo
Entiendo que el código funciona bien, pero la ejecución dura tanto tiempo que no se sabe si se ha colgado Access. Si es el caso, puedes intercalar dentro de ese procedimiento las instrucciones DoEvents necesarias para devolver temporalmente el control y que se actualice Access, la pantalla, Windows haga otras cosas,...
- https://support.microsoft.com/es-es/off ... 3d4c2575b0
- https://support.microsoft.com/es-es/off ... 3d4c2575b0
Re: Bucle en módulo
Perdoname, pero no acabo de ver como usarlo.... 

Re: Bucle en módulo
Yo tampoco, porque no sé cómo es tu código. En la página de ayuda de la instrucción, aparece un ejemplo donde usan DoEvents dentro de un bucle. En caso de que no haya bucles, se puede colocar cada x líneas. También puede ser que tengas una SQL a la que le cueste mucho ejecutarse. En este caso tendrás que ver si se puede ejecutar por partes o por grupos de registros.
Pero lo dicho, si no sabemos cómo es tu código, difícilmente podemos dar una ayuda más precisa.
Pero lo dicho, si no sabemos cómo es tu código, difícilmente podemos dar una ayuda más precisa.
Re: Bucle en módulo
Buenos días,
El código es este:
Quitando el bucle del "For" todo va genial, y tarda nada y menos. Sé que al haber puesto el for, la cantidad de cálculos y demás que hace ha aumentado de forma exponencial, pero cómo al arrancar en muy poco rato access se queda en "no responde", no sé hasta qué punto sigue cálculando o en qué momento de verdad se ha bloqueado.
Mirando el administrador de tareas sí que da la sensación de funcionar, o sí al final cierras access a lo "burro" al reabrirlo se ve que estaba haciendo sus cálculos.
Había pensado en poner una barra de progreso, pero sinceramente, no creo que sirva de nada si access se queda en ese estado...
No sé si tu sugerencia del "DoEvents" servirá en estos casos, porque por mucho que me miro la ayuda no entiendo ni cómo funciona ni en qué momentos se ha de usar...
Cómo siempre... gracias por vuestro tiempo y ayuda!
Saludos
El código es este:
Código: Seleccionar todo
Public Sub Patro2AUTO()
Dim strsql As String
Dim rstsql As DAO.Recordset
Dim strCompara As String
Dim rstCompara As DAO.Recordset
Dim intEst As Integer
Dim strPatro As String
Dim rstPatro As DAO.Recordset
Dim datIni As Date
Dim datFin As Date
Dim varRes As Variant
Dim intRegs As Integer
Dim intNMxCicles As Integer
Dim i As Long
Dim m As Long
datIni = Now
strsql = "SELECT Count(TC1C11.Id) AS CuentaDeId FROM TC1C11"
Set rstsql = CurrentDb.OpenRecordset(strsql, dbOpenForwardOnly)
intRegs = rstsql.Fields(0).Value
rstsql.Close
Set rstsql = Nothing
intNMxCicles = intRegs / 3
strsql = "SELECT TOpc.Id, TOpc.InfImpor FROM TOpc WHERE (((TOpc.Id)=2))"
Set rstsql = CurrentDb.OpenRecordset(strsql, dbOpenSnapshot)
If rstsql.EOF = rstsql.BOF And rstsql.EOF = True Then
MsgBox "Valor no encontrado", vbInformation
rstsql.Close
Set rstsql = Nothing
Exit Sub
End If
intEst = rstsql.Fields(1).Value
rstsql.Close
Set rstsql = Nothing
For i = 1 To intNMxCicles
strsql = "SELECT TResul.Id, TResul.C1 FROM TResul WHERE (((TResul.Id)>=" & intEst & "))"
Set rstsql = CurrentDb.OpenRecordset(strsql, dbOpenForwardOnly)
For m = 1 To i
rstsql.MoveNext
Next m
Do Until rstsql.EOF
strCompara = "SELECT TC1C11.Id, TC1C11.N1 FROM TC1C11 WHERE (((TC1C11.Id)=" & (rstsql!ID - i) & "))"
Set rstCompara = CurrentDb.OpenRecordset(strCompara, dbOpenForwardOnly)
If rstsql!ID <> (rstCompara!ID + i) Then
MsgBox "No pot ser que els id siguin diferents", vbCritical, "Error"
Exit Sub
End If
strPatro = "SELECT TPatrons2AUTO.NumC1, TPatrons2AUTO.NumC2, TPatrons2AUTO.nveg, TPatrons2AUTO.ntot,TPatrons2AUTO.nsalts"
strPatro = strPatro & " FROM TPatrons2AUTO WHERE (((TPatrons2AUTO.NumC1)=" & rstsql!c1 & ") AND ((TPatrons2AUTO.NumC2)=" & rstCompara!N1 & ")"
strPatro = strPatro & " AND ((TPatrons2AUTO.nsalts)=" & i & "))"
Set rstPatro = CurrentDb.OpenRecordset(strPatro, dbOpenDynaset)
If (rstPatro.EOF = rstPatro.BOF) And (rstPatro.EOF = True) Then
With rstPatro
.AddNew
.Fields(0) = rstsql!c1.Value
.Fields(1) = rstCompara!N1.Value
.Fields(2) = 1
.Fields(3) = 1
.Fields(4) = i
.Update
End With
rstPatro.Close
Set rstPatro = Nothing
rstCompara.Close
Set rstCompara = Nothing
GoTo c1
End If
With rstPatro
.Edit
.Fields(2) = .Fields(2) + 1
.Fields(3) = .Fields(2) + 1
.Update
End With
rstPatro.Close
Set rstPatro = Nothing
strPatro = "SELECT TPatrons2AUTO.NumC1, TPatrons2AUTO.NumC2, TPatrons2AUTO.nveg, TPatrons2AUTO.ntot"
strPatro = strPatro & " FROM TPatrons2AUTO WHERE (((TPatrons2AUTO.NumC1)=" & rstsql!c1 & ") AND ((TPatrons2AUTO.NumC2)<>" & rstCompara!N1 & ")"
strPatro = strPatro & " AND ((TPatrons2AUTO.nsalts)=" & i & "))"
Set rstPatro = CurrentDb.OpenRecordset(strPatro, dbOpenDynaset)
If (rstPatro.EOF = rstPatro.BOF) And (rstPatro.EOF = True) Then
rstPatro.Close
Set rstPatro = Nothing
rstCompara.Close
Set rstCompara = Nothing
GoTo c1
End If
Do Until rstPatro.EOF
With rstPatro
.Edit
.Fields(3) = .Fields(2) + 1
.Update
End With
rstPatro.MoveNext
Loop
rstPatro.Close
Set rstPatro = Nothing
rstCompara.Close
Set rstCompara = Nothing
c1:
rstsql.MoveNext
Loop
rstsql.Close
Set rstsql = Nothing
Next i
strPatro = "UPDATE TPatrons2AUTO SET TPatrons2AUTO.Total = [TPatrons2AUTO]![nveg]/[TPatrons2AUTO]![ntot]"
CurrentDb.Execute strPatro
datFin = Now
varRes = DateDiff("s", datIni, datFin)
MsgBox "Proceso finalizado correctamente" & vbCrLf & "Ha tardado: " & varRes & " segundos", vbInformation, "Resultado"
End Sub
Quitando el bucle del "For" todo va genial, y tarda nada y menos. Sé que al haber puesto el for, la cantidad de cálculos y demás que hace ha aumentado de forma exponencial, pero cómo al arrancar en muy poco rato access se queda en "no responde", no sé hasta qué punto sigue cálculando o en qué momento de verdad se ha bloqueado.
Mirando el administrador de tareas sí que da la sensación de funcionar, o sí al final cierras access a lo "burro" al reabrirlo se ve que estaba haciendo sus cálculos.
Había pensado en poner una barra de progreso, pero sinceramente, no creo que sirva de nada si access se queda en ese estado...
No sé si tu sugerencia del "DoEvents" servirá en estos casos, porque por mucho que me miro la ayuda no entiendo ni cómo funciona ni en qué momentos se ha de usar...

Cómo siempre... gracias por vuestro tiempo y ayuda!
Saludos
Re: Bucle en módulo
DoEvents no va a conseguir que el código se ejecute más rápido; de hecho, al devolver parcialmente el control a Windows para que se ejecuten otras aplicaciones y se actualicen las ventanas, va a ser más lento. Pero si el código está bien y Access no entra en bucle infinito, verás que Access no se congela. Puedes empezar con algo así:
Y ver si realmente acaba el bucle. Después puedes ir ajustando, de forma que el DoEvents se ejecute 1 de cada 10 veces, por ejemplo.
Y si quieres barras de progreso, puedes usar la de Access. Pero en este caso, es más que recomendable usar DoEvents para que se actualicen las pantallas:
- https://docs.microsoft.com/es-es/office ... ress-meter
Código: Seleccionar todo
For i = 1 To intNMxCicles
DoEvents
Y ver si realmente acaba el bucle. Después puedes ir ajustando, de forma que el DoEvents se ejecute 1 de cada 10 veces, por ejemplo.
Y si quieres barras de progreso, puedes usar la de Access. Pero en este caso, es más que recomendable usar DoEvents para que se actualicen las pantallas:
- https://docs.microsoft.com/es-es/office ... ress-meter
Re: Bucle en módulo
Con tu ejemplo, si no he entendido mal, el doevents se ejecutará en cada bucle del For?
Re: Bucle en módulo
En el ejemplo que he puesto, sí. Tu puedes ajustar para que se ejecute cada x veces, por ejemplo. Eso depende de lo que ralentize al código el DoEvents y de cuan importante es que no parezca que se cuelga Access.
Re: Bucle en módulo
Lo acabo de probar y genial, ese estado de bloqueo ha desaparecido y junto a la barra de progreso queda claro que funciona.
Muchísimas gracias!!
Muchísimas gracias!!
¿Quién está conectado?
Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 8 invitados