Saltar al contenido

AimKeys (Enviar combinacion de teclas directamente al buffer del teclado)


verzulsan

Recommended Posts

(NUEVO) AimKeys (Enviar combinacion de teclas directamente al buffer del teclado)

Mi aporte no es la API (mas info de la API al final del post), sino la función AimKeys, que no es más que un gestor de combos de teclas muy sencillo de usar. Usa la misma sintaxis que AIM Keys, All-in-One Macro Utility, el cual llevo años usando y quizás por esto me resulte coherente usar dicha sintaxis.

En la demo, cuyo código pongo debajo de este párrafo, encontrareis algunos ejemplos de uso, es bastante intuitivo pero si tenéis alguna duda puedo poner más ejemplos.

Sub AbrirNotepad()
AimKeys "<winr>r<winr><wx>(200)notepad<enter><wx>(700)"
End Sub

Sub AbrirCalculadora()
AimKeys "<winr>r<winr><wx>(200)calc<enter><wx>(700)"
End Sub

Sub DemoAyudaExcel()
MsgBox "No toques nada hasta que finalize la demo, gracias"
AbrirNotepad
AimKeys "<shift>e<shift>sto es una prueba de escritura<enter>"
AimKeys "<wx>(1300)" 'espera 1.3 segundos
AimKeys "<shift>n<shift>o toques ni el teclado ni el raton hasta que finalize la demo<np>(.)"
For i = 1 To 5
AimKeys "<wx>(500)<np>(.)" 'Espera y escribe un punto del teclado numerico
Next i
AimKeys "<enter><enter>"
AimKeys "<shift>v<shift>oy a escribir del 0 al 9 en dos notepad distintos<enter><enter><wx>(2000)"
AbrirNotepad
For i = 0 To 9
AimKeys "<alt><tab><alt><wx>(333)" & i
Next
AimKeys "<enter><enter><wx>(1000)"
AimKeys "<shift>y<shift>a por ultimo, haremos una sencilla operacion en la calculadora: 5<np>(.)3<np>(+)4<np>(.)7<wx>(2500)"
AbrirCalculadora
AimKeys "5<np>(.)3<np>(+)4<np>(.)7<enter><wx>(1000)"
AimKeys "<alt><tab><alt><wx>(400)<enter><enter><shift>fin de la demo<shift>"
End Sub[/CODE]

Un detalle importante, al igual que el AIMKeys original, la mayoría de las teclas son del tipo (Press/Release) excepto 5 teclas (shift, alt, ctrl, Windows-R y Windows-L) que actúan como interruptor, de modo que <shift><shift> corresponde a KeyDown SHIFT y KeyUp SHIFT, mientras que <enter> haría KeyDown y KeyUp.

El resto de los comandos podéis verlos comentados en el código y en la demo. Adjunto un archivo DEMO y el código de la función AimKeys.

[CODE]'El código es más extenso de lo que podría resumirse, la intencion es que el código se ejecute con _
la mayor rapidez posible, por eso intento evitar la anidación de operaciones recursivas sacando de _
los bucles las operaciones que se repiten mas de una vez.
'Ejemplo de entrada:'"<alt><tab><alt><wx>(2000) xcv <home><shift><end><shift><wx>(3000)<ctrl>v<ctrl> xcv "
Public Sub AimKeys(Cadena As String)

Dim Caracter As String 'Caracter lector de operaciones
Dim InnerOuter As Boolean '0: Leyendo inner, 1: Leyendo outer
Dim Longitud As Long 'Largo de la cadena de entrada y del array de operaciones
Dim Inner As String, Outer As String 'Almacen de comando inner y outer
Dim ResetTag As Boolean 'Cierra la palabra
Dim Comandos() As String 'Array con cadena de comandos
Dim CommandCont As Integer 'Contador de comandos
Dim StateArray(5) As Boolean 'Estado de las teclas interruptor (KeyDown/KeyUp)
Dim asciiVar As Long 'Ascii del caracter suelto
Dim Comando As String 'Almacen temporal de comandos que se ejecutaran

'Inicializacion de variables
Longitud = Len(Cadena)
CommandCont = -1


'========= Generando array de comandos =========
For i = 1 To Longitud
Caracter = Mid(Cadena, i, 1)
If Caracter = "<" Or Caracter = ">" Then
InnerOuter = Not (InnerOuter)
If Caracter = ">" Then
CommandCont = CommandCont + 1
ReDim Preserve Comandos(CommandCont) As String
Comandos(CommandCont) = Outer
Outer = ""
End If
Else
If InnerOuter Then
'Leyendo del outer (Todo lo que esté dentro de los simbolos Menor y Mayor)
Outer = Outer & Caracter
Else
'Leyendo del inner (Todo lo que este fuera de los simbolos Menor y Mayor)
If Caracter = "(" Or Caracter = ")" Then
'Accion asignada al comando anterior
i = i + 1
Caracter = Mid(Cadena, i, 1)
Do While (Caracter <> ")")
Inner = Inner & Caracter
i = i + 1
Caracter = Mid(Cadena, i, 1)
Loop
CommandCont = CommandCont + 1
ReDim Preserve Comandos(CommandCont) As String
Comandos(CommandCont) = Inner
Inner = ""
Else
'Caracter suelto que se evalua como un comando por si solo
CommandCont = CommandCont + 1
ReDim Preserve Comandos(CommandCont) As String
Comandos(CommandCont) = Caracter
End If
End If
End If
Next i


'========= Ejecutando array de comandos =========
'Creo que lo mejor es hacer un array para manejar los Tecla Abajo de los Tecla Arriba..,.
Longitud = UBound(Comandos)
For i = 0 To Longitud
Comando = UCase(Comandos(i))
'TECLAS ESTANDAR DE UN SOLO CARACTER
If Len(Comando) = 1 Then
asciiVar = Asc(Comando)
SendKey asciiVar
Else
Select Case Comando

'COMBOS ESPECIALES
Case "WX" 'Se va a ejecutar una espera de milisegundos, se salta el siguiente comando que equivale a los milisegundos de espera
i = i + 1
Comando = Comandos(i)
Call WaitMilisec(CLng(Comando))
Case "FF" 'Teclas F, desde <FF>(1) a <FF>(24)
i = i + 1
asciiVar = CLng(Comandos(i)) + 111
SendKey asciiVar
Case "NP" 'Teclas NumPad (Teclado Numerico),
i = i + 1
Comando = Comandos(i)
If IsNumeric(Comando) Then 'Teclas desde <NP>(0) a <NP>(9)
asciiVar = CLng(Comandos(i)) + 96
SendKey asciiVar
Else
Select Case Comando
Case "*" 'Tecla <NP>(*)
SendKey 106
Case "+" 'Tecla <NP>(+)
SendKey 107
Case "-" 'Tecla <NP>(-)
SendKey 109
Case "/" 'Tecla <NP>(/)
SendKey 111
Case "." 'Tecla <NP>(.)
SendKey 110
Case Else
MsgBox "No existe tal tecla en el teclado numerico"
End Select
End If

'TECLAS INTERRUPTOR (Para agregar mas, cambiar tambien la dimension de StateArray() en la declaracion)
Case "CTRL" 'Tecla Control (Modo interruptor)
If StateArray(0) Then
KeyUp (17)
Else: KeyDown (17): End If
StateArray(0) = Not (StateArray(0))
Case "ALT" 'Tecla Alt (Modo interruptor)
If StateArray(1) Then
KeyUp (164)
Else: KeyDown (164): End If
StateArray(1) = Not (StateArray(1))
Case "SHIFT" 'Tecla Mayusculas (Modo interruptor)
If StateArray(2) Then
KeyUp (16)
Else: KeyDown (16): End If
StateArray(2) = Not (StateArray(2))
Case "WINL" 'Tecla Windows (Izquierda) (Modo interruptor)
If StateArray(3) Then
KeyUp (91)
Else: KeyDown (91): End If
StateArray(3) = Not (StateArray(3))
Case "WINR" 'Tecla Windows (Derecha) (Modo interruptor)
If StateArray(4) Then
KeyUp (92)
Else: KeyDown (92): End If
StateArray(4) = Not (StateArray(4))

'TECLAS ESPECIALES (Ordenadas por las que uso mas frecuentemente, así sale antes del Select) _
Las siguientes teclas son presionadas y liberadas, no son del tipo interruptor
Case "SPACE": SendKey 32 'Tecla Espacio
Case "LEFT": SendKey 37 'Tecla Izquierda
Case "UP": SendKey 38 'Tecla Arriba
Case "RIGHT": SendKey 39 'Tecla Derecha
Case "DOWN": SendKey 40 'Tecla Abajo
Case "ENTER": SendKey 13 'Tecla Enter
Case "ESC": SendKey 27 'Tecla Escape
Case "PRTSCR": SendKey 44 'Tecla Imprimir Pantalla
Case "BACKSPACE": SendKey 8 'Tecla Retroceso
Case "TAB": SendKey 9 'Tecla Tabulador
Case "END": SendKey 35 'Tecla Fin
Case "HOME": SendKey 36 'Tecla Inicio
Case "INS": SendKey 45 'Tecla Insertar
Case "DEL": SendKey 46 'Tecla Suprimir
Case "PGUP": SendKey 33 'Tecla RePag
Case "PGDOWN": SendKey 34 'Tecla AvPag
Case "PAUSE": SendKey 19 'Tecla Pausa (Inter)
Case "CAPS": SendKey 20 'Tecla Bloque Mayusculas
Case "NUMLOCK": SendKey 144 'Tecla (Bloq Num) Activar/Desactivar Teclado Numerico
Case "SCRLOCK": SendKey 145 'Tecla (Bloq Despl) Bloquea el desplazamiento
Case "CENTER": SendKey 12 '======================
Case "APPS": SendKey 93 '====================


Case Else
MsgBox "No se ha localizado ningun caso que corresponda con la tecla"
End Select
End If
Next i
End Sub[/CODE]

Este aporte deja obsoleto a mi antiguo aporte https://www.ayudaexcel.com/foro/ideas-aportes-64/sendkeys-enviar-combinacion-teclas-directamente-al-buffer-del-teclado-8289/, que aun que aparentemente funcionaba bien, algunas teclas especiales se quedaban cogidas y no permitia realizar combos de teclas. La API que finaliza en el comentario “Fin del modulo SendKeyss” la he tomado prestada de [VB 6][tutorial] Send Key Methods - RaGEZONE forums que si os interesa el tema, disponen de 2 métodos más de manejo de teclas.

Espero que os guste, os dejo con el archivo.

Saludos.

AIMkeys_v2.xls

Enlace a comentario
Compartir con otras webs

Archivado

Este tema está ahora archivado y está cerrado a más respuestas.

  • 97 ¿Te parecen útiles los tips de las funciones? (ver tema completo)

    1. 1. ¿Te parecen útiles los tips de las funciones?


      • No
      • Ni me he fijado en ellos

  • Ayúdanos a mejorar la comunidad

    • Donaciones recibidas este mes: 0.00 EUR
      Objetivo: 130.00 EUR
  • Archivos

  • Estadísticas de descargas

    • Archivos
      177
    • Comentarios
      90
    • Revisiones
      27

  • Crear macros Excel

  • Mensajes

    • Hola que tal amigos programadores por favor me podrían ayudar con una macro que me genere un archivo CSV delimitado por comas, la estructura del archivo CSV no deberá llevar encabezado, los datos del archivo CSV serán obtenidos de la hoja “Datos”. En la columna A: deberá tener la clave clues que se toma de la columna B de la hoja Datos En la Columna B: el Código (son 230 codigos que van del rango G1:IB1 de la hoja datos) En la Columna C: el valor almacenado a su correspondiente al código y clues En la Columna D: el número del mes que se obtendrá de la de la columna E de la hoja Datos En la Columna E: el año que se tomará de la columna F de la hoja de Datos   Son 230 códigos por lo que la macro generará 230 filas por cada clave clues que tenga la hoja Datos En el archivo anexo una hoja llamada CSV para que vean la estructura que tendrá, el archivo CSV estará delimitado por comas   Les agradecería mucho que me ayuden por favor, Dios los bendiga Exportar datos a csv.xlsx
    • Hola buenas tardes.   Debido al trabajo debo estar comparando en un periodo unos archivos dentro de una carpeta o subcarpeta. en base a la fecha de creacion o modificacion.  pero tengo que estar viendo carpeta por carpeta y aveces son varios. Con una macro intente  listar los archivos de cualquier carpeta y subcarpeta, esto activandolo segun la celdaactiva. El problema es que tiene algunos errores. 1. si la carpeta cuenta con subcarpetas me los manda a muchas filas abajo. Mi idea es hoja(Así debe quedar) Que con una macro pueda seleccionar la carpeta desde el buscador y me de la lista de archivos a partir de la fila 6. siendo columna A= fecha de modificación, columna B =Fecha de creación y columna C=Nombre del archivo con hiperlink. Con otro o con la misma macro poder seleccionar otra carpeta y sus subcarpetas, según sea el caso. y me liste a partir de la columna F de la fila 6 Siendo La columna F=Nombre del archivo, columna H=fecha de creación, columna I=ultima modificación   Para así poder acceder y comparar mis archivos, directamente desde excel.   Muchas gracias Mariano       Listar archivos de 2 carpetas para comparar.xlsm
    • Hola buenas, Os presento mis dudas. Tengo un libro  (llamémosle LibroDestino) con dos módulos, uno de definición de variables "ModDef" y otro de inicializacion de esas mismas variables "ModCfg". Necesito que al copiarme una hoja de otro libro(llamémosle LibroOrigen), mediante un procedimiento, sobrescribir el modulo de inicialización de variables del LibroDestino con el  contenido del módulo que hay en el LibroOrigen. Destacar que los dos módulos de cada libro tienen el mismo nombre "ModCfg". Y tienen una única variable llamada "Mensaje". En el LibroDestino tiene el valor "Hola" y en el LibroOrigen el valor "Adiós" Este procedimiento lo realiza perfectamente,  es decir se sobrescribe, pero si en el mismo procedimiento quiero utilizar el nuevo valor de esa variable, me conserva el valor de la variable anterior. Para hacer las comprobaciones he ejecutado un MsgBox al empezar y al acabar el procedimiento, pero en los dos casos me devuelve el valor original del LibroDestino el valor "Hola", cuando mi idea es que al sobrescribir el modulo con el nuevo valor de la variable, el último MsgBox me devuelva el valor "Adios". Mi objetivo es poder tener la inicialización de esas variables en un libro que no sea el de trabajo (LibroDestino), ya que según la hoja que importe puedo requerir que las variables tengan un valor u otro. ¿Por que no me coge en el procedimiento el nuevo valor de la variable? ¿Cómo podría conseguirlo? He tenido que activar en VBA  la referencia Microsoft visual basic for applications extensibility 5.3 desde  Herramientas -> Referencias. Creo que es la única manera de poder trabajar con los módulos desde VBA, aunque si se pudiera de otra manera creo que sería mas óptimo. Mil gracias de antemano, un saludo!         Libro1_Prueba.xlsm Libro2_Prueba.xlsm
    • Agradecido Antoni! Tus sugerencias me ayudaron mucho! Como pudiese hacerte llegar el archivo?
    • Prueba este código. Sin el archivo no te puedo ajustar más. Private Sub btnCargaBancos_Click() 'El tipo de dato debe especificase para cada variable Dim TasaCompra As Double, TasaVenta As Double, InvBanesco As Double, InvVzla As Double Dim MontoBanesco As Double, MontoVzla As Double, TasaDiaBan As Double, TasaDiaVzla As Double Dim TasaActual As Double 'Hay que comprobar que los textbox tienen contenido numérico 'Los datos numéricos solo pueden contener números y el separador decimal, cualquier otro caracter dará error al convertir If Not IsNumeric(txtInverBanesco) Or _ Not IsNumeric(txtInverVzla) Or _ Not IsNumeric(txtTasaCompra) Or _ Not IsNumeric(txtTasaVenta) Then MsgBox "Los datos deben ser numéricos", vbCritical Exit Sub End If InvBanesco = CDbl(txtInverBanesco) InvVzla = CDbl(txtInverVzla) TasaCompra = CDbl(txtTasaCompra) TasaVenta = CDbl(txtTasaVenta) 'Los datos de los divisores no pueden ser 0 (Indeterminación matemática) If TasaCompra = 0 Or _ InvBanesco = 0 Or _ InvVzla = 0 Then MsgBox "Los datos no admiten valor cero", vbCritical Exit Sub End If MontoBanesco = (InvBanesco / TasaCompra) * (1 - 0.18 / 100) * (TasaVenta * (1 - 0.18 / 100)) MontoVzla = (InvVzla / TasaCompra) * (1 - 0.18 / 100) * (TasaVenta * (1 - 0.18 / 100)) TasaDiaBan = (MontoBanesco / InvBanesco) * (1 - 0.055) TasaDiaVzla = (MontoVzla / InvVzla) * (1 - 0.055) If TasaDiaBan < TasaDiaVzla Then TasaActual = TasaDiaBan Else TasaActual = TasaDiaVzla End If 'En VBA, los datos numéricos no admiten ser formateados, formatear directamente en las celdas, 'MontoBanesco = FormatNumber(MontoBanesco, 2, True, vbFalse) 'MontoVzla = FormatNumber(MontoVzla, 2, True, vbFalse) 'TasaActual = FormatNumber(TasaActual, 5, True, False) txtBcoBanesco = MontoBanesco txtBcoVenezuela = MontoVzla txtTasaDiaria = TasaActual End Sub  
  • Visualizado recientemente

    • No hay usuarios registrado para ver esta página.
×
×
  • Crear nuevo...

Información importante

Echa un vistazo a nuestra política de cookies para ayudarte a tener una mejor experiencia de navegación. Puedes ajustar aquí la configuración. Pulsa el botón Aceptar, si estás de acuerdo.