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

VBA Sort en Excel — Range.Sort frente al objeto Sort (y cómo recuperar el orden original)

|

VBA Sort en Excel — Range.Sort frente al objeto Sort (y cómo recuperar el orden original)

TL;DR — Ordenar en código es una reordenación permanente: no hay Ctrl+Z después de que una macro se ejecuta, así que en cuanto .Sort se dispara, el orden original de las filas desaparece salvo que lo hayas guardado. Si podrías necesitarlo de vuelta, añade una columna índice (1, 2, 3…) antes de ordenar para poder deshacer la ordenación más tarde. Pasa siempre Header:=xlYes o Excel podría ordenar tu fila de títulos y meterla entre los datos. Y ordena un registro completo — la tabla entera mediante CurrentRegion, nunca una sola columna, o reordenarás una columna y descuadrarás el resto.

' Ordena una tabla por la columna C (3a col del rango) de forma descendente - todo el registro se mueve junto.
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sales")
With ws.Range("A1").CurrentRegion               ' tabla entera, para que cada columna se mantenga alineada
    .Sort Key1:=.Columns(3), Order1:=xlDescending, Header:=xlYes
End With

Ordenar parece la operación más segura de Excel — lo haces a mano cien veces al día y lo deshaces con una pulsación de tecla. En código, esa red de seguridad desaparece. Lo más importante que hay que entender sobre ordenar en VBA no es la sintaxis; es que una ordenación en una macro es una mutación que no puedes revertir a la ligera. Todo lo de abajo está organizado en torno a proteger tus datos de ese hecho, y después, la mecánica.

Lo que aprenderás

  • El modelo mental — una ordenación es una mutación permanente, y cómo hacerla reversible
  • La única regla que salva tus datos — ordena un registro completo, nunca una columna suelta
  • Header:=xlYes — por qué omitirlo deja caer tus títulos entre los datos
  • Range.Sort (rápido, límite de 3 claves) frente al objeto Sort (verboso, ilimitado, persistente)
  • La trampa de SortFields.Clear — heredar claves de ordenación de una ejecución anterior
  • Por qué los números guardados como texto se ordenan como 1, 10, 2 — y cómo arreglarlo

El modelo mental: una ordenación es una mutación, no una vista

La guía anterior presentó AutoFilter como una vista — reversible, sin ocultar nada de forma permanente. Sort es lo contrario: una mutación. Reescribe físicamente el orden de las filas. No hay ningún «original» oculto por debajo que restaurar. Y, algo crítico, Application.Undo no funciona después de que una macro ordena — ejecutar VBA borra la pila de deshacer de Excel, así que el usuario tampoco puede pulsar Ctrl+Z.

Eso cambia cómo deberías pensar antes de cada ordenación: si este orden importa, tengo que preservarlo yo mismo. La forma barata y a prueba de balas es una columna índice — marca las filas 1, 2, 3… antes de ordenar, de modo que «volver a ordenar al original» es solo una ordenación sobre esa columna:

' Anade una columna para restaurar el orden ANTES de ordenar.
Dim i As Long, lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
For i = 2 To lastRow
    ws.Cells(i, "Z").Value = i - 1        ' 1, 2, 3... en una columna libre
Next i
' ...ahora ordena como quieras; para restaurar, ordena por la columna Z de forma ascendente.

Adopta ese hábito para cualquier ordenación cuyo orden original puedas necesitar, y el problema de «no hay deshacer» desaparece.

La regla más importante: ordena el registro entero, no una sola columna

Este es el error que destruye datos en silencio. Si seleccionas una columna y la ordenas, Excel reordena solo esa columna y deja todas las demás donde estaban. Los nombres ahora se alinean con los números de teléfono equivocados; los IDs de factura apuntan a los importes equivocados. Nada da error — la hoja simplemente se vuelve, en silencio y de forma permanente, incorrecta.

' INCORRECTO - ordena la columna B sola, arrancandola del resto de cada fila.
ws.Range("B2:B100").Sort Key1:=ws.Range("B2"), Order1:=xlAscending

' CORRECTO - ordena la tabla entera; cada columna viaja con su fila.
ws.Range("A1").CurrentRegion.Sort Key1:=ws.Range("B2"), Order1:=xlAscending, Header:=xlYes

La regla: ordena el rango más pequeño que siga siendo un registro completo. En la práctica eso significa la tabla entera — Range("A1").CurrentRegion te agarra el bloque contiguo. La clave de ordenación puede ser una sola columna; el rango de ordenación debe abarcar todas las columnas del registro. Esta es exactamente la misma lección de alineación que eliminar una sola celda en lugar de una fila entera — reordena parte de un registro y lo corromperás por completo.

Header:=xlYes o tus títulos acaban ordenados entre los datos

Range.Sort tiene un argumento Header, y su valor por defecto es xlGuess — Excel intenta detectar si la primera fila es una cabecera. Cuando adivina mal, tus títulos de columna se ordenan hacia abajo entre los datos como cualquier otra fila, y acaban en algún punto del medio. Nunca dejes que adivine:

.Sort Key1:=.Columns(1), Order1:=xlAscending, Header:=xlYes   ' la primera fila son titulos - dejala en su sitio

Pasa Header:=xlYes cuando tu rango incluye la fila de cabecera (el caso habitual), xlNo cuando son datos puros. Este único argumento evita el clásico error de «mis cabeceras acabaron en la fila 43».

Dos formas de ordenar: Range.Sort frente al objeto Sort

VBA te da dos APIs, y intercambian brevedad por potencia.

Range.Sort es el rápido — una sola instrucción con hasta tres claves de ordenación (Key1/Key2/Key3). Perfecto para el caso común:

' Ordena por Region (asc), luego por Amount (desc) dentro de cada region.
ws.Range("A1").CurrentRegion.Sort _
    Key1:=ws.Range("B1"), Order1:=xlAscending, _
    Key2:=ws.Range("C1"), Order2:=xlDescending, _
    Header:=xlYes

El objeto Worksheet.Sort es el verboso — añades SortFields de uno en uno — pero elimina el techo de las tres claves y admite ordenar por color de celda, color de fuente e icono, cosa que Range.Sort no puede. Además persiste: los ajustes de ordenación se quedan pegados a la hoja, que es justo por lo que tiene un filo peligroso.

With ws.Sort
    .SortFields.Clear                       ' <-- CRITICO: suelta primero las claves sobrantes
    .SortFields.Add Key:=ws.Range("B2:B100"), Order:=xlAscending
    .SortFields.Add Key:=ws.Range("C2:C100"), Order:=xlDescending
    .SetRange ws.Range("A1").CurrentRegion
    .Header = xlYes
    .Apply
End With

La trampa que define al objeto Sort: SortFields.Clear tiene que ir primero. Como los campos de ordenación persisten en la hoja, las claves que dejó atrás una ejecución anterior de la macro — o un usuario ordenando a mano — siguen ahí. Sáltate .Clear y ordenarás por las claves antiguas más las nuevas, en una mezcla que nunca pediste. Mi regla: echa mano de Range.Sort para todo lo que llegue hasta tres claves, y pásate al objeto Sort solo cuando de verdad necesites más claves o una ordenación por color/icono — y cuando lo hagas, SortFields.Clear es la primera línea dentro del With.

La trampa del tipo de dato: números guardados como texto

Una ordenación que «sale en el orden equivocado» es casi siempre un problema de tipo de dato. Si una columna de números en realidad está guardada como texto — habitual tras importar de un CSV o de la web — Excel la ordena lexicográficamente, carácter a carácter: «1», «10», «2», «21», «3». Los valores parecen números y se ordenan como palabras.

La solución está aguas arriba: convierte la columna a números reales antes de ordenar, para que 2 se ordene antes que 10. Eso es un trabajo de conversión — mira CStr, CDate y Val para convertir texto importado en tipos numéricos genuinos. Una vez que la columna contiene números reales, la ordenación es correcta; por mucho que ajustes los argumentos de ordenación, nada arregla un texto que finge ser números.

Cómo ayuda ExcelMaster

Ordenar esconde sus peligros detrás de una operación familiar y amable: el Header:=xlYes ausente que entierra tus títulos, la ordenación de una sola columna que descuadra los registros, el SortFields.Clear que falta y hereda claves rancias, el orden de texto que finge ser números, y por encima de todo el hecho de que no hay deshacer una vez que una macro se ha ejecutado. Ninguno de estos lanza un error — simplemente dejan tus datos reordenados de forma incorrecta e irrecuperable.

ExcelMaster te deja describir la ordenación que quieres. Di «ordena por región, luego por importe de mayor a menor» y ordena el registro entero (no una columna), fija Header de forma explícita, limpia los campos de ordenación rancios y — como hace primero una copia de seguridad de la hoja — te deja una vía de vuelta aunque el propio deshacer de Excel haya desaparecido. Te quedas con el libro y con el código; te ahorras la parte en la que una ordenación de una sola columna desengancha en silencio cada nombre de su número.

Preguntas frecuentes

¿Puedo deshacer una ordenación hecha por una macro de VBA?

No. Ejecutar una macro borra la pila de deshacer de Excel, así que ni tu código ni el usuario pueden hacer Ctrl+Z de una ordenación que realizó una macro. Protege tú mismo el orden original antes de ordenar — la forma más sencilla es marcar una columna índice (1, 2, 3…) para poder volver a ordenar a ella más tarde, o hacer primero una copia de seguridad de la hoja.

¿Por qué mi ordenación de VBA descuadró los datos?

Casi siempre porque ordenaste una sola columna en lugar del registro entero. Ordenar una columna reordena solo esa columna y deja las demás en su sitio, así que los valores de cada fila ya no van juntos. Ordena la tabla entera — Range("A1").CurrentRegion — con la clave de ordenación apuntando a la columna que quieres ordenar.

¿Cómo evito que VBA ordene mi fila de cabecera y la meta entre los datos?

Pasa Header:=xlYes a .Sort (o fija .Header = xlYes en el objeto Sort). El valor por defecto es xlGuess, que deja a Excel intentar detectar la cabecera y a veces ordena tus títulos hacia abajo entre las filas. Fijar xlYes de forma explícita mantiene la primera fila fija como cabecera.

¿Cuál es la diferencia entre Range.Sort y el objeto Sort en VBA?

Range.Sort es una sola instrucción limitada a tres claves de ordenación — rápida y adecuada para la mayoría de las tareas. El objeto Worksheet.Sort añade claves de una en una con SortFields.Add, admite claves ilimitadas y ordenar por color o icono, y persiste sus ajustes en la hoja — así que debes llamar primero a SortFields.Clear para no heredar claves antiguas.

¿Por qué mi ordenación de VBA pone el 10 antes del 2?

Porque esos números están guardados como texto, y el texto se ordena lexicográficamente («1», «10», «2») en lugar de numéricamente. Convierte la columna a números reales antes de ordenar — mira la guía de conversión CStr/Val — y los valores se ordenarán en verdadero orden numérico.

Probado en

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

Guías relacionadas: VBA Find · VBA AutoFilter · VBA CStr, CDate y Val · VBA eliminar filas · VBA Range