TL;DR —
SendKeysno 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 unDoEvents, así que las líneas que van después deSendKeysse 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 un50%literal se escribe50{%}. UsaSendKeyssolo 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
