Imprimir página | Cerrar ventana

Selección de celdas que cumplen una condición

Impreso de: Foro de Access y VBA
Categoría: Otros de Microsoft: Windows y Office
Nombre del foro: Excel
Descripción del foro: Foro de Excel y VBA de Excel
URL: http://www.mvp-access.com/foro/forum_posts.asp?TID=84038
Fecha de impresión: 19/Noviembre/2019 a las 04:41


Tema: Selección de celdas que cumplen una condición
Publicado por: jmpm
Asunto: Selección de celdas que cumplen una condición
Fecha de publicación: 24/Octubre/2018 a las 19:19
Buenas, en realidad lo que busco es crear una macro que encuentre entre todas las celdas de una columna (A) aquellas cuyo valor esté comprendido entre un determinado rango (100<valor de la celda<200) y seleccionar las celdas de una columna diferente (D) que se encuentren en las filas correspondientes a las celdas de la columna A que cumplían las condiciones, para después calcular el máximo entre esos valores seleccionados en D. Gacias de antemano



Respuestas:
Publicado por: emiliove
Fecha de publicación: 24/Octubre/2018 a las 20:21
Confírmame que estas hablando de Excel, para mover el hilo al foro adecuado.

Saludos.


Publicado por: jmpm
Fecha de publicación: 25/Octubre/2018 a las 11:25
Correcto, pero pregunté aquí porque VBA es lo que se utiliza en Excel para trabajar con macros.

Un saludo.


Publicado por: AnSanVal
Fecha de publicación: 25/Octubre/2018 a las 18:06
Esa misma pregunta la hiciste en otro foro, y te respondí.

Como has copiado el texto de aquella consulta y lo has pegado aquí, haré lo mismo con mi respuesta.


Pego.

Título: Crear una macro en excel que haga lo mismo que la función max.si.conjunto 

- VBA es menos  rápido/eficiente que cualquier otro lenguaje de más bajo nivel.

- Las funciones integradas fueron programadas en  un lenguaje de más bajo nivel que el que empleamos en las macros.

- Por tanto...

- ... cualquier macro que haga «lo mismo» que una Función integrada, será menos rápida/eficiente que dicha función.


¿Por que quieres hacerlo con una macro?


Fin pego.





-------------
Aprendemos viendo respuestas de otros, también intentando resolver dudas (intenta ayudar cuando puedas/sepas).

Mi http://achinet.mvp-access.es/" rel="nofollow - sitio_web con ejemplos Excel.


Publicado por: lbauluz
Fecha de publicación: 25/Octubre/2018 a las 18:17
Asumo que en la columna A solo tienes números, que no está ordenada  y que no hay filas en blanco
Así mismo, asumo que en la columna D solo tienes números

Necesitas:
0 Tener una variable con el valor máximo = 0 )es decir, limpiar la variable)
1 ver cual es la última fila en A, para eso te voy a dar el código
    ' Ver numero de filas en columna A
    Range("A1").Select
    Selection.End(xlDown).Select
    ActiveWindow.SmallScroll Down:=3
    lMaxRows = ActiveCell.Row

Ahora ya sabes cuantas filas tienes

2 necesitas  leer uno a uno todos los valores de la columna A y para cada fila
Es decir, leer en un bucle FOR n = 1 (supongo que empieza en la fila 1) hasta  A lMaxRows 

3 verificar si el valor en esa celda está en el rango que buscas
Para tomar dicho valor puedes usar algo similar a esto:
X = Range("A" & n).Value
Y comparar es facil, if X > 100 y X < 200

Si está en el rango, leer el valor de la columna D 
Y = Range("D" & n).Value

Ahora comparas la variable con el valor máximo  con Y

Si Y es MENOR que la variable la variable tiene que ser igual a Y (almacenas en Y el mayor valor)
fin del bucle FOR n...

Y con eso, al final tienes el valor máximo.

Un saludo.

Luis



-------------
El Búho es mi ídolo caido


Publicado por: AnSanVal
Fecha de publicación: 25/Octubre/2018 a las 18:54
Hola Luis, con filtro avanzado es una sola línea de código y lo entrega 'hecho' la grabadora. Wink




-------------
Aprendemos viendo respuestas de otros, también intentando resolver dudas (intenta ayudar cuando puedas/sepas).

Mi http://achinet.mvp-access.es/" rel="nofollow - sitio_web con ejemplos Excel.


Publicado por: lbauluz
Fecha de publicación: 25/Octubre/2018 a las 20:40
Muy buenas Don Antonio.

Perdón por el pisotón, no fue intencionado.

La pregunta tal como está hecha, da la sensación de ser para algún tipo de práctica (¿escolar?) por eso le he dado las pistas más que suficientes para que que entienda la lógica de lo que debe hacer haciéndolo todo con VBA "puro, duro y sencillo"

-------------
El Búho es mi ídolo caido


Publicado por: AnSanVal
Fecha de publicación: 25/Octubre/2018 a las 22:15
¿Pisotón? pues no lo noté, no dolió nada.  Clown

«... da la sensación de ser para algún tipo de práctica (¿escolar?)…» Pues puede que tengas razón y de ahí que «no quiera» utilizar MAX.SI.CONJUNTO.




-------------
Aprendemos viendo respuestas de otros, también intentando resolver dudas (intenta ayudar cuando puedas/sepas).

Mi http://achinet.mvp-access.es/" rel="nofollow - sitio_web con ejemplos Excel.


Publicado por: jmpm
Fecha de publicación: 29/Octubre/2018 a las 15:38
Hola Antonio, como ya te contesté en aquel foro en Excel 2013 no tengo la opción max.si.conunto y viendo que era la única repuesta que obtenía, busqué otro foro.

Un saludo


Publicado por: jmpm
Fecha de publicación: 29/Octubre/2018 a las 15:46
Gracias por contestar Luis, lo que asumes es correcto. Ya he conseguido hacer un código que cumple con lo que quiero excepto que tarda 8 min en darme las soluciones, pues tiene que recorrer del orden de 30000 filas. A ver si pudieras ayudarme a mejorarlo

Esto ha sido lo que he hecho:

Sub IfMaxCondition()
    
Dim rpm As String
Dim finalrow As Integer
Dim i As Integer
Dim max As Double

Sheets("Vibration1").Range("P1:Z50000").ClearContents
finalrow = Sheets("Vibration1").Range("A50000").End(xlUp).Row
'655
For i = 2 To finalrow
    If Cells(i, 2) < 656 And Cells(i, 2) > 654 Then
        Cells(i, 8).Copy
        Range("P10000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
    End If
Next i
'690
For i = 2 To finalrow
    If Cells(i, 2) < 693 And Cells(i, 2) > 687 Then
        Cells(i, 8).Copy
        Range("R10000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
    End If
   Next i
'730
   For i = 2 To finalrow
    If Cells(i, 2) < 733 And Cells(i, 2) > 727 Then
        Cells(i, 8).Copy
        Range("T10000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
    End If
   Next i
'842
   For i = 2 To finalrow
    If Cells(i, 2) < 845 And Cells(i, 2) > 839 Then
        Cells(i, 8).Copy
        Range("V10000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
    End If
   Next i
'860
   For i = 2 To finalrow
    If Cells(i, 2) < 863 And Cells(i, 2) > 857 Then
        Cells(i, 8).Copy
        Range("X10000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
    End If
   Next i

Range("P2").Select

max = Application.WorksheetFunction.max(Range("P2:P10000"))
Range("Q2") = max
max = Application.WorksheetFunction.max(Range("R2:R10000"))
Range("S2") = max
max = Application.WorksheetFunction.max(Range("T2:T10000"))
Range("U2") = max
max = Application.WorksheetFunction.max(Range("V2:V10000"))
Range("W2") = max
max = Application.WorksheetFunction.max(Range("X2:X10000"))
Range("Y2") = max

Hoja2.Select

Range("A1") = Sheets("Vibration1").Range("Q2")
Range("B1") = Sheets("Vibration1").Range("S2")
Range("C1") = Sheets("Vibration1").Range("U2")
Range("D1") = Sheets("Vibration1").Range("W2")
Range("E1") = Sheets("Vibration1").Range("Y2")


End Sub


Publicado por: lbauluz
Fecha de publicación: 29/Octubre/2018 a las 19:13
Si te funciona, prueba así, haciendo el bucle una sola vez.

No he mirado nada más que mejorar el bucle, así que supongo que funcionará como quieres y tardará aproximadamente una quinta parte del tiempo.

Por otro lado, he añadido el Application.ScreenUpdating = False que hace que la pantalla no se actualice hasta el final, suele ahorrar mucho tiempo.

Suerte.

Luis


Sub IfMaxCondition()
    
Dim rpm As String
Dim finalrow As Integer
Dim i As Integer
Dim max As Double

Application.ScreenUpdating = False

Sheets("Vibration1").Range("P1:Z50000").ClearContents
finalrow = Sheets("Vibration1").Range("A50000").End(xlUp).Row
'655
For i = 2 To finalrow
    Cells(i, 8).Copy
    If Cells(i, 2) = 655 Then ' Cells(i, 2) < 656 And Cells(i, 2) > 654
        Range("P10000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
    ElseIf Cells(i, 2) < 693 And Cells(i, 2) > 687 Then
        Range("R10000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
    ElseIf Cells(i, 2) < 733 And Cells(i, 2) > 727 Then
        Range("T10000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
    ElseIf Cells(i, 2) < 845 And Cells(i, 2) > 839 Then
        Range("V10000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
    ElseIf Cells(i, 2) < 863 And Cells(i, 2) > 857 Then
        Range("X10000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
    End If
Next i


Range("P2").Select ' ???
Range("Q2").Value = Application.WorksheetFunction.max(Range("P2:P10000"))
Range("S2").Value = Application.WorksheetFunction.max(Range("R2:R10000"))
Range("U2").Value = Application.WorksheetFunction.max(Range("T2:T10000"))
Range("W2").Value = Application.WorksheetFunction.max(Range("V2:V10000"))
Range("Y2").Value = Application.WorksheetFunction.max(Range("X2:X10000"))

Hoja2.Select

Range("A1").Value = Sheets("Vibration1").Range("Q2")
Range("B1").Value = Sheets("Vibration1").Range("S2")
Range("C1").Value = Sheets("Vibration1").Range("U2")
Range("D1").Value = Sheets("Vibration1").Range("W2")
Range("E1").Value = Sheets("Vibration1").Range("Y2")

Application.ScreenUpdating = True
End Sub


-------------
El Búho es mi ídolo caido


Publicado por: AnSanVal
Fecha de publicación: 29/Octubre/2018 a las 20:27

Prueba con una fórmula matricial:

   {=MAX(($A$2:$A$30>=100)*($A$2:$A$30<=200)*$D$2:$D$30)}

Las llaves no debes escribirlas, como fórmula matricial que es, debes entrarla con Ctrl +Mayúscula + Intro (no con solo Intro).





-------------
Aprendemos viendo respuestas de otros, también intentando resolver dudas (intenta ayudar cuando puedas/sepas).

Mi http://achinet.mvp-access.es/" rel="nofollow - sitio_web con ejemplos Excel.


Publicado por: jmpm
Fecha de publicación: 30/Octubre/2018 a las 10:28
Muchísimas gracias Luis! Ha pasado de durar 10 min a 2 min


Publicado por: jmpm
Fecha de publicación: 30/Octubre/2018 a las 10:31
Ojalá me hubiera funcionado porque habría sido mucho más rápido, pero me aparece #VALOR en la celda. Gracias de todos modos


Publicado por: AnSanVal
Fecha de publicación: 30/Octubre/2018 a las 12:42
 

Interpreto que con  «Ojalá me hubiera funcionado... »  te refieres a la fórmula (lo de Luis te funciona).


Algo debes tener mal, la fórmula  funciona:


http://1drv.ms/u/s!AiHNLEcByIEjjljw27-DnA3SUqFE" rel="nofollow - https://1drv.ms/u/s!AiHNLEcByIEjjljw27-DnA3SUqFE

http://1drv.ms/u/s!AiHNLEcByIEjjljw27-DnA3SUqFE" rel="nofollow -

Lo de #¡VALOR!  normalmente es  porque alguno de los valores calculados NO es un número, por ejemplo si incluyes los títulos en los rangos o (p.e.) si tienes algún texto en la columna D.


En esta segunda imagen,...

https://1drv.ms/u/s!AiHNLEcByIEjjlmEJ9M3qgeRgX6h" rel="nofollow - https://1drv.ms/u/s!AiHNLEcByIEjjlmEJ9M3qgeRgX6h

https://1drv.ms/u/s!AiHNLEcByIEjjlmEJ9M3qgeRgX6h" rel="nofollow -

... me da error #¡VALOR!  porque la celda D10 incluye despues del ocho un Caracter(160).






-------------
Aprendemos viendo respuestas de otros, también intentando resolver dudas (intenta ayudar cuando puedas/sepas).

Mi http://achinet.mvp-access.es/" rel="nofollow - sitio_web con ejemplos Excel.


Publicado por: lbauluz
Fecha de publicación: 31/Octubre/2018 a las 04:03
Intenta el método de AnSanVal, es el método correcto para lo que quieres, e infinitamente más rápido


-------------
El Búho es mi ídolo caido



Imprimir página | Cerrar ventana