Enviar correos masivos desde Excel con Outlook
Tienes una lista en Excel con nombres, correos y algún dato propio de cada persona, y necesitas mandar un correo a cada una con su información y, a menudo, su adjunto. Hacerlo a mano son tardes enteras de copiar y pegar. Con una macro de Excel que usa tu propio Outlook, el envío entero tarda lo que se tarda en revisar el primer borrador.
Cuéntanos tu procesoEn resumen: para enviar correos masivos desde Excel se prepara una hoja con una fila por destinatario (correo, nombre, datos variables y ruta del adjunto) y una macro VBA recorre la lista, crea un correo en Outlook para cada fila y lo envía o lo deja como borrador. Funciona con el Outlook clásico de escritorio, no con el «nuevo Outlook», y conviene que la macro anote en la propia hoja qué se ha enviado para no repetir nunca un envío.
Cuándo tiene sentido hacerlo desde Excel
Si lo que quieres es un boletín para miles de contactos, Excel no es la herramienta: para eso están Mailchimp, Brevo y servicios parecidos, que gestionan las bajas y la entregabilidad. El envío desde Excel brilla en otra cosa, en correos operativos personalizados a gente con la que ya trabajas:
- El extracto o el saldo pendiente de cada cliente, con su PDF adjunto.
- La nómina, el parte de horas o el certificado de cada trabajador.
- Recordatorios de vencimiento con la factura concreta y su importe.
- Pedidos a proveedores generados a partir de una tabla de reposición.
En todos esos casos los datos ya viven en un Excel, el correo sale de tu cuenta de siempre (así que llega como un correo normal, no como publicidad) y cada mensaje es distinto.
Cómo preparar la hoja
La macro de abajo espera una hoja llamada Envios con esta estructura. Las columnas se pueden cambiar, pero el principio es el mismo: una fila, un correo.
| A · Email | B · Nombre | C · Importe | D · Adjunto (ruta) | E · Resultado |
|---|---|---|---|---|
| compras@cliente1.es | Marta | 1.250,00 | C:\Extractos\cliente1.pdf | la rellena la macro |
| admin@cliente2.es | Jorge | 380,40 |
La columna E es la más importante y la que casi todos los ejemplos de internet olvidan: ahí la macro escribe «Enviado» con la fecha y hora, o el motivo por el que no envió. Si Outlook se cuelga en el correo 40 de 80, vuelves a lanzar la macro y continúa por el 41 en lugar de mandar otra vez los 40 primeros.
La macro, explicada
Pégala en un módulo del editor de VBA (Alt + F11, Insertar, Módulo). Arranca en modo prueba: abre cada correo para que lo revises en vez de enviarlo.
Option Explicit
' Hoja "Envios": A = email, B = nombre, C = importe pendiente,
' D = ruta completa del adjunto (opcional), E = resultado (lo escribe la macro).
Sub EnviarCorreos()
Const SOLO_BORRADORES As Boolean = True ' True: abre cada correo. False: lo envía.
Dim ol As Object, msg As Object, ws As Worksheet
Dim fila As Long, ultima As Long, ruta As String
Set ws = ThisWorkbook.Worksheets("Envios")
ultima = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Set ol = CreateObject("Outlook.Application")
For fila = 2 To ultima
If ws.Cells(fila, "E").Value <> "" Then GoTo Siguiente ' ya tratada
If Not ws.Cells(fila, "A").Value Like "*?@?*.?*" Then
ws.Cells(fila, "E").Value = "Email no válido"
GoTo Siguiente
End If
ruta = Trim$(ws.Cells(fila, "D").Value)
If ruta <> "" And Dir(ruta) = "" Then
ws.Cells(fila, "E").Value = "No encuentro el adjunto"
GoTo Siguiente
End If
Set msg = ol.CreateItem(0) ' 0 = correo
msg.To = ws.Cells(fila, "A").Value
msg.Subject = "Saldo pendiente a " & Format(Date, "dd/mm/yyyy")
msg.HTMLBody = "<p>Hola, " & ws.Cells(fila, "B").Value & ":</p>" & _
"<p>Según nuestros registros, el saldo pendiente es de <b>" & _
Format(ws.Cells(fila, "C").Value, "#,##0.00") & " €</b>.</p>" & _
"<p>Un saludo.</p>"
If ruta <> "" Then msg.Attachments.Add ruta
On Error Resume Next
If SOLO_BORRADORES Then msg.Display Else msg.Send
If Err.Number <> 0 Then
ws.Cells(fila, "E").Value = "Error: " & Err.Description
Err.Clear
Else
ws.Cells(fila, "E").Value = IIf(SOLO_BORRADORES, "Borrador ", "Enviado ") & _
Format(Now, "dd/mm/yyyy hh:nn")
End If
On Error GoTo 0
Siguiente:
Next fila
End Sub
Lo que hace, en orden:
- Salta las filas ya tratadas (columna E con algo escrito). Antes del envío real, borra la columna E para que no se salte las filas que solo abriste como borrador.
- Descarta los correos mal escritos con una comprobación sencilla (que haya algo, una arroba, algo, un punto y algo) y lo deja anotado.
- Comprueba que el adjunto existe antes de crear el correo. Un correo que dice «te adjunto tu extracto» sin adjunto es peor que no mandarlo.
- Construye el cuerpo en HTML con los datos de la fila. Aquí es donde se personaliza: puedes meter tantas columnas como quieras.
- Envía o abre el borrador y apunta el resultado. Si Outlook rechaza un correo, el error queda escrito en su fila y la macro sigue con el siguiente.
Prueba siempre con tu propia dirección primero. Pon tu correo en las tres primeras filas, lanza la macro con SOLO_BORRADORES = False y revisa lo que te llega: acentos, formato del importe, nombre del adjunto. Solo después cambia a la lista real.
Los cinco problemas con los que te vas a encontrar
1. «No hace nada» o da error de automatización
El motivo más frecuente hoy: estás usando el nuevo Outlook para Windows. Esa versión no admite automatización por VBA, así que CreateObject("Outlook.Application") falla o no encuentra nada. La solución es volver al Outlook clásico (el propio Outlook tiene un interruptor para ello) o, si en tu empresa ya no está disponible, enviar con Power Automate o con la API de Microsoft 365. Lo contamos en VBA, Python o Power Automate.
2. Se pierde la firma
Al asignar HTMLBody se sustituye todo el cuerpo, firma incluida. Hay dos salidas: escribir la firma en el propio HTML de la macro, o abrir el correo primero con .Display (Outlook inserta la firma) y añadir tu texto delante de lo que ya hay.
3. Límites de envío
Microsoft 365 limita cada buzón a unos 30 mensajes por minuto y 10.000 destinatarios al día. Lo que pase de ahí se retiene o se rechaza. Para 80 o 300 correos no es un problema, pero si la lista es grande conviene meter una pausa entre envíos y repartirla en tandas. Las cuentas gratuitas de Gmail o Outlook.com tienen topes bastante más bajos.
4. El correo sale de la cuenta equivocada
Si tienes varias cuentas en Outlook, el correo sale de la predeterminada. Con la propiedad SendUsingAccount se elige la cuenta, o con SentOnBehalfOfName si envías en nombre de un buzón compartido como administracion@.
5. Gmail en lugar de Outlook
Desde VBA se puede enviar por SMTP con la biblioteca CDO, pero Google exige contraseñas de aplicación y verificación en dos pasos, y es más frágil. Si en la empresa se usa Gmail, suele salir mejor una solución con Apps Script dentro de Google Sheets.
Lo que dice la ley sobre estos envíos
Mandar a tus clientes información sobre su propia cuenta, sus facturas o sus pedidos es comunicación operativa y no plantea problema. Mandar publicidad por correo es otra cosa: en España la Ley 34/2002 (LSSI) exige que el destinatario lo haya autorizado o que sea cliente tuyo y se trate de productos parecidos a los que ya te compró, y siempre con una forma fácil de darse de baja. Que el envío salga de un Excel no cambia nada de eso.
Del ejemplo a algo que puedas usar cada mes
La macro de arriba sirve para entender el mecanismo y para envíos sencillos. Lo que suele pedir una empresa cuando lo usa en serio es algo más: generar el PDF de cada cliente en el mismo proceso (lo explicamos en guardar PDF desde Excel), elegir la plantilla del correo según el tipo de cliente, copiar a su comercial, guardar un registro de envíos con fecha que se pueda enseñar si alguien dice que no le llegó nada, y un botón en la hoja para que lo lance cualquiera sin abrir el editor de VBA.
Eso es lo que hacemos en Fusionik: partimos de tu lista y de los correos que ya mandas a mano, y te entregamos la macro probada con tus datos, documentada y con su botón.
Cada semana enseñamos una macro nueva funcionando en Instagram (@fusionik_). También en TikTok y LinkedIn.
Actualizado el 31 de octubre de 2026.
Preguntas frecuentes
Sí, con la combinación de correspondencia de Word usando Excel como origen de datos: Word envía un correo por fila a través de Outlook. El límite es que no permite un adjunto distinto por destinatario ni condiciones (por ejemplo, otro texto si el saldo es negativo). Para eso hace falta una macro o Power Automate.
No. El nuevo Outlook no admite automatización por VBA. La macro necesita el Outlook clásico de escritorio. Si tu empresa ya solo permite el nuevo, la alternativa es Power Automate o la API de Microsoft 365.
Salen de tu propio buzón, igual que si los escribieras a mano, así que se tratan como correos normales. Lo que dispara los filtros es el volumen alto de golpe, los asuntos idénticos y los enlaces sospechosos. Para envíos operativos de unos cientos de correos no suele haber problema.
Sí, es justo lo que la macro resuelve mejor que cualquier otra vía: cada fila lleva la ruta de su adjunto y la macro comprueba que existe antes de crear el correo. También se puede generar el PDF en el mismo proceso, justo antes de enviarlo.
Depende de lo que tenga que hacer además de enviar: generar los PDF, elegir plantillas o llevar un registro. Cuéntanos tu caso en el formulario y te damos un precio cerrado después de ver la prueba funcionando con tus datos de ejemplo.
¿Cuántos correos mandas a mano cada mes?
Cuéntanos qué envías y a quién. Te preparamos la macro sobre una copia de tu lista con datos ficticios para que la veas funcionar antes de decidir.
¿Prefieres escribirnos directamente? info@fusionik.com