Ordenar Excel VBA por fecha (sin textbox)

Odeatho -  
lermite222 Mensajes publicados 9042 Estado Colaborador -
Hola a todos,
He recorrido bastantes foros que dan respuestas que me convienen casi, pero que no logro adaptar.
Tengo una hoja de cálculo de Excel con una columna llena de fechas y me gustaría simplemente hacer un orden según la fecha.
Leí que la solución probablemente pasaría por la conversión a modo estándar de la columna.

He encontrado un código que funciona casi:

Dim ColDates As Integer
Dim f1 As Worksheet
Set f1 = Worksheets("sheet")
ColDates = 40
'1.Columns(ColDates).NumberFormat = "0"
f1.Range("A1").CurrentRegion.Sort Key1:=Range("I250"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
' ', _DataOption1:=xlSortNormal
'1.Columns(ColDates).NumberFormat = "dd/mm/yyyy"

Pero hay dos problemas que no logro resolver.
El primero es que para indicar el contenido de mis columnas, la primera celda es una cadena, así que cuando se ordena, la pone automáticamente al final, que es lo que no quiero. He intentado cambiarlo a número durante el periodo del ordenamiento, pero no tuve éxito.

Segundo problema, me parece entender que Excel tiene problemas entre fechas jj/mm/aaaa y mm/jj/aaaa, además cuando pongo la columna en formato estándar hay algunas celdas que no cambian (que no logro formatear como Fecha)

¿Tendrías ideas?

11 respuestas

  1. lermite222 Mensajes publicados 9042 Estado Colaborador 1 199
     
    Hola,
    Efectivamente no es posible cambiar una fecha ingresada como texto por un formato fecha.
    La causa: Excel trata las fechas como números '1 = 1/1/1900
    el 13/11/2008 = 39765
    Lo que implica que en la celda no hay una fecha sino un número que Excel MUESTRA con el formato designado.
    Pero en una celda de texto, no es un número lo que hay, sino una cadena (string).
    y no hay problema con los formatos.
    Para solucionarlo puedes hacer un bucle sobre tu columna para volver a convertir todo a fecha con..
     Worksheets("Feuil2").Range("A7") = CVDate(Worksheets("Feuil2").Range("A7"))

    Ajusta las direcciones, por supuesto.
    Cuando esté hecho, tu filtro funcionará normaal.
    A+
    --
    La experiencia instruye con más seguridad que el consejo. (André Gide)  
    Si te golpeas un pote y suena hueco, no es necesariamente el pote el que está vacío. ;-) (Confucio)
    0
    1. Odeatho
       
      Gracias =) Pero no tengo un nivel muy bueno en VBA y me cuesta manejar los Range Ves en el trozo de código que cité en mi primer post, no entiendo por qué es Range(A1) luego Key(I250). Y intenté usar tu fórmula pero es igual, no consigo decirle que tome desde la celda 1 hasta la 250. Otra pregunta, ¿cómo se hace para poner la columna AN dentro de un rango? No he tenido éxito tampoco. Aquí está el código que puse pero el rango no es correcto. Dim A As Long For A = 2 To 250 Cells(40, A).Value = Cells(12, A).Value f1.Range(12, A) = CVDate(f1.Range(12, A)) Next A Seguramente son preguntas fáciles que hago, lo siento :)
      0
  2. michel_m Mensajes publicados 18903 Fecha de registro   Estado Colaborador Última intervención   3 320
     
    Hola,

    esperando a nuestro amigo Louis (¡hola, Lhermite, es la hora!) ;-)

    tu variable A siendo un número designando una columna no puedes emplear con facilidad el objeto "range"

    entonces debes usar cells(12,A)

    si tu variable X designara una fila en la columna B podrías escribir range("B:" & X)

    --

    Cordialmente,
    Michel
    0
    1. Odeatho
       
      Gracias Michel =)
      Intenté hacer lo que me dijiste pero no funcionó, tengo la impresión de que soy yo quien no entiende lol
      en realidad me gustaría recorrer mi columna L o AN a elegir de 1 a 250
      probé esto (en un bucle de 1 a 250 con A como variable incrementada) :

      f1.Range("AN:" & A) = CVDate(f1.Range("AN:" & A))
      me dice "method range of object worsheet failed"

      y esto :
      f1.Cells("AN:" & A) = CVDate(f1.Cells("AN:" & A))
      me dice " Type mismatch"

      no entiendo qué es lo que falla
      0
  3. michel_m Mensajes publicados 18903 Fecha de registro   Estado Colaborador Última intervención   3 320
     
    CVdate?

    ¿No sería mejor Cdate?

    --
    Atentamente,
    Michel
    0
  4. lermite222 Mensajes publicados 9042 Estado Colaborador 1 199
     
    Hola, hola Michel, ya estoy despierto... :-)
    No, es bien CVDate...
    Y comencemos por el principio, cambia tu columna Textre a fecha...
    1°) con Range primero pones la columna Y DESPUÉS la fila.. Tipo B5
    Pero con Cells es al revés, Cells(Fila,Columna)
    así que cuando pones...
    Cells(40, A).Value = Cells(12, A).Value
    Las direcciones no son correctas.
    Ejecuta primero esta pequeña función
    Sub ChangerT_D() Dim Lig As Long, Col As Integer Col = 2 ' Para la columna B .. a adaptar. Nota: para la columna AN es 40 For Lig = 2 To 250 'adaptar las filas Cells(Lig, Col) = CVDate(Cells(Lig, Col)) Next Lig End Sub

    Tú dices..
    Y veremos para la continuación
    EDIT:
    Evita usar variables abstractas como A, B, C etc, si trabajas con filas pon una variable que te haga pensar en filas, yo empleo Lig y Col para columnas.
    Intenta también poner una o varias mayúsculas en el nombre de la variable pero cuando la retranscribas NO PONGAS mayúsculas, así podrás detectar rápidamente un error de sintaxis si la palabra que acabas de escribir no se transforma sola con una o más mayúsculas. (pequeños trucos)
    --
    La experiencia instruye más seguramente que el consejo. (André Gide)  
    Si te golpeas a un pote y suena hueco, no necesariamente es el pote el que está vacío. ;-)(Confucio)
    0
  5. lermite222 Mensajes publicados 9042 Estado Colaborador 1 199
     
    Voy a responder de todas maneras a tu segunda pregunta antes de tu respuesta,
    Key1:=Range("I250"), me sorprendería que eso esté bien,
    Key es la “palabra” a buscar, así que si por ejemplo lo que buscas está en una lista de nombres escribe en A1 ...Marcel
    y entonces debería ser Key=range("A1"), buscará todas las líneas donde esté escrito el nombre Marcel.
    --
    La experiencia instruye más seguramente que el consejo. (André Gide)  
    Si te pegas a un pote y suena hueco, no es necesariamente que el pote esté vacío. ;-)(Confucio)
    0
    1. Odeatho
       
      Hola a todos,
      Gracias, voy a probar todo esto ( desde ahora hasta el miércoles por la noche de la próxima semana y sí, ¡viva la alternancia! :p)
      les mantendré informados.

      Sí, entonces de hecho la función que escribí en mi primer post no ordena por fecha en absoluto, ¿verdad?
      O tal vez está previsto que no haya nada en la casilla en cuestión, en cuyo caso el orden se haría de menor a mayor?
      En fin, son solo suposiciones. Es raro, de todos modos, tomé esa función de un foro que daba funciones para ordenar por fecha.

      ¡Muchísimas gracias!
      0
      1. Odeatho > Odeatho
         
        Salta las personas (lo siento por el retraso :) )

        Lo siento por ustedes pero
        Cells(Lig, Col) = CVDate(Cells(Lig, Col))
        me devuelve Type Mismatch

        No entiendo por qué d a demás
        0
  6. lermite222 Mensajes publicados 9042 Estado Colaborador 1 199
     
    Hola,
    Probablemente porque hay una mezcla de formato,
    intenta poner toda la columna en Texto.. si no funciona prueba en Estándar..
    Tú dices.
    Hasta luego
    EDIT:
    Negativo, no funciona cambiando el formato.

    --
    La experiencia instruye más seguramente que el consejo. (André Gide)  
    Si te empeñas en un pote y suena hueco, no es necesariamente porque el pote esté vacío. ;-)(Confucio)
    0
  7. lermite222 Mensajes publicados 9042 Estado Colaborador 1 199
     
    intenta más bien con...
    Sub ChangerT_D() Dim Lig As Long, Col As Integer Col = 2 ' Para la columna B .. a adaptar. Nota: para la columna AN es 40 On Error resume Next For Lig = 2 To 250 'adaptar las filas Cells(Lig, Col) = CVDate(Cells(Lig, Col)) Next Lig End Sub

    dices.
    --
    La experiencia instruye más seguramente que el consejo. (André Gide)  
    Si te golpeas a una olla y suena hueca, no es necesariamente la olla la que está vacía. ;-)(Confucius)
    0
    1. Odeatho
       
      Gracias Lermitte22,
      siento que avanza mucho, te lo agradezco (no me olvido de los demás, eh :) )
      entonces digamos que no me lo ordena en orden ascendente ( pero eso no viene del formato, creo)
      Voy a darte el código exacto de la macro
      y también en las celdas donde no hay nada (ponía 250 para estar seguro de no pasarlo por alto, pero creo que solo hay unas 150 celdas llenas) hay 00/01/1900 pero creo que es porque considera que la celda vacía representa 0.

      Solo quiero entender ahora por qué no se ordena en el orden correcto.

      Sub TrierSelonLaDate()
      Dim f1 As Worksheet
      Set f1 = Worksheets("Actions GO")


      Dim Lig As Long, Col As Integer, ColDep As Integer

      Col = 40 ' Para la columna B .. a adaptar. Nota: para la columna AN es 40
      ColDep = 12

      On Error Resume Next
      For Lig = 2 To 250 'adaptar las filas
      Cells(Lig, Col).Value = Cells(Lig, ColDep).Value
      Cells(Lig, Col) = CVDate(Cells(Lig, Col))
      Next Lig

      Cells(1, Col) = 1

      Dim A As Long
      For A = 2 To 250


      Next A
      Cells(40, 1).Value = "1000"
      Dim ColDates As Integer

      ColDates = 40
      f1.Columns(ColDates).NumberFormat = "0"
      f1.Range("A1").CurrentRegion.Sort Key1:=Range("I250"), Order1:=xlAscending, Header:=xlGuess, _
      OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
      ', _DataOption1:=xlSortNormal
      f1.Columns(ColDates).NumberFormat = "dd/mm/yyyy"
      End Sub





      Ella probablemente esté mal escrita o no esté escrita como un código verdadero, lo siento de antemano.
      Te agradezco a todos
      0
  8. lermite222 Mensajes publicados 9042 Estado Colaborador 1 199
     
    Hola,
    S, creo que viene del formato,
    Primero lo pones en formato estándar o numérico (no recuerdo cuál) lo que, visto que Excel trata las fechas como números, traduce tus fechas en números y el ordenamiento se hace sobre números.
    Luego vuelves a poner el formato de fecha
    No lo ves porque va demasiado rápido.
    Pero es una buena idea a recordar para ordenar por fecha.
    A+
    EDIT:
    ¿Qué quieres decir con “no ordena en el orden correcto”? si quieres cambiar el sentido basta con cambiar xlAscending por xlDescending
    --
    La experiencia instruye más firmemente que el consejo. (André Gide)  
    Si te golpeas con una olla y suena hueco, no siempre es que la olla esté vacía. ;-)(Confucius)
    0
    1. Odeatho
       
      Sí Lermitte22, era el principio de base: copiar la columna de fecha, transformarla al formato de fecha, luego en estándar hacer un orden de menor a mayor y después reformatearla como fecha.

      cuando te digo que está en el orden incorrecto es algo así:

      15/11/2008
      15/10/2008
      15/05/2009
      31/10/2008
      10/08/2008
      31/10/2008
      31/10/2008
      26/10/2007
      15/10/2008
      15/10/2008


      por eso no entiendo muy bien qué está fallando, ¿no hay algo más simple que lo que escribí arriba solo para ordenar los números? no necesito reformatearlo como fecha al final ya que lo voy a copiar en una columna sin usar.
      0
  9. lermite222 Mensajes publicados 9042 Estado Colaborador 1 199
     
    Sin embargo, con la idea de cambiar el formato funciona impecable...
    Sub TrieDate() Dim Plage As Range Dim Col As Byte, LigDeb As Long, DerLig As Long Sheets("TriDate").Select Col = 6 'para la columna F LigDeb = 5 '1ª fila de tri DerLig = 14 Set Plage = Range(Cells(LigDeb, Col), Cells(DerLig, Col)) Plage.Select Selection.NumberFormat = "0" Selection.Sort Key1:=Range("F5"), Order1:=xlAscending, Header:=xlGuess, _ OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom Selection.NumberFormat = "dd/mm/yyyy" Range("F17").Select End Sub

    Resultado...
    26/10/2007 10/08/2008 15/10/2008 15/10/2008 15/10/2008 31/10/2008 31/10/2008 31/10/2008 15/11/2008 15/05/2009

    He probado con el ejemplo que das..
    Un saludo
    --
    La experiencia enseña con más seguridad que el consejo. (André Gide)  
    Si te golpeas un pote y suena hueco, no necesariamente es el pote el que está vacío. ;-) (Confucio)
    0
  10. lermite222 Mensajes publicados 9042 Estado Colaborador 1 199
     
    Un poco más automático...
    Sub TrieDate() Dim Plage As Range Dim Col As Byte, LigDeb As Long, DerLig As Long Sheets("TriDate").Select Col = 6 'para la columna F LigDeb = 5 '1ª fila de clasificación DerLig = Cells(65536, Col).End(xlUp).Row Set Plage = Range(Cells(LigDeb, Col), Cells(DerLig, Col)) Plage.NumberFormat = "0" Plage.Sort Key1:=Cells(LigDeb, Col), Order1:=xlAscending, Header:=xlGuess, _ OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom Plage.NumberFormat = "dd/mm/yyyy" End Sub


    --
    La experiencia instruye con más seguridad que el consejo. (André Gide)  
    Si te empeñas en un cubo y suena hueco, no necesariamente es el cubo el que está vacío. ;-) (Confucio)
    0
    1. Odeatho
       
      Gracias gente, va avanzando bien, casi no falta nada.

      Tengo un problema en realidad, tomé tu macro lermitte22 y cuando la ejecuto mis fechas se ordenan primero por día y luego por mes, así obtengo:

      01/01/2008
      01/03/2009
      01/07/2008
      01/08/2008
      01/08/2008
      01/09/2008
      01/11/2008
      02/10/2008
      02/10/2008
      03/09/2008
      03/10/2008
      03/10/2008
      03/11/2008
      (la lista es larga pero doy un ejemplo simple)
      Entonces pensé en quitar la última línea para ver cómo se presenta el formato y de hecho solo la celda 3 pasa a modo estándar (mi primera fila es la fila 2)
      Creo que todo el problema viene de que mi celda 1 en la columna de fechas es un texto, eso debe causar problemas para formatear toda la columna.
      Por eso cuando al principio intentaba copiar mi columna en la columna AN (vacía) y poner 1 como valor en estándar en la celda 1 para que la fila 1 no se moviera.
      Es complicado :s
      0
  11. lermite222 Mensajes publicados 9042 Estado Colaborador 1 199
     
    Hola,
    Incluso en texto eso debería cambiar, ¡excepto si hay espacios en las celdas!
    Para probar, pon en una columna vacía =NBCAR(..) y verifica si muestra el número de caracteres que ves.
    Si es más, me dices y te pasaré una macro que lo corrija
    --
    La experiencia instruye más seguramente que el consejo. (André Gide)
    Si te golpeas con una rodaja y suena hueca, no necesariamente es la rodaja la que está vacía. ;-)(Confucio)
    0