una progreso mientras macro ejemplo ejecuta barra ms-access access-vba

ms-access - ejemplo - barra de progreso mientras se ejecuta una macro



Barra de progreso en MS Access (7)

Tengo una consulta ejecutándose en Microsoft Access 2010 y demora más de 30 minutos en ejecutarse normalmente. Me gustaría presentar al usuario final algún estado de la consulta. Una barra de progreso sería agradable pero no requerida. El acceso parece estar mal enlazado y se bloquea firmemente durante la ejecución de la consulta, negando cualquier actualización que intente. Aunque prefiero sacar a VS y escribir mi propia aplicación para hacer esto, me veo obligado a usar Access.

¿Algunas ideas?

EDITAR

Solía ​​ejecutar esto desde un script por lotes que llenaba la base de datos, pero me gustaría tenerlo todo en Access. Para ser específico, la "consulta" es realmente un script VBA que hace ping a una serie de hosts. Por lo tanto, no me preocupa la optimización del tiempo en sí, sino simplemente informarle al usuario final que no se ha cerrado.


A menudo hago algo como esto

Dim n As Long, db As DAO.Database, rs As DAO.Recordset ''Show the hour glass DoCmd.Hourglass True Set db = CurrentDb Set rs = db.OpenRecordset("SELECT ...") rs.MoveLast ''Needed to get the accurate number of records ''Show the progress bar SysCmd acSysCmdInitMeter, "working...", rs.RecordCount rs.MoveFirst Do Until rs.EOF ''Do the work here ... ''Update the progress bar n = n + 1 SysCmd acSysCmdUpdateMeter, n ''Keep the application responding (optional) DoEvents rs.MoveNext Loop rs.Close: Set rs = Nothing db.Close: Set db = Nothing ''Remove the progress bar SysCmd acSysCmdRemoveMeter ''Show the normal cursor again DoCmd.Hourglass False

Nota: Por supuesto, debe hacer el trabajo programáticamente para que esto funcione. No puede ver una consulta de ejecución en código o similar en Access. Posiblemente podría dividir el trabajo de su consulta lenta en partes más pequeñas, para tener la oportunidad de actualizar una barra de progreso. Pero siempre se puede mostrar el reloj de arena; esto le dice al usuario que algo está sucediendo.


Debido a problemas con el control disponible, creé una barra de progreso desarrollada en casa usando 2 rectángulos. Un borde y una barra sólida que se redimensiona a medida que avanzan las cosas. El rectángulo de progreso en frente del borde. Usar

If pbar Is Nothing Then Set pbar = New pBar_sub pbar.init Me.Progressbar_border, Me.ProgressBar_Bar End If pbar.value = 0 pbar.show pbar.max = 145 '' number of interations ... ... Do While Not recset.EOF count = count + 1 pbar.value = count '' get next recset.MoveNext Loop

Uno puede asociar una línea de estado con la barra de progreso que anuncia qué elemento se está procesando. Como: 123. District SomeWhere, agente de ventas Quienquiera

======== Barra de progreso sustituye a pBar_sub ==============

Option Compare Database Option Explicit Dim position As Long Dim maximum As Long Dim increment As Single Dim border As Object Dim bar As Object Sub init(rect As Object, b As Object) Set border = rect Set bar = b bar.width = 0 hide End Sub Sub hide() bar.visible = False border.visible = False End Sub Sub show() bar.visible = True border.visible = True End Sub Property Get Max() As Integer Max = maximum End Property Property Let Max(val As Integer) maximum = val increment = border.width / val End Property Property Get value() As Integer value = position End Property Property Let value(val As Integer) position = val bar.width = increment * value End Property


En caso de que a otros les resulte útil, aquí hay una clase que escribí para este propósito. Lo uso todo el tiempo en mis proyectos de desarrollo de Access. Simplemente clsLblProg en su proyecto en un módulo de clase llamado clsLblProg , y utilícelo así:

Esto produce una pequeña barra de progreso agradable:

En su formulario, todo lo que necesita es tres etiquetas. Coloque la etiqueta posterior en el tamaño deseado y haga que los otros dos estén ocultos. La clase hace el resto.

Y aquí está el código para clsLblProg :

Option Compare Database Option Explicit '' By Adam Waller '' Last Modified: 12/16/05 ''Private Const sngOffset As Single = 1.5 '' For Excel Private Const sngOffset As Single = 15 '' For Access Private mdblMax As Double '' max value of progress bar Private mdblVal As Double '' current value of progress bar Private mdblFullWidth As Double '' width of front label at 100% Private mdblIncSize As Double Private mblnHideCap As Boolean '' display percent complete Private mobjParent As Object '' parent of back label Private mlblBack As Access.Label '' existing label for back Private mlblFront As Access.Label '' label created for front Private mlblCaption As Access.Label '' progress bar caption Private mdteLastUpdate As Date '' Time last updated Private mblnNotSmooth As Boolean '' Display smooth bar by doevents after every update. '' This class displays a progress bar created '' from 3 labels. '' to use, just add a label to your form, '' and use this back label to position the '' progress bar. Public Sub Initialize(BackLabel As Access.Label, FrontLabel As Access.Label, CaptionLabel As Access.Label) On Error GoTo 0 '' Debug Mode Dim objParent As Object '' could be a form or tab control Dim frm As Form Set mobjParent = BackLabel.Parent '' set private variables Set mlblBack = BackLabel Set mlblFront = FrontLabel Set mlblCaption = CaptionLabel '' set properties for back label With mlblBack .Visible = True .SpecialEffect = 2 '' sunken. Seems to lose when not visible. End With '' set properties for front label With mlblFront mdblFullWidth = mlblBack.Width - (sngOffset * 2) .Left = mlblBack.Left + sngOffset .Top = mlblBack.Top + sngOffset .Width = 0 .Height = mlblBack.Height - (sngOffset * 2) .Caption = "" .BackColor = 8388608 .BackStyle = 1 .Visible = True End With '' set properties for caption label With mlblCaption .Left = mlblBack.Left + 2 .Top = mlblBack.Top + 2 .Width = mlblBack.Width - 4 .Height = mlblBack.Height - 4 .TextAlign = 2 ''fmTextAlignCenter .BackStyle = 0 ''fmBackStyleTransparent .Caption = "0%" .Visible = Not Me.HideCaption .ForeColor = 16777215 '' white End With ''Stop Exit Sub ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "Initialize", Erl Resume Next '' Resume at next line. End Select End Sub Private Sub Class_Terminate() On Error GoTo 0 '' Debug Mode On Error Resume Next mlblFront.Visible = False mlblCaption.Visible = False On Error GoTo 0 '' Debug Mode Exit Sub ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "Class_Terminate", Erl Resume Next '' Resume at next line. End Select End Sub Public Property Get Max() As Double On Error GoTo 0 '' Debug Mode Max = mdblMax Exit Property ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "Max", Erl Resume Next '' Resume at next line. End Select End Property Public Property Let Max(ByVal dblMax As Double) On Error GoTo 0 '' Debug Mode mdblMax = dblMax Exit Property ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "Max", Erl Resume Next '' Resume at next line. End Select End Property Public Property Get Value() As Double On Error GoTo 0 '' Debug Mode Value = mdblVal Exit Property ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "Value", Erl Resume Next '' Resume at next line. End Select End Property Public Property Let Value(ByVal dblVal As Double) On Error GoTo 0 '' Debug Mode ''update only if change is => 1% If (CInt(dblVal * (100 / mdblMax))) > (CInt(mdblVal * (100 / mdblMax))) Then mdblVal = dblVal Update Else mdblVal = dblVal End If Exit Property ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "Value", Erl Resume Next '' Resume at next line. End Select End Property Public Property Get IncrementSize() As Double On Error GoTo 0 '' Debug Mode IncrementSize = mdblIncSize Exit Property ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "IncrementSize", Erl Resume Next '' Resume at next line. End Select End Property Public Property Let IncrementSize(ByVal dblSize As Double) On Error GoTo 0 '' Debug Mode mdblIncSize = dblSize Exit Property ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "IncrementSize", Erl Resume Next '' Resume at next line. End Select End Property Public Property Get HideCaption() As Boolean On Error GoTo 0 '' Debug Mode HideCaption = mblnHideCap Exit Property ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "HideCaption", Erl Resume Next '' Resume at next line. End Select End Property Public Property Let HideCaption(ByVal blnHide As Boolean) On Error GoTo 0 '' Debug Mode mblnHideCap = blnHide Exit Property ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "HideCaption", Erl Resume Next '' Resume at next line. End Select End Property Private Sub Update() On Error GoTo 0 '' Debug Mode Dim intPercent As Integer Dim dblWidth As Double ''On Error Resume Next intPercent = mdblVal * (100 / mdblMax) dblWidth = mdblVal * (mdblFullWidth / mdblMax) mlblFront.Width = dblWidth mlblCaption.Caption = intPercent & "%" ''mlblFront.Parent.Repaint '' may not be needed '' Use white or black, depending on progress If Me.Value > (Me.Max / 2) Then mlblCaption.ForeColor = 16777215 '' white Else mlblCaption.ForeColor = 0 '' black End If If mblnNotSmooth Then If mdteLastUpdate <> Now Then '' update every second. DoEvents mdteLastUpdate = Now End If Else DoEvents End If Exit Sub ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "Update", Erl Resume Next '' Resume at next line. End Select End Sub Public Sub Increment() On Error GoTo 0 '' Debug Mode Dim dblVal As Double dblVal = Me.Value If dblVal < Me.Max Then Me.Value = dblVal + 1 ''Call Update End If Exit Sub ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "Increment", Erl Resume Next '' Resume at next line. End Select End Sub Public Sub Clear() On Error GoTo 0 '' Debug Mode Call Class_Terminate Exit Sub ErrHandler: Select Case Err.Number Case Else LogErr Err, "clsLblProg", "Clear", Erl Resume Next '' Resume at next line. End Select End Sub Private Function ParentForm(ctlControl As Control) As String '' returns the name of the parent form Dim objParent As Object Set objParent = ctlControl Do While Not TypeOf objParent Is Form Set objParent = objParent.Parent Loop '' Now we should have the parent form ParentForm = objParent.Name End Function Public Property Get Smooth() As Boolean '' Display the progress bar smoothly. '' True by default, this property allows the call '' to doevents after every increment. '' If False, it will only update once per second. '' (This may increase speed for fast progresses.) '' '' negative to set default to true Smooth = mblnNotSmooth End Property Public Property Let Smooth(ByVal IsSmooth As Boolean) mblnNotSmooth = Not IsSmooth End Property Private Sub LogErr(objErr, strMod, strProc, intLine) '' For future use. End Sub


