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
.Sortse 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 siempreHeader:=xlYeso Excel podría ordenar tu fila de títulos y meterla entre los datos. Y ordena un registro completo — la tabla entera medianteCurrentRegion, 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 datosRange.Sort(rápido, límite de 3 claves) frente al objetoSort(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
