Quiero ordenar con una macro una tabla excel por varias columnas

Tengo una tabla excel que quiero ordenar con una macro por tres criterios y luego filtrar y el resultado de los filtros copiarlos a diferentes hojas. El filtrado me funciona bien. Pero la ordenación no me esta funcionando, ni siquiera para una sola columna, pero no me da error.

El código que estoy utilizando es una modificación del que hice con la grabadora de macros. Son X columnas: Empresa, chapa, combustible, servicentro y provincia. El orden de ordenacion es: provincia, empresa, servicentro

Sub Macro1()

' Macro1 Macro

' ORDENAR Y FILTRAR

' Acceso directo: Ctrl+Mayús+W

   '*************************** MACRO HECHA CON LA GRABADORA ***************************

  'Range("A2:D1579").Select   

' PREPARANDO ORDEN x PROVINCIA

' desde D2 hasta ultima fila (por definir)

'    ActiveWorkbook.Worksheets("LISTADO COMPLETO").Sort.SortFields.Add Key:=Range( _

'        "D2:D1579"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _

'        xlSortNormal

' ************************************* moodificacion de la macro de la grabadora

    Dim MiRango As Range ' variable para el rango de toda la tabla que varia de una semana a otra

    Dim rng_var  As Range ' variable para el rango resultante de aplicarle un filtro a MiRango

     Set MiRango = ActiveSheet.Range("LISTADO_COMPLETO")

     MiRango.Select

     ActiveWorkbook.Worksheets("LISTADO COMPLETO").Sort.SortFields.Clear

    ' PREPARANDO ORDEN x PROVINCIA

    ActiveWorkbook.Worksheets("LISTADO COMPLETO").Sort.SortFields.Add Key:=Range( _

    "E2", Range("E2").End(xlDown)), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _

    xlSortNormal

' APLICANDO LA ORDENACION

 With ActiveWorkbook.Worksheets("LISTADO COMPLETO").Sort

        .SetRange MiRango

        .Header = xlYes

        .MatchCase = False

        .Orientation = xlTopToBottom

        .SortMethod = xlPinYin

        .Apply

    End With

' se aplica el filtro pero incorrectamente para la primera fila ¿por qué?

este es el orden inicial, son datos de ejemplo

así es como me queda después de ordenar por provincia

¿Qué estoy haciendo mal?

Respuesta
4

Te dejo una macro obtenida con la grabadora, a la que le hice unos arreglos para que sirva para contemplar otras situaciones y dimensiones (*)

Sub OrdenandoColumnas()
'x Elsamatilde
 'se aplica filtros si aún no los tiene
If ActiveSheet.AutoFilterMode = False Then
    Range("A1:E1").AutoFilter
Else
    'si está filtrada se muestran todas las filas
    If ActiveSheet.FilterMode = True Then ActiveSheet.ShowAllData
End If
'encontrar el fin de rango para acotar el filtrado
finx = Range("A" & Rows.Count).End(xlUp).Row
Range("E1").Select
    ActiveWorkbook.Worksheets("Hoja1").AutoFilter.Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Hoja1").AutoFilter.Sort.SortFields.Add2 Key:=Range _
        ("E2:E" & finx), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
        xlSortNormal
    ActiveWorkbook.Worksheets("Hoja1").AutoFilter.Sort.SortFields.Add2 Key:=Range _
        ("A2:A" & finx), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
        xlSortNormal
    ActiveWorkbook.Worksheets("Hoja1").AutoFilter.Sort.SortFields.Add2 Key:=Range _
        ("D2:D" & finx), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
        xlSortNormal
    With ActiveWorkbook.Worksheets("Hoja1").AutoFilter.Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub

A partir de la línea Range("E1").Select siguen las instrucciones obtenidas con la grabadora. En cada columna podés ajustar el orden (Ascending o Descending) a tu gusto. 

Todavía se la puede mejorar un poco más sin hacer mención a libro y hoja con la expresión:

ActiveSheet en lugar de ActiveWorkbook. Worksheets("Hoja1")

* Te invito a mirar el video Nº 62 - La Grabadora de Macros ...

1 respuesta más de otro experto

Respuesta
2

El problema en tu código parece estar relacionado con cómo defines el rango para la ordenación. Aquí hay una versión corregida del código que debería funcionar para ordenar por tres columnas: provincia, empresa y servicentro.

Dim MiRango As Range ' variable para el rango de toda la tabla que varía de una semana a otra Dim rng_var As Range ' variable para el rango resultante de aplicarle un filtro a MiRango

Sub Macro1()
    Dim MiRango As Range ' variable para el rango de toda la tabla que varía de una semana a otra
    Dim rng_var As Range ' variable para el rango resultante de aplicarle un filtro a MiRango
    Dim i As Integer ' variable para contar el número de filas filtradas
    ' Define el rango completo de la tabla
    Set MiRango = ActiveSheet.Range("A2:E1579")
    ' Limpia cualquier campo de ordenación existente
    ActiveWorkbook.Worksheets("LISTADO COMPLETO").Sort.SortFields.Clear
    ' Configura los campos de ordenación
    With ActiveWorkbook.Worksheets("LISTADO COMPLETO").Sort
        ' Configura el primer campo de ordenación por provincia (columna E)
        .SortFields.Add Key:=Range("E2", Range("E2").End(xlDown)), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        ' Configura el segundo campo de ordenación por empresa (columna A)
        .SortFields.Add Key:=Range("A2", Range("A2").End(xlDown)), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        ' Configura el tercer campo de ordenación por servicentro (columna D)
        .SortFields.Add Key:=Range("D2", Range("D2").End(xlDown)), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        ' Aplica la ordenación
        .SetRange MiRango
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    ' Aplica el filtro por provincia (ejemplo: "Madrid")
    ActiveSheet.Range("E1:E" & MiRango.Rows.Count).AutoFilter Field:=1, Criteria1:="Madrid"
    ' Copia los resultados filtrados a una nueva hoja
    i = MiRango.SpecialCells(xlCellTypeVisible).Rows.Count - 1 ' Resta 1 para excluir el encabezado
    MiRango.SpecialCells(xlCellTypeVisible).Copy Destination:=Sheets("Hoja2").Range("A2")
    ' Limpia el filtro
    ActiveSheet.AutoFilterMode = False
    ' Se aplica el filtro y se copian los resultados a diferentes hojas según tus necesidades
    ' Agrega aquí tu código para aplicar el filtro y copiar los resultados a diferentes hojas
    MsgBox "La ordenación y filtrado se ha completado correctamente."
End Sub

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas