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

VBA eliminar duplicados en Excel — desduplica en una línea (y por qué elimina sin deshacer)

|

VBA eliminar duplicados en Excel — desduplica en una línea (y por qué elimina sin deshacer)

TL;DRRange.RemoveDuplicates es 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 argumento Columns toma 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 siempre Header:=xlYes salvo 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 Columns son desfases del rango, no columnas de la hoja
  • Por qué Header:=xlYes es 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, AdvancedFilter o un Dictionary

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