Esta no es una forma profesional, pero se puede aplicar si te gusta. Si está utilizando un formulario, puede tener un pequeño cuadro de texto en un lugar conveniente por defecto con color verde.

Suponiendo que el nombre del cuadro de texto es TxtProcessing ,
Las propiedades pueden ser las siguientes.

Name : TxtProcessing Visible : Yes Back color : Green Locked: Yes Enter Key Behavior : Default

1) En su script VB puede poner Me.TxtProcessing.BackColor = vbRed que estará en rojo y significa la tarea en proceso.
2) puedes escribir todo tu conjunto de scripts
3) Por fin puedes poner Me.TxtProcessing.BackColor = vbGreen

Me.TxtProcessing.BackColor = vbRed Me.TxtProcessing.SetFocus Me.Refresh Your Code here..... Me.TxtProcessing.BackColor = vbGreen Me.TxtProcessing.SetFocus

:-) Divertido pero el propósito se logra.


Primero arrastre el control de barra progresiva en el formulario de MS Access, luego cambie el nombre de barra progresiva como aa .

Luego vaya a la form property , en el temporizador :write código

me.aa.value=me.aa.value+20

intervalo de tiempo 300 según su elección. Ejecute el formulario verá la barra progresiva.


Simplemente agregando mi parte a la colección anterior para futuros lectores.

Si buscas menos código y quizás una interfaz de usuario genial. Echa un vistazo a mi GitHub para Progressbar para VBA

una personalizable:

La Dll está pensada para MS-Access pero debería funcionar en todas las plataformas VBA con cambios menores. Todos los códigos se pueden encontrar en la base de datos de muestra.

Este proyecto está actualmente en desarrollo y no todos los errores están cubiertos. Así que espera un poco!

Debería preocuparse por las DLL de terceros y, si lo está, no dude en utilizar cualquier antivirus en línea de confianza antes de implementar la DLL.


Utilice el comando DoEvents después de actualizar la barra de progreso (acSysCmdUpdateMeter).

En caso de un gran número de registros, solo ejecute DoEvents cada x veces, ya que esto ralentiza un poco su aplicación.