Macro Para Extraer Valores De Fecha Máximo y Mínimo

De nuevo en busca de un poco de ayuda por acá. Se trata de lo siguiente: tengo una hoja con dos columnas, en la columna "A" van las fechas y en la columna "B" los precios.

Quisiera extraer los valores máximos o mínimos entre dos fechas, según se especifique para un numero determinado de registros.

Es decir, en una celda escribo una fecha inicial, en otra una fecha final, en otra "mínimo": o "máximo", según convenga y en otra celda "5", estas celdas actuarían como filtro dando como resultado al ejecutar la macro un rango de fechas y precios atendiendo al filtro especificado.

Tengo Excel 2016

1 Respuesta

Respuesta
1

este es el resultado de la macro

Y esta es la macro solo cambia las referencias A1, e1, e2, e4 y e5 por las referencias que estés usando

Sub filtrar()
Dim funcion As WorksheetFunction
Set DATOS = Range("a1").CurrentRegion
Set funcion = WorksheetFunction
fecha_i = Range("e1")
fecha_f = Range("e2")
parametro = UCase(Range("e4"))
With DATOS
    cuenta = funcion.CountIfs(.Columns(1), ">=" & CDbl(fecha_i), .Columns(1), "<=" & CDbl(fecha_f))
    fila = funcion.Match(CDbl(fecha_i), .Columns(1), 0)
    Set FECHAS = .Rows(fila).Resize(cuenta)
    If parametro = "MÍNIMO" Then
        Range("D5") = "VALOR MINIMO"
        Range("E5") = funcion.Min(FECHAS.Columns(2))
    Else
        Range("D5") = "VALOR MÁXIMO"
        Range("E5") = funcion.Max(FECHAS.Columns(2))
    End If
End With
Set DATOS = Nothing: Set FECHAS = Nothing
Set funcion = Nothing
End Sub

Gracias por su oportuna respuesta. La macro funciona, pero creo que la explicación que di no fue suficientemente clara. Es decir la macro me devuelve el el precio mas alto para el rango de fecha especificado; pero lo que yo pretendí exponer es que dado un rango de fechas y un numero de fechas determinado y un parámetro, me devolviera cuales son las fechas con sus respectivos precios. Adjunto un capture

Entonces prueba con esta macro

Sub filtrar()
Dim funcion As WorksheetFunction
Set DATOS = Range("a2").CurrentRegion
Set funcion = WorksheetFunction
fecha_i = Range("e2")
fecha_f = Range("e3")
parametro = UCase(Trim(Range("e5")))
dias = Val(Range("e4"))
Set resultado = Range("g2").Resize(dias, 2)
With DATOS
    cuenta = funcion.CountIfs(.Columns(1), ">=" & CDbl(fecha_i), .Columns(1), "<=" & CDbl(fecha_f))
    fila = funcion.Match(CDbl(fecha_i), .Columns(1), 0)
    Set fechas = .Rows(fila).Resize(cuenta)
    If parametro = "MÍNIMO" Then
        For i = 1 To dias
            res = funcion.Small(fechas.Columns(2), i)
            fila = funcion.Match(res, fechas.Columns(2), 0)
            With resultado
                .Cells(i, 2) = res
                .Cells(i, 1) = fechas.Cells(fila, 1)
                .Cells(i, 1).NumberFormat = "dd/mm/yyyy"
            End With
        Next i
    Else
        For i = 1 To dias
            res = funcion.Large(fechas.Columns(2), i)
            fila = funcion.Match(res, fechas.Columns(2), 0)
            With resultado
                .Cells(i, 2) = res
                .Cells(i, 1) = fechas.Cells(fila, 1)
                .Cells(i, 1).NumberFormat = "dd/mm/yyyy"
            End With
        Next i
    End If
End With
Set DATOS = Nothing: Set fechas = Nothing
Set funcion = Nothing
End Sub

Gracias amigo James Bond. Solo un detalle. La parte que se refiere al parametro no pude hacerla funcionar.
Veo en tu macro una linea que se refiere a "If parámetro = "MÍNIMO" Then", pero la macro da el mismo resultado independientemente
que el valor de la celda correspondiente sea "Minimo" o "Maximo", lo cual no es lo que se busca.
Lo que se busca es que si el valor es "Minimo" devuelva x cantidad de resultados correspondientes a los precios minimos y sus fechas;
de igual forma si el valor que se escoge es "Máximo" x cantidad de resultados correspondientes a los precios máximos y sus fechas

Hay un detalle en mi maquina el mínimo y el máximo lo pone con acentos así mínimo, máximo, así que tuve que poner en la macro la condición if con MÍNIMO solo cambia en la macro este parámetro por MÍNIMO así con letras mayúsculas. Y con esto la macro debe responder

Muchísimas gracias por su colaboración, ya he puesto  a funcionar la macro como debe ser.  

Saludos de nuevo. He estado trabajando con esta macro y me ha sido de mucha utilidad, pero me gustaría sacarle un poco mas. Se trata de lo siguiente: he agregado otras columnas a las fechas y he he creado  4 categorías de resultados, a saber el valor máximo superior, el valor máximo inferior, el valor mínimo superior y el valor mínimo inferior; siempre que se aplique el filtro descrito. He logrado que la modificación funcione, pero inconsistentemente. 

Como no tengo suficientes cono

Sub MaxMax()
Range("q8:r26").Select
Selection.ClearContents
Dim funcion As WorksheetFunction
Set DATOS = Range("a8:a500").CurrentRegion
Set funcion = WorksheetFunction
fecha_i = Range("r1")
fecha_f = Range("r2")
parametro = UCase(Trim(Range("r4")))
dias = Val(Range("r3"))
Set resultado = Range("q7").Resize(dias, 2)
With DATOS
cuenta = funcion.CountIfs(.Columns(1), ">=" & CDbl(fecha_i), .Columns(1), "<=" & CDbl(fecha_f))
fila = funcion.Match(CDbl(fecha_i), .Columns(1), 0)
Set fechas = .Rows(fila).Resize(cuenta)
If parametro = "Minimo" Then
For i = 1 To dias
res = funcion.Small(fechas.Columns(2), i)
fila = funcion.Match(res, fechas.Columns(2), 0)
With resultado
.Cells(i, 2) = res
.Cells(i, 1) = fechas.Cells(fila, 1)
.Cells(i, 1).NumberFormat = "dd/mm/yyyy"
End With
Next i
Else
For i = 1 To dias
res = funcion.Large(fechas.Columns(3), i)
fila = funcion.Match(res, fechas.Columns(3), 0)
With resultado
.Cells(i, 2) = res
.Cells(i, 1) = fechas.Cells(fila, 1)
.Cells(i, 1).NumberFormat = "dd/mm/yyyy"
End With
Next i
End If
End With
Set DATOS = Nothing: Set fechas = Nothing
Set funcion = Nothing
Range("q7:r26").Select
ActiveWorkbook.Worksheets("MaxMin").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("MaxMin").Sort.SortFields.Add2 Key:=Range("r7:r26") _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("MaxMin").Sort
.SetRange Range("q7:r26")
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("r7:r26").Select
Selection.NumberFormat = "0.00000000"
Range("r7").Select
End Sub

Sub MaxMin()
Range("q32:r51").Select
Selection.ClearContents
Dim funcion As WorksheetFunction
Set DATOS = Range("a8:a500").CurrentRegion
Set funcion = WorksheetFunction
fecha_i = Range("r1")
fecha_f = Range("r2")
parametro = UCase(Trim(Range("r29")))
dias = Val(Range("r3"))
Set resultado = Range("q32").Resize(dias, 2)
With DATOS
cuenta = funcion.CountIfs(.Columns(1), ">=" & CDbl(fecha_i), .Columns(1), "<=" & CDbl(fecha_f))
fila = funcion.Match(CDbl(fecha_i), .Columns(1), 0)
Set fechas = .Rows(fila).Resize(cuenta)
If parametro = "Minimo" Then
For i = 1 To dias
res = funcion.Small(fechas.Columns(2), i)
fila = funcion.Match(res, fechas.Columns(2), 0)
With resultado
.Cells(i, 2) = res
.Cells(i, 1) = fechas.Cells(fila, 1)
.Cells(i, 1).NumberFormat = "dd/mm/yyyy"
End With
Next i
Else
For i = 1 To dias
res = funcion.Large(fechas.Columns(12), i)
fila = funcion.Match(res, fechas.Columns(12), 0)
With resultado
.Cells(i, 2) = res
.Cells(i, 1) = fechas.Cells(fila, 1)
.Cells(i, 1).NumberFormat = "dd/mm/yyyy"
End With
Next i
End If
End With
Set DATOS = Nothing: Set fechas = Nothing
Set funcion = Nothing
Range("q32:r51").Select
ActiveWorkbook.Worksheets("MaxMin").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("MaxMin").Sort.SortFields.Add2 Key:=Range("r32:r51") _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("MaxMin").Sort
.SetRange Range("q32:r51")
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("r32:r51").Select
Selection.NumberFormat = "0.00000000"
Range("r32").Select
End Sub

Sub MinMax()
Range("q56:r75").Select
Selection.ClearContents
Dim funcion As WorksheetFunction
Set DATOS = Range("a8:a500").CurrentRegion
Set funcion = WorksheetFunction
fecha_i = Range("r1")
fecha_f = Range("r2")
parametro = UCase(Trim(Range("r53")))
dias = Val(Range("r3"))
Set resultado = Range("q56").Resize(dias, 2)
With DATOS
cuenta = funcion.CountIfs(.Columns(1), ">=" & CDbl(fecha_i), .Columns(1), "<=" & CDbl(fecha_f))
fila = funcion.Match(CDbl(fecha_i), .Columns(1), 0)
Set fechas = .Rows(fila).Resize(cuenta)
If parametro = "Minimo" Then
For i = 1 To dias
res = funcion.Small(fechas.Columns(4), i)
fila = funcion.Match(res, fechas.Columns(4), 0)
With resultado
.Cells(i, 2) = res
.Cells(i, 1) = fechas.Cells(fila, 1)
.Cells(i, 1).NumberFormat = "dd/mm/yyyy"
End With
Next i
Else
For i = 1 To dias
res = funcion.Large(fechas.Columns(4), i)
fila = funcion.Match(res, fechas.Columns(4), 0)
With resultado
.Cells(i, 2) = res
.Cells(i, 1) = fechas.Cells(fila, 1)
.Cells(i, 1).NumberFormat = "dd/mm/yyyy"
End With
Next i
End If
End With
Set DATOS = Nothing: Set fechas = Nothing
Set funcion = Nothing
Range("q56:r75").Select
ActiveWorkbook.Worksheets("MaxMin").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("MaxMin").Sort.SortFields.Add2 Key:=Range("r56:r75") _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("MaxMin").Sort
.SetRange Range("q56:r75")
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("r56:r75").Select
Selection.NumberFormat = "0.00000000"
Range("r56").Select
End Sub

cimientos, clone la macro original para hacer una por cada categoría de resultados y cambie algunos valores, he aquí lo que hice:

Se entiende mejor si subes una pantalla con la información que agregaste y el resultado que quieres lograr.

Así como lo planteas es otra macro la que tiene que hacerse para que de los resultados como se muestra en la imagen

la macro hace 4 filtros a la vez y esta es la macro

Sub filtrar_maximos_minimos()
inicio = Range("f2")
Final = Range("f3")
cantidad = Range("f4")
Set datos = Range("a1").CurrentRegion
datos.AutoFilter
inicio = ">=" & Format(inicio, "mm/dd/yyyy")
Final = "<=" & Format(Final, "mm/dd/yyyy")
ActiveSheet.Range(datos.Address).AutoFilter Field:=1, Criteria1:= _
        inicio, Operator:=xlAnd, Criteria2:=Final
        datos.SpecialCells(xlCellTypeVisible).Copy Destination:=Range("k1")
Set tabla = Range("k1").CurrentRegion
With tabla
    filas = .Rows.Count
    .Sort key1:=Range(.Columns(2).Address), order1:=xlDescending, Header:=xlYes
End With
datos.AutoFilter
Range("e9").Resize(1000, 6).Clear
Set tabla1 = Range("e9").Resize(cantidad, 2)
Set tabla2 = Range("h9").Resize(cantidad, 2)
Set tabla3 = tabla1.Rows(cantidad + 4).Resize(cantidad, 2)
Set tabla4 = tabla2.Rows(cantidad + 4).Resize(cantidad, 2)
tabla1.Value = tabla.Cells(2, 1).Resize(cantidad, 2).Value
tabla2.Value = tabla.Cells(filas - cantidad + 1, 1).Resize(cantidad, 2).Value
With tabla
    filas = .Rows.Count
    .Sort key1:=Range(.Columns(3).Address), order1:=xlDescending, Header:=xlYes
End With
With tabla3
    .Columns(1).Value = tabla.Cells(2, 1).Resize(cantidad, 1).Value
    .Columns(2).Value = tabla.Cells(2, 3).Resize(cantidad, 1).Value
    .Cells(0, 1) = "PRECIO MINIMO MAS ALTO"
End With
With tabla4
    .Columns(1).Value = tabla.Cells(2, 1).Resize(cantidad, 1).Value
    .Columns(2).Value = tabla.Cells(filas - cantidad + 1, 3).Resize(cantidad, 1).Value
    .Cells(0, 1) = "PRECIO MINIMO MAS BAJO"
End With
tabla.Clear
Set tabla = Nothing: Set tabla1 = Nothing
Set tabla2 = Nothing: Set tabla3 = Nothing: Set tabla4 = Nothing
End Sub

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas