Saltar al contenido

Formulario de usuario de Excel VBA: ejecute Sub cuando algo cambie

Solución:

Esto se puede lograr utilizando un módulo de clase. En el ejemplo que sigue, asumiré que ya tiene un formulario de usuario con algunos cuadros de texto.

En primer lugar, cree un módulo de clase en su proyecto VBA (llamemos clsTextBox – ¡asegúrese de cambiar la propiedad ‘Nombre’ del módulo de clase!)

Private WithEvents MyTextBox As MSForms.TextBox

Public Property Set Control(tb As MSForms.TextBox)
    Set MyTextBox = tb
End Property

Private Sub MyTextBox_Change()
    AutoCalc() //call your AutoCalc sub / function whenever textbox changes
End Sub

Ahora, en el formulario de usuario, agregue el siguiente código:

Dim tbCollection As Collection

Private Sub UserForm_Initialize()
    Dim ctrl As MSForms.Control
    Dim obj As clsTextBox

    Set tbCollection = New Collection
        For Each ctrl In Me.Controls
            If TypeOf ctrl Is MSForms.TextBox Then
                Set obj = New clsTextBox
                Set obj.Control = ctrl
                tbCollection.Add obj
            End If
        Next ctrl
    Set obj = Nothing

End Sub

El uso de clases, como sugiere la respuesta anterior, es una buena estrategia para manejar muchos controles de una manera concisa y elegante, sin embargo:

1) No veo problemas en la creación de 25 eventos con 1 línea, llamando a una rutina privada de formulario de usuario común, a menos que el número de controles sea dinámico. Es un BESO filosofía.

2) Generalmente, considero el Cambio Evento muy perturbador porque hace todo el recálculo de cada dígito ingresado. Es más sensato y moderado hacer esto usando el Salida evento o Antes de la actualización evento, porque hace el recálculo solo cuando se decide sobre un valor. Por ejemplo, el Google Instant Me molesta intentar devolver respuestas, consumiendo recursos, sin que el usuario haya definido la pregunta.

3) Hubo un problema de validación. Estoy de acuerdo en que puedes evitar claves incorrectas con Cambio evento, sin embargo, si necesita validar los datos, no puede saber si el usuario continuará escribiendo o si los datos están listos para ser validados.

4) Debes recordar que Cambio o Salida Los eventos no obligan al usuario a pasar campos de texto, por lo que el sistema debe ser revalidado y recalculado al intentar salir del formulario sin cancelar.

El siguiente código es simple pero efectivo para formularios estáticos.

Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Call  AutoCalc(Cancel)
End Sub

Private Sub TextBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Call  AutoCalc(Cancel)
End Sub
.....
Private Sub TextBox25_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Call  AutoCalc(Cancel)
End Sub

Private Function Valid
.....
End Function 

Private Sub AutoCalc(Canc As Variant)
If Not Valid() Then Canc=True
'  Calculation
End Sub

Si es adicto a ahorrar tiempo, puede crear una rutina VBA genérica para generar código para eventos relacionados con controles en una forma que se ajuste a una máscara. Este código puede estar en una hoja de borrador (es más seguro generar código directamente, que tiene errores en algunas versiones de Excel) y que copiar y pegar en un módulo de formulario.

 Sub GenerateEvent(Form As String, Mask As String, _
   Evento As String, Code As String)
 '  Form - Form name in active workbook
 '  Mark - String piece inside control name
 '  Evento - Event name to form procedure name
 '  Code   - Code line inside event
 Dim F As Object
 Dim I As Integer
 Dim L As Long
 Dim R As Range
 Dim Off As Long
 Set F = ThisWorkbook.VBProject.VBComponents(Form)
 Set R = ActiveCell   ' Destination code
 Off = 0
 For I = 0 To F.Designer.Controls.Count - 1
    If F.Designer.Controls(I).Name Like "*" & Mask & "*" Then
        R.Offset(Off, 0) = "Private Sub " & _
          F.Designer.Controls(I).Name & "_" & Evento & "()"
        R.Offset(Off + 1, 0) = "     " & Code
        R.Offset(Off + 2, 0) = "End Sub"
        Off = Off + 4
    End If
 Next I
 End Sub

 Sub Test()
 Call GenerateEvent("FServCons", "tDt", "Exit", _
    "Call AtuaCalc(Cancel)")
 End Sub

Eche un vistazo a esto para saber cómo crear una clase que responda a un cambio en cualquier cuadro de texto. El ejemplo es para botones, pero se puede modificar. Sin embargo, tenga en cuenta que los controles Textbox no tienen un evento Exit (ese evento es en realidad parte del formulario de usuario) por lo que realmente tendrá que usar el evento Change.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *