🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA SendKeys en Excel — sintaxis, códigos de tecla y por qué se ejecuta fuera de orden

|

VBA SendKeys en Excel — sintaxis, códigos de tecla y por qué se ejecuta fuera de orden

TL;DR — SendKeys no pulsa teclas. Deja pulsaciones en una cola, y las recibe la ventana que tenga el foco cuando se leen. De ahí salen dos consecuencias que explican casi todas las quejas. Las teclas enviadas a Excel solo se leen cuando tu macro cede el control, al final o en un DoEvents, así que las líneas que van después de SendKeys se ejecutan antes. Y las teclas enviadas a otro programa van a la ventana que tenga el foco cuando llegan, que puede no ser la que pretendías. Caracteres como + ^ % ~ ( ) son códigos, así que un 50% literal se escribe 50{%}. Usa SendKeys solo como última línea de una macro, para dejar la propia interfaz de Excel lista para el usuario. Para todo lo demás hay una llamada del modelo de objetos que hace el trabajo directamente.

Sub EditNoteCell()
    Range("D2").Select
    SendKeys "{F2}"                 ' ultima linea: el usuario queda en modo de edicion en D2
End Sub

Este es el tercer artículo de una serie sobre macros que Excel ejecuta por ti: desde un atajo de teclado, desde el reloj con OnTime y aquí, desde pulsaciones simuladas. La idea de la serie es que ninguna de estas llama a nada directamente: cada una deja una petición en una cola, y la petición se atiende cuando Excel está libre y listo. En el caso de SendKeys, la petición es una pulsación, y la cola es la entrada de teclado de la ventana que esté delante.

Lo que aprenderás

  • El modelo mental: pulsaciones en una cola, entregadas a la ventana con el foco
  • Sintaxis, códigos de tecla y cómo enviar caracteres especiales literales
  • Por qué SendKeys parece ejecutarse fuera de orden
  • El foco, la ventana equivocada y por qué no puede ejecutarse sin nadie delante
  • El efecto secundario en Bloq Num
  • Los pocos trabajos para los que sirve SendKeys, y qué usar en su lugar

El modelo mental: pulsaciones en una cola

Cuando pulsas una tecla, Windows la mete en la cola de entrada de la ventana que tiene el foco, y ese programa la lee cuando le toca. SendKeys escribe en esa misma cola, como si las teclas se hubieran tecleado.

Así que SendKeys decide qué se teclea, pero no cuándo se lee ni quién lo lee:

  • Cuándo: el programa receptor lee su cola cuando está libre. Si el receptor es Excel, Excel está ocupado ejecutando tu macro, así que lee las teclas cuando tu macro cede el control.
  • Quién: las teclas van a la ventana que tiene el foco en el momento de leerlas, no a la ventana en la que pensabas cuando escribiste la línea.

Ten presentes esas dos preguntas y el comportamiento extraño se vuelve predecible.

Sintaxis y códigos de tecla

Hay dos formas, con los mismos argumentos:

SendKeys "^c"                       ' instruccion de VBA
Application.SendKeys "^c"           ' metodo de Excel
SendKeys "~", True                  ' Wait:=True, espera a que se procesen las teclas

La mayoría de las teclas se escriben tal cual: SendKeys "abc" teclea abc. Los modificadores y las teclas con nombre usan códigos:

Código Tecla
^ Ctrl, como en ^s para Ctrl+S
+ Mayús, como en +{F10} para Mayús+F10
% Alt, como en %{DOWN} para Alt+Flecha abajo
~ o {ENTER} Enter
{TAB}, {ESC}, {BS}, {DEL} Tab, Esc, Retroceso, Supr
{UP}, {DOWN}, {LEFT}, {RIGHT} teclas de flecha
{HOME}, {END}, {PGUP}, {PGDN} desplazamiento
{F1} a {F16} teclas de función
{LEFT 3} una tecla repetida 3 veces
+(abc) Mayús pulsada mientras se pulsan a, b y c

No hay código para la tecla Windows ni para Impr Pant, y SendKeys no puede hacer clic con el ratón.

Los caracteres especiales literales van entre llaves

Como + ^ % ~ ( ) son códigos, no se pueden teclear como texto. Esto envía 50 y luego pulsa Alt:

SendKeys "Discount 50%"             ' mal: % significa Alt
SendKeys "Discount 50{%}"           ' bien: las llaves lo hacen literal

Los caracteres que hay que poner entre llaves son + ^ % ~ ( ) { } [ ]. Si el texto viene de una celda o del usuario, escápalo con una función en lugar de a mano:

Function EscapeKeys(ByVal s As String) As String
    Dim i As Long, ch As String, result As String
    For i = 1 To Len(s)
        ch = Mid$(s, i, 1)
        If InStr("+^%~(){}[]", ch) > 0 Then
            result = result & "{" & ch & "}"
        Else
            result = result & ch
        End If
    Next i
    EscapeKeys = result
End Function

Por qué SendKeys parece ejecutarse fuera de orden

Es la pregunta más habitual: el código que va después de SendKeys se ejecuta antes que las teclas. Un ejemplo típico:

Sub CopyWithKeys()
    Range("A1:C10").Select
    SendKeys "^c"                   ' en cola, todavia sin leer
    Worksheets("Report").Paste      ' se ejecuta ya: el portapapeles sigue vacio
End Sub

SendKeys dejó Ctrl+C en la cola de Excel y volvió al instante. Excel leerá la cola cuando esté libre, y no lo está: está ejecutando CopyWithKeys. Así que Paste va primero, y la copia ocurre cuando la macro ya ha terminado. Wait:=True no ayuda aquí, porque Excel no puede procesar teclas dirigidas a sí mismo mientras tu código sigue en marcha. Un DoEvents después del SendKeys a veces deja pasar las teclas y a veces no, lo cual es peor que nunca.

La regla que sale de aquí: las teclas enviadas a Excel van en la última línea de la macro. Nada de lo que tenga que ocurrir después debería depender de ellas. Y aquí la respuesta correcta no es arreglar el momento, sino usar el modelo de objetos, que se ejecuta exactamente cuando se ejecuta la línea:

Range("A1:C10").Copy Destination:=Worksheets("Report").Range("A1")

La guía de copiar y pegar cubre todos los métodos de copia.

El foco decide quién recibe las teclas

Cuando envías teclas a otro programa, manda la segunda pregunta: ¿quién tiene el foco cuando se leen las teclas?

Shell "notepad.exe", vbNormalFocus
Application.Wait Now + TimeSerial(0, 0, 1)   ' con suerte el Bloc de notas ya esta listo
SendKeys "Monthly total: 1250~"

Si el Bloc de notas tarda en abrirse, las teclas llegan a Excel y se escriben en una celda. Si una notificación, un correo o una ventana de chat se lleva el foco durante ese segundo, el texto va allí. Con la pantalla bloqueada o en una sesión remota minimizada, las teclas no van a ninguna parte. Y Windows bloquea las teclas que un programa normal envía a un programa que se ejecuta como administrador, así que SendKeys hacia una ventana con privilegios elevados no hace nada, y en silencio.

Eso hace absoluta la regla para el trabajo desatendido: SendKeys no puede ejecutarse cuando no hay nadie mirando. Una macro lanzada por OnTime o por el Programador de tareas que use SendKeys acabará, tarde o temprano, escribiendo donde no debe. Para controlar otro programa, usa su modelo de objetos mediante CreateObject, o arráncalo con argumentos mediante Shell.

El efecto secundario en Bloq Num

Un efecto secundario conocido desde hace mucho: en muchos equipos con Windows, la instrucción SendKeys de VBA desactiva Bloq Num, y a veces afecta a Bloq Mayús. Los usuarios se dan cuenta de que el teclado numérico ha dejado de funcionar después de ejecutar tu macro.

El código que envía {NUMLOCK} para volver a activarlo solo lo conmuta otra vez, así que acierta en unos equipos y falla en otros. Se dice que Application.SendKeys lo provoca con menos frecuencia que la instrucción, pero ninguno de los dos es fiable. El arreglo de verdad es el mismo que para todo lo demás en esta página: enviar menos teclas. Una macro que solo usa SendKeys una vez, como última línea, rara vez llama la atención por esto.

La decisión de criterio: un último recurso, para la propia interfaz de Excel

SendKeys sirve para un tipo de trabajo: dejar la propia interfaz de Excel lista para el usuario, como última línea de una macro. Poner una celda en modo de edición con {F2}, o abrir el desplegable de un filtro con %{DOWN}, son usos razonables, porque el usuario está delante y nada de tu código depende del resultado.

Para todo lo demás hay una llamada directa que se ejecuta cuando se ejecuta la línea, con cualquier distribución de teclado y con cualquier ventana delante:

Para qué se envían teclas Qué usar en su lugar
^c, ^v para copiar y pegar Range.Copy, PasteSpecial
^s para guardar ThisWorkbook.Save
~ para responder a un aviso de Excel Application.DisplayAlerts = False
secuencias con % para un comando de la cinta de opciones Application.CommandBars.ExecuteMso "PasteValues"
abrir un cuadro de diálogo integrado Application.Dialogs(xlDialogPrint).Show
escribir en otro programa su modelo de objetos mediante CreateObject

Las secuencias de acceso como Alt, H, V, V dependen además del idioma de Office: las letras de la cinta de opciones cambian entre el Excel en inglés, en alemán y en español, así que una secuencia de SendKeys escrita en uno falla en el otro. En un Excel en español, sin ir más lejos, la pestaña Inicio no responde a la H, y una macro copiada de un foro en inglés pulsa letras que no llevan a ninguna parte. Las llamadas de la columna derecha no tienen ese problema. La guía de DisplayAlerts muestra cómo manejar los avisos de Excel sin pulsar ninguna tecla.

Cómo ayuda ExcelMaster

El código con SendKeys suele funcionar en la máquina en la que se escribió, el día en que se escribió. Se rompe con otra distribución de teclado, un PC más lento, otro idioma de Office o la primera vez que una notificación le roba el foco.

ExcelMaster lee la macro, deduce qué intenta hacer cada línea de SendKeys y la sustituye por la llamada del modelo de objetos que hace lo mismo directamente, para que la macro deje de depender del momento, del foco o de la distribución del teclado.

Preguntas frecuentes

¿Cómo envío la tecla Enter con SendKeys?

Usa SendKeys "~" o SendKeys "{ENTER}". La virgulilla es la tecla Enter principal; {ENTER} es la tecla Enter del teclado numérico, y las dos funcionan en la mayoría de los programas.

¿Por qué SendKeys no funciona en mi macro?

Normalmente sí funciona, pero más tarde de lo que esperas: las teclas enviadas a Excel se leen cuando tu macro cede el control, así que las líneas que van después de SendKeys se ejecutan antes. Las teclas enviadas a otro programa van a la ventana que tenga el foco cuando se leen. Pon SendKeys en la última línea, o sustitúyelo por una llamada del modelo de objetos.

¿Por qué SendKeys desactiva Bloq Num?

Es un efecto secundario conocido desde hace mucho de la instrucción SendKeys de VBA en Windows. Enviar {NUMLOCK} de vuelta solo lo conmuta y no es fiable. Usa SendKeys lo menos posible.

¿Qué diferencia hay entre SendKeys y Application.SendKeys?

SendKeys es la instrucción de VBA y Application.SendKeys es el método de Excel. Admiten los mismos códigos de tecla y el mismo argumento Wait. Los dos escriben en la cola de entrada de la ventana que tiene el foco.

¿Cómo envío un signo de porcentaje o un signo más con SendKeys?

Ponlo entre llaves: {%}, {+}, {^}, {~}, {(} y {)}. Sin llaves, estos caracteres se leen como Alt, Mayús, Ctrl, Enter y códigos de agrupación.

Probado en

Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 03/10/2026.

Guías relacionadas: VBA Shortcut Key · VBA OnTime · VBA Copy Paste · VBA DisplayAlerts · VBA DoEvents · VBA Shell · VBA CreateObject · VBA Wait