TL;DR —
Range.RemoveDuplicateses el botón Datos > Quitar duplicados en una línea de código. Dos cosas lo hacen peligroso de una forma en que un bucle no lo es. Primero, es destructivo: elimina filas en su sitio, conserva la primera aparición de cada duplicado y no se puede deshacer una vez que una macro se ha ejecutado. Segundo, su argumentoColumnstoma desfases dentro del rango, no números de columna de la hoja —Columns:=Array(1, 2)significa la primera y la segunda columna del rango, así que si tu rango empieza en la columna C, esas son C y D, no A y B. Pasa siempreHeader:=xlYessalvo que tu rango de verdad no tenga cabecera, y haz una copia de seguridad de los datos antes de ejecutarlo.
' Elimina las filas que repiten el mismo Email (columna 3 de este rango). Conserva la primera de cada.
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Contacts")
ws.Range("A1").CurrentRegion.RemoveDuplicates _
Columns:=3, _ ' 3a columna DEL RANGO, contando desde A1
Header:=xlYes ' la primera fila son cabeceras, no la trates como datos
Quitar duplicados de una lista es uno de los trabajos de limpieza más comunes que hay, y Excel ya
tiene un motor para ello — no necesitas recorrer, comparar y eliminar a mano. Pero
RemoveDuplicates esconde dos filos afilados tras su comodidad: destruye datos sin red de
seguridad, y su argumento clave no significa lo que la mayoría supone. Esta guía se construye
alrededor de esos dos hechos.
Lo que aprenderás
- El modelo mental — es el botón Quitar duplicados, y elimina en su sitio
- La regla más importante — los números de
Columnsson desfases del rango, no columnas de la hoja - Por qué
Header:=xlYeses casi siempre obligatorio - Que conserva la primera fila, no la última — y no hay deshacer
- Una columna o varias: qué cuenta de verdad como «duplicado»
- Cuándo usar
RemoveDuplicates,AdvancedFiltero unDictionary
El modelo mental: es el botón, y elimina
Range.RemoveDuplicates hace exactamente lo que hace Datos > Quitar duplicados en la cinta:
recorre el rango, y por cada fila cuyas columnas clave repiten una fila anterior, elimina esa
fila. Las filas de debajo suben para rellenar el hueco, igual que en cualquier otra eliminación de
filas.
Dos consecuencias se siguen de inmediato, y ambas pillan a la gente. Cambia tus datos en su sitio
— no hay un modo de «copia los únicos a otra parte»; las filas originales desaparecen. Y después de
que una macro se ejecuta, la pila de deshacer de Excel está vacía, así que ni tú ni el usuario
podéis pulsar Ctrl+Z para recuperarlas. Trata RemoveDuplicates como tratarías a un
Delete: algo que solo ejecutas sobre datos de los que tienes copia de seguridad, o sobre una copia
que hiciste a propósito.
La regla más importante: Columns son desfases del rango, no columnas de la hoja
Este es el error que hace que RemoveDuplicates «elimine las filas equivocadas». El argumento
Columns cuenta columnas desde el borde izquierdo del rango, empezando en 1 — no tiene nada que
ver con las letras de columna de la hoja ni con sus números absolutos.
' El rango empieza en la columna C. Queremos desduplicar por la columna Email, que es la columna E de la hoja.
' Email es la TERCERA columna del rango (C=1, D=2, E=3), asi que:
ws.Range("C1:F500").RemoveDuplicates Columns:=3, Header:=xlYes ' correcto - E
' INCORRECTO - pasar el numero de columna de hoja 5 apunta una mas alla del rango (o da error):
ws.Range("C1:F500").RemoveDuplicates Columns:=5, Header:=xlYes ' no es la columna Email
Si tu rango resulta empezar en la columna A, el desfase coincide con el número de columna de la hoja
y el error se esconde — que es justo por lo que sorprende a la gente la primera vez que un rango
empieza en cualquier otro sitio. Cuando desduplicas por más de una columna, pasa un array de
desfases del rango: Columns:=Array(1, 3) significa que la primera y la tercera columna del
rango juntas forman la clave.
Header:=xlYes — o tu cabecera se convierte en datos
RemoveDuplicates tiene que saber si la primera fila es una cabecera o datos de verdad. El argumento
es Header, y si lo omites el valor por defecto (xlNo) trata la fila 1 como datos. Eso tiene dos
efectos desagradables: tu fila de cabecera se compara contra los datos y — si una fila de datos
casualmente coincide con el texto de la cabecera — hasta puede eliminarse.
ws.Range("A1").CurrentRegion.RemoveDuplicates Columns:=1, Header:=xlYes
Pasa Header:=xlYes siempre que tu rango incluya una fila de cabecera, que es casi siempre. La única
vez que usas xlNo es un bloque de valores genuinamente sin cabecera. Equivocarte en esto rara vez
lanza un error; simplemente destroza en silencio la parte de arriba de tu tabla.
Conserva la primera, no la última — y no hay deshacer
Cuando las filas chocan, RemoveDuplicates siempre conserva la primera aparición y elimina las
posteriores. La mayoría de las veces eso está bien. Pero si tus filas están en orden cronológico y
quieres el registro más reciente por clave, «conservar la primera» es lo contrario de lo que
necesitas.
No hay opción para invertir esto. El idioma es ordenar primero, luego desduplicar: ordena de modo
que la fila que quieres que sobreviva sea la de más arriba para su clave, y el comportamiento de
«conservar la primera» conserva ahora la fila correcta. ¿Quieres la última entrada por cliente?
Ordena por fecha de forma descendente, y luego RemoveDuplicates sobre la clave de cliente. (Mira
VBA Sort para las reglas de Header:=xlYes y de registro completo que evitan
que una ordenación te desordene las columnas.)
Y por decirlo una vez más, porque es el error que duele: no hay deshacer después de una macro. Si
las filas eliminadas pudieran importar algún día, no las elimines — extrae los únicos a una nueva
ubicación con AdvancedFilter, que deja el original intacto.
Una columna o varias: qué cuenta como duplicado
El argumento Columns también define qué significa «duplicado». Pasa una columna y dos filas son
duplicados cuando ese único campo coincide. Pasa varias y las filas son duplicados solo cuando
todas las columnas nombradas coinciden a la vez.
' Duplicado = mismo Email (clave de una columna).
rng.RemoveDuplicates Columns:=3, Header:=xlYes
' Duplicado = mismo nombre Y apellido juntos (clave compuesta).
rng.RemoveDuplicates Columns:=Array(1, 2), Header:=xlYes
Vale la pena pensarlo un momento antes de ejecutarlo, porque decide qué filas desaparecen. «La misma persona» podría significar el mismo email, o el mismo nombre, o el mismo nombre y la fecha de nacimiento — y cada elección elimina un conjunto distinto de filas. Las columnas que nombras son la definición; todo lo demás de la fila simplemente viaja con la copia que sobreviva.
RemoveDuplicates frente a AdvancedFilter frente a Dictionary
Tres herramientas desduplican, y no son intercambiables:
RemoveDuplicates— la más rápida de escribir, muta en su sitio, conserva la primera, sin deshacer. La correcta cuando de verdad quieres encoger los datos en sí y tienes una copia de seguridad.AdvancedFilter— extrae una copia única a una nueva ubicación y deja la fuente intacta. La correcta cuando necesitas una lista distinta sin destruir el original, o cuando quieres únicos filtrados por criterios a la vez.Dictionary— control total en código. La correcta cuando tu clave de desduplicación es calculada (sin distinción de mayúsculas, recortada, una combinación), cuando necesitas contar apariciones sobre la marcha, o cuando quieres decidir por fila qué copia conservar.
El juicio que vale la pena decir con claridad: si hay alguna posibilidad de que quieras de vuelta las
filas eliminadas, no uses RemoveDuplicates — su falta de deshacer es la razón misma por la que
existe AdvancedFilter.
Cómo ayuda ExcelMaster
RemoveDuplicates parece una línea de nada y se comporta como un arma cargada: los desfases de
Columns que no son columnas de la hoja, el indicador Header que se come en silencio tu fila de
cabecera, la regla de la primera y no la última que conserva el registro equivocado, y el deshacer
ausente que vuelve permanente un error. Cada uno de ellos elimina datos sin lanzar un error.
ExcelMaster te deja
describir la limpieza en su lugar. Di «elimina los contactos duplicados, conservando el más reciente
por fecha» o «desduplica por email pero deja en paz la hoja original», y elige la herramienta
correcta — ordenar antes de un RemoveDuplicates cuando quieres el más reciente, o un
AdvancedFilter a un rango nuevo cuando la fuente debe sobrevivir — y siempre hace una copia de
seguridad de la hoja antes de eliminar nada. Te quedas con el libro y con el código; te ahorras la
ejecución en la que una clave desviada por una columna eliminó en silencio las filas equivocadas.
Preguntas frecuentes
¿Cómo elimino duplicados en VBA?
Llama a RemoveDuplicates sobre el rango: ws.Range("A1").CurrentRegion.RemoveDuplicates Columns:=1, Header:=xlYes. El argumento Columns nombra qué columnas definen un duplicado (como desfases dentro
del rango), y Header:=xlYes le dice a Excel que la primera fila es una cabecera. Elimina las filas
coincidentes en su sitio, conservando la primera de cada una, así que haz primero una copia de
seguridad de tus datos.
¿Por qué VBA RemoveDuplicates elimina las filas equivocadas?
Casi siempre porque Columns cuenta desde el inicio del rango, no desde la columna A de la hoja. Si
tu rango empieza en la columna C, Columns:=1 es la columna C, no la A. Pasa el desfase de la columna
clave dentro del rango, y usa Array(...) de desfases para una clave de varias columnas.
¿VBA RemoveDuplicates conserva el primer o el último duplicado?
Conserva la primera aparición y elimina las posteriores, y no hay opción para cambiarlo. Para
conservar la última (por ejemplo, el registro más reciente), ordena los datos de modo que la fila que
quieres quede arriba para su clave, y luego ejecuta RemoveDuplicates.
¿Puedo deshacer RemoveDuplicates en VBA?
No. Ejecutarlo desde una macro borra la pila de deshacer de Excel, así que ni Ctrl+Z ni
Application.Undo restaurarán las filas eliminadas. Haz primero una copia de seguridad de los datos,
o usa AdvancedFilter para copiar las filas únicas a una nueva ubicación en lugar de eliminar en su
sitio.
¿Cómo elimino duplicados por varias columnas en VBA?
Pasa un array de desfases del rango a Columns: rng.RemoveDuplicates Columns:=Array(1, 2), Header:=xlYes. Las filas se tratan como duplicados solo cuando todas las columnas nombradas
coinciden. Los números son posiciones dentro del rango, contando desde su primera columna como 1.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 10/08/2026.
Guías relacionadas: VBA Filtro avanzado · VBA Dictionary · VBA Sort · VBA eliminar filas · VBA Range
