Ejecutar macro con atajos, estando con un formulario ya abierto - VBA Excel

Tengo el inconveniente de que no puedo ejecutar una macro desde un atajo (combinación de teclas) cuando tengo un formulario abierto. Solamente se ejecuta la macro cuando estoy sobre una hoja del libro abierto.

Me parece que es posible ejecutarla con atajos cuando estoy en un formulario, pero no se como.
¿Alguien sabe como hacerlo?

1 Respuesta

Respuesta
1

En el evento KeyDown del UserForm debe haber una instrucción que ejecute la otra otra macro.

Ejemplo:

Private Sub UserForm_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = vbKeyK Then
    If Shift = 2 Then
        Call Nombre_de_la_macro
    End If
End If
End Sub

En el ejemplo se ejecuta la macro al presionar la combinación CTRL+K

En los argumentos del evento KeyDown veras que hay uno que se llama Shift y devuelve un integer. A pesar de que se llama Shift ese argumento en realidad se refiere a 3 teclas, SHIFT, CONTROL y ALT

Para SHIFT el Integer es 1

Para CONTROL el integer es 2

Para ALT el integer es 3

La constante para la tecla "K" es vbKeyK como para casi todas las teclas vbKeyA-Z

Para comprobar una combinación de teclas debes anidar dos IF. El primer IF chequea la letra secundaria, y el segundo IF comprueba el estado del argumento Shift.

PD: Es posible combinar varios estados de SHIFT por ejemplo CTRL+SHIFT+K, etc etc.

Si tienes alguna duda sobre alguna combinación en especifico, déjanos saber.

Perdón, el Integer para ALT es 4, no 3.

Hola Andy, gracias por tu pronta respuesta. La verdad es que no me estaría funcionando lo que me has mandado. Igualmente me ha servido mucho para interiorizarme en el tema. Voy a seguir intentándolo. En caso que tengas que corregir algo y lo puedas hacer, espero tu nueva respuesta.
Gracias

Hola Andy, Hice la prueba de tu código pero lo coloque en un Control del formulario (en el mismo evento) y anduvo perfecto. 
Me parece que debe ser porque el foco esta sobre algún Control. Voy a tener que poner el código en todos los Controles del formulario.

Muchas gracias igual.. 

Disculpa la demora, ando viendo la final de la Copa América ja.

Claro, el evento solo dispara en el control que tenga el Foco. Mi respuesta fue generalizada. La manera correcta y completa de hacer esto y que sea aplicable para todo el formulario incluyendo sus controles es haciendo tu propia clase y creando un control general con el evento KeyDown e inicializar la clase en el evento Initialize del UserForm. Me tomé la molestia de hacer un ejemplo donde incluyo los controles mas comunes: TextBox, ComboBox, Labels, OptionButtons.

Video demo

Este es el poder de crear tus propias clases.

De esta forma no tienes que escribir el mismo código en cada evento de cada control. Es lo llamado "Escribe una vez, usa donde sea". Solo escribes una clase y luego la puedes usar en cualquier formulario de tu proyecto en una única Inicializacion:

Si te interesa el código es este:

Dim WithEvents uForm As MSForms.UserForm
Dim WithEvents txtBox As MSForms.TextBox
Dim WithEvents optBtn As MSForms.OptionButton
Dim WithEvents lbl As MSForms.ListBox
Dim WithEvents cmdBtn As MSForms.ComboBox
Event KeyDown(ByVal KeyCode As Integer, ByVal Shift As Integer)
Friend Sub DoKeyPreview(Parent As UserForm)
Dim ctr As Control
Set uForm = Parent
For Each ctr In Parent.Controls
Select Case TypeName(ctr)
Case "TextBox"
Set txtBox = ctr
Case "OptionButton"
Set optBtn = ctr
Case "ListBox"
Set lbl = ctr
Case "ComboBox"
Set cmdBtn = ctr
End Select
Next ctr
End Sub
Private Sub cmdBtn_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
RaiseEvent KeyDown(KeyCode, Shift)
End Sub
Private Sub uForm_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
RaiseEvent KeyDown(KeyCode, Shift)
End Sub
Private Sub txtBox_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
RaiseEvent KeyDown(KeyCode, Shift)
End Sub
Private Sub optBtn_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
RaiseEvent KeyDown(KeyCode, Shift)
End Sub
Private Sub lbl_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
RaiseEvent KeyDown(KeyCode, Shift)
End Sub

Y en el UserForm solo escribes esto:

Dim WithEvents kp As KeyPreview
Private Sub UserForm_Initialize()
Set kp = New KeyPreview
kp.DoKeyPreview Me
End Sub
Private Sub kp_KeyDown(ByVal KeyCode As Integer, ByVal Shift As Integer)
If KeyCode = vbKeyF1 Then
    If Shift = 2 Then
        Call DeAtajo
    End If
End If
End Sub

Ten en cuenta que el nombre del modulo de la clase debe ser igual al Objeto que estas inicializando:

Andy

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas