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

VBA eliminar filas en Excel — eliminar filas, filas en blanco y filas por condición (¡recorre el bucle hacia atrás!)

|

VBA eliminar filas en Excel — eliminar filas, filas en blanco y filas por condición (¡recorre el bucle hacia atrás!)

TL;DR — Eliminar una fila es una edición estructural: no vacía la fila, la quita y hace subir una posición cada fila de debajo. Ese único hecho está detrás del error de VBA más común que existe: un bucle hacia delante que elimina filas se salta cada fila que iba justo detrás de una eliminada, porque los números de fila se desplazan bajo el bucle. La solución cabe en una palabra: recorre hacia atrás (For i = last To first Step -1). Elimina la fila entera con .EntireRow.Delete y, cuando son muchas filas dispersas, reúnelas en una sola Union y elimínalas de una vez — es más rápido y esquiva por completo el problema del desplazamiento.

' Elimina cada fila cuya columna A esté vacía — recorre de ABAJO hacia ARRIBA.
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Data")
Dim lastRow As Long, i As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

For i = lastRow To 2 Step -1                 ' <-- hacia atrás, o te saltas filas
    If Trim(ws.Cells(i, "A").Value) = "" Then ws.Rows(i).EntireRow.Delete
Next i

«Elimina estas filas» suena como la tarea más simple de la automatización de Excel, y es la que hace tropezar a casi todo el mundo la primera vez. El motivo no es el método Delete — es que eliminar cambia justo aquello que estás recorriendo. Acierta con la dirección del recorrido y eliminar por condición es trivial; fállala y tu macro deja en silencio la mitad de las filas coincidentes sin tocar. Esta guía se construye alrededor de esa única idea y, después, de los patrones prácticos que se derivan de ella.

Lo que aprenderás

  • El modelo mental — eliminar quita una fila y hace subir todo lo que está debajo
  • La regla más importante — recorre hacia atrás, o un bucle hacia delante se salta filas
  • Por qué .EntireRow.Delete es el objetivo seguro, y qué hace en cambio .Delete sobre una celda
  • El patrón más rápido para filas dispersas — construye una Union y elimina una sola vez
  • Quitar filas en blanco y eliminar por condición sin romper las fórmulas de referencia

El modelo mental: eliminar mueve la cuadrícula, no vacía una fila

Hay dos operaciones completamente distintas que la gente llama igual, «eliminar». Pulsar Supr vacía una celda — la fila se queda, el valor desaparece. Clic derecho ▸ Eliminar, o Rows(i).Delete en código, quita la fila — la fila deja de existir y cada fila de debajo sube una posición para cerrar el hueco. La fila que era la 11 ahora es la 10.

Ese comportamiento de cerrar el hueco es toda la historia. Cuando eliminas la fila 10, los datos de la fila 11 pasan a estar en la fila 10. Cualquier código que diera por hecho que «la fila 11 sigue conteniendo lo que contenía hace un momento» ahora es incorrecto. Por eso eliminar filas se siente distinto de cualquier otro bucle que escribas: la dirección de los datos que aún no has procesado cambia en el instante en que eliminas. Estás editando el sistema de coordenadas mientras lo recorres.

Ten esa imagen presente — por debajo de la fila eliminada, todo se desplaza hacia arriba — y cada regla que sigue es solo una consecuencia de ella.

La regla más importante: recorre hacia atrás o te saltas filas

Este es el error, escrito tal como casi todo el mundo lo escribe la primera vez:

' INCORRECTO — un bucle hacia delante sobre filas que estás eliminando.
For i = 2 To lastRow
    If ws.Cells(i, "A").Value = "DELETE" Then ws.Rows(i).EntireRow.Delete
Next i

Supongamos que las filas 5 y 6 dicen ambas "DELETE". El bucle llega a i = 5, elimina la fila 5 y la fila 6 sube para convertirse en la nueva fila 5. Pero el bucle avanza ahora a i = 6 — que es la fila que antes era la 7. La antigua fila 6 no se comprobó nunca. Dos coincidencias contiguas, y la segunda sobrevive. Con un bloque de coincidencias, dejas atrás más o menos una de cada dos, y el síntoma («algunas filas no se eliminaron») parece aleatorio.

La solución no cuesta nada. Recorre de abajo arriba:

' CORRECTO — elimina desde la última fila hacia la primera.
For i = lastRow To 2 Step -1
    If ws.Cells(i, "A").Value = "DELETE" Then ws.Rows(i).EntireRow.Delete
Next i

Yendo hacia atrás, eliminar la fila 6 hace subir las filas por debajo de la 6 — pero esas ya las has tratado. Las filas que aún no has mirado están todas por encima de la que acabas de eliminar, y sus números no se movieron. El desplazamiento sigue ocurriendo; solo que ocurre detrás de ti, donde no puede hacer ningún daño. Siempre que un bucle elimine filas, va con Step -1. Memoriza eso y la mitad de todos los errores al eliminar desaparecen.

La regla que mantiene los datos alineados: elimina la fila, no una celda

Delete está disponible en cualquier rango, y cuanto más pequeño es el rango, más peligroso resulta. Si escribes ws.Cells(i, "A").Delete, eliminas una sola celda, y Excel sube las celdas que están debajo de ella solo en la columna A — dejando las columnas B, C y D exactamente donde estaban. Cada fila a partir de ese punto queda desalineada: la columna A muestra un registro mientras B y C muestran el de debajo. No salta ningún error; tus datos simplemente se desordenan sin avisar.

Eliminar la fila entera mantiene cada columna acompasada:

ws.Rows(i).EntireRow.Delete        ' se elimina la fila 11 entera; 12, 13... suben juntas
ws.Cells(i, "A").EntireRow.Delete  ' idéntico — .EntireRow asciende una celda a su fila completa

.EntireRow es el ascenso de «esta celda» a «la fila entera en la que está esta celda», y es lo que casi siempre quieres. Reserva el Range.Delete a secas con Shift:=xlUp/xlToLeft para el caso raro en el que de verdad pretendes mover un bloque de celdas, no quitar un registro.

El patrón más rápido y seguro: reúne una Union y elimina una sola vez

Recorrer y eliminar fila por fila funciona en cuanto recorres hacia atrás, pero en hojas grandes es lento — cada .Delete obliga a Excel a desplazar la cuadrícula y recalcular. Hay un patrón que es a la vez más rápido e inmune a la trampa del desplazamiento, porque hace toda la eliminación en un solo paso: acumula en un Range cada fila que quieres quitar con Union y luego elimina todo el conjunto al final.

Dim victims As Range, i As Long
For i = 2 To lastRow                          ' la dirección da igual — eliminamos después
    If ws.Cells(i, "A").Value = "DELETE" Then
        If victims Is Nothing Then
            Set victims = ws.Rows(i)
        Else
            Set victims = Union(victims, ws.Rows(i))
        End If
    End If
Next i

If Not victims Is Nothing Then victims.EntireRow.Delete   ' un solo delete, todas las filas a la vez

Como no se quita ninguna fila hasta que el bucle termina, los números de fila nunca se mueven durante el barrido — así que aquí un bucle hacia delante es perfectamente seguro. Y un único .Delete de un rango de varias áreas es muchísimo más rápido que cientos de eliminaciones individuales. Mi regla general: un puñado de filas, recorre hacia atrás; cientos o miles, reúne una Union (o filtra — mira más abajo) y elimina una sola vez. Envuelve cualquiera de las dos en Application.ScreenUpdating = False / Calculation = xlManual y las eliminaciones grandes pasan de segundos a instantáneas.

Filas en blanco, condiciones y la trampa de las referencias

Eliminar filas en blanco tiene una sola línea que gana a cualquier bucle — deja que Excel encuentre los blancos:

On Error Resume Next   ' SpecialCells lanza 1004 si no hay celdas en blanco
ws.Range("A2:A" & lastRow).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
On Error GoTo 0

SpecialCells(xlCellTypeBlanks) devuelve cada celda vacía de la columna A como un único rango de varias áreas, y .EntireRow.Delete quita todas sus filas de un solo golpe. Dos advertencias: se guía por una columna (una fila con A vacía pero B rellena también se elimina) y da error cuando no hay blancos — de ahí la protección con On Error.

Para eliminar por condición en grandes volúmenes de datos, la jugada profesional es AutoFilter: filtra las filas que no quieres, elimina las visibles y quita el filtro. Es el enfoque más rápido de todos porque Excel se encarga de la coincidencia:

With ws.Range("A1").CurrentRegion
    .AutoFilter Field:=1, Criteria1:="DELETE"
    .Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete  ' salta la fila de encabezado
End With
ws.AutoFilterMode = False

Una trampa sobrevive a todas las demás: eliminar filas desplaza las referencias. Si una fórmula en otro sitio apunta a =A20 y eliminas la fila 5, Excel la reescribe como =A19 — normalmente lo que quieres. Pero si eliminas la fila de la que una fórmula depende, esa fórmula se convierte en #REF!. Eliminar filas por debajo de fórmulas vivas es la causa clásica de una hoja llena de errores #REF!, así que antes de una eliminación masiva, averigua si algo más adelante hace referencia a las filas que estás quitando. Encontrar dónde terminan tus datos es una habilidad relacionada — mira VBA última fila.

Cómo ayuda ExcelMaster

El código para eliminar filas tiene unas cuantas formas silenciosas de salir mal: el bucle hacia delante que se salta filas, el borrado de una sola celda que desalinea columnas, la llamada a SpecialCells que se cae cuando no hay blancos, la eliminación masiva que deja #REF! detrás. Ninguna lanza un error evidente — solo producen datos ligeramente incorrectos.

ExcelMaster te deja describir el resultado en su lugar. Di «elimina cada fila donde la columna A esté vacía» o «quita las filas cuyo estado sea Cancelado», y escribe el bucle en la dirección segura (o una Union/filtro para grandes volúmenes), apunta a .EntireRow, protege los casos límite y hace primero una copia de seguridad de la hoja. Te quedas con el libro y con el código; te ahorras la parte en la que un Step -1 olvidado corrompe un informe sin que te enteres.

Preguntas frecuentes

¿Por qué mi bucle de VBA se salta filas al eliminar?

Porque eliminar una fila hace subir una posición cada fila de debajo, pero un bucle hacia delante sigue incrementando. Después de eliminar la fila 5, la antigua fila 6 pasa a ser la fila 5 — y el bucle avanza a la fila 6, saltándosela. Recorre hacia atrás en su lugar: For i = lastRow To 2 Step -1. Así, las filas que aún no has comprobado están siempre por encima de la eliminación, de modo que sus números nunca se mueven.

¿Cómo elimino una fila entera en VBA?

Usa .EntireRow.Delete — por ejemplo ws.Rows(11).EntireRow.Delete o ws.Cells(11, "A").EntireRow.Delete. Ambos quitan la fila completa, así que cada columna se mantiene alineada. Evita Cells(11, "A").Delete, que elimina una sola celda y desplaza únicamente esa columna, desordenando el resto.

¿Cuál es la forma más rápida de eliminar muchas filas en VBA?

Para cientos o miles de filas, no elimines de una en una. O bien aplicas AutoFilter a las filas que quieres quitar y eliminas las celdas visibles en un solo paso, o bien construyes una Union de todas las filas objetivo durante el bucle y llamas a .EntireRow.Delete una sola vez al final. Una única eliminación de varias filas es mucho más rápida que muchas individuales, sobre todo con ScreenUpdating y Calculation desactivados.

¿Cómo elimino todas las filas en blanco en VBA?

ws.Range("A2:A" & lastRow).SpecialCells(xlCellTypeBlanks).EntireRow.Delete quita en una sola operación cada fila cuya columna A esté en blanco. Envuélvelo en On Error Resume Next / On Error GoTo 0 porque SpecialCells lanza un error cuando no hay celdas en blanco que encontrar.

¿Por qué obtengo errores #REF! después de eliminar filas?

Eliminar filas desplaza las referencias de celda. Las fórmulas que apuntan más allá de las filas eliminadas se renumeran automáticamente, pero cualquier fórmula que hiciera referencia a una celda dentro de una fila eliminada ya no puede resolverse y se convierte en #REF!. Antes de una eliminación masiva, comprueba si otras celdas dependen de las filas que estás a punto de quitar.

Probado en

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

Guías relacionadas: VBA insertar filas y columnas · VBA ocultar columnas y filas · VBA última fila · VBA For Loop · VBA Range