Buscando una macro para ocultar filas con condicionante
Tengo una hoja de excel y necesito una macro que me oculte filas que contengan un "NO" en la columna d.
En la columna "c" esta las casillas de verificación de las que dependen los "si" o "no" que están en la Columna D.
La casilla de verificación cambia el valor de si a no y al revés de las filas que se encuentran a su derecha.
Yo necesito una macro que me oculte automaticament todas las casillas que tengan "NO" en d o que al activar su casilla de verificación se ejecute la macro.
1 respuesta
.
Buenas,
La siguiente rutina ocultará las líneas que estén contengan un NO en la columna D.
Coloca esta secuencia en un módulo de Visual Basic.
Sub OcultaNo()
'Primero muestra todas las filas:
Rows("1:61560").EntireRow.Hidden = False
Cells(1, 4).Select
Do While Not IsEmpty(ActiveCell)
If ActiveCell.Value = "NO" Then ActiveCell.EntireRow.Hidden = True
ActiveCell.Offset(1, 0).Select
Loop
Cells(1, 4).Select
End Sub
Espero que te sirva.
Abrazo
Fernando
.
.
Sólo ten en cuenta cuál es la primera celda ocupada de la columna D, luego la macro se detendrá cuando encuentre una celda vacía en esa columna.
En esta segunda versión, el número de la primera fila ocupada es una variable (PrimFila) cuyo valor puedes cambiar para adaptarla a tu modelo:
Sub OcultaNo() 'variable de primera fila ocupada: PrimFila = 4 'Primero muestra todas las filas: Rows("1:61560").EntireRow.Hidden = False Cells(PrimFila, 4).Select Do While Not IsEmpty(ActiveCell) If ActiveCell.Value = "NO" Then ActiveCell.EntireRow.Hidden = True ActiveCell.Offset(1, 0).Select Loop Cells(PrimFila, 4).Select End Sub
Saludos
Fernando
.
hola buenas
El código funciona bien. El problema pude venir por la longitud de la hoja. Tiene muchísimos registros ya que es todo un mes y cada día unos 80 trababajadores y cada trabajador tiene dos filas el horario normal y el cambiado. ¿Habría alguna posibilidad de la macro solo afectara a la fila en la que está la casilla de verificación y la justamente inferior y después se va asignando a cada casilla de verificación esta macro?... osea que solo ocultara el "NO" de ese trabajador.
Aun así muchísimas gracias por ayudarme.
.
Buenos días, Luis
Viendo la estructura de la planilla -siempre ayuda- comprendo mejor tu inquietud.
La rutina que te había pasado afecta a toda la hoja y lo que requieres es que sólo cambie el status de la persona donde cambias la marca en la casilla de verificación. A su vez, tal marca cambia el contenido de lo que está en la columna D, si es que te hubiera entendido correctamente.
A partir de tal interpretación, ensayé distintas soluciones pero -en todas ellas- la casilla de verificación complica más que resuelve. Mi experiencia dice que el uso masivo de ella es poco práctico aunque estéticamente pueda agradar. Además, cada vez que agregas una tienes que indicarle qué celda tiene asociada para que funcione correctamente.
Por ello, para resolver tu problema propongo que uses una celda de esa columna C para poner un simple Sí o No en lugar del tilde en la casilla. Eventualmente, puedes usar una lista de validación con un menú, descolgable, aunque también aporta poco.
Esto daría lugar a una solución que, cada vez que cambies la selección de esa celda y elijas Sí (Es decir que sí cambió), una rutina de VBA se encargaría de ocultar la fila de abajo de donde hiciste la selección.
Si aceptaras este cambio, que recomiendo fuertemente, sólo tendrías que hacer lo siguiente:
1.- Botón derecho del mouse sobre la solapa de la hoja donde quieres que esto funcione:
Esto te abrírá una pantalla del Editor de Visual Basic, pero para esa hoja específica.
2.- En el panel de la derecha pega el siguiente código:
Private Sub Worksheet_Change(ByVal Target As Range) Set isect = Application.Intersect(Range("C:C"), Target) If Not isect Is Nothing Then 'MsgBox "Cambio " & Target.Address If Not UCase(Target.Value) <> "NO" Then Target.Offset(1).EntireRow.Hidden = False Else Target.Offset(1).EntireRow.Hidden = True End If End If Set isect = Nothing End Sub
Listo, puedes cerrar el editor de VBA y ya estará en funcionamiento.
Básicamente ésta rutina está pendiente de que haya un cambio en la columna C. Si lo hay y cambia a Sí cualquier celda de esa columna, oculta la línea inmediata siguiente. También prevé que si cambiaras a No, muestre la línea que estuviera oculta.
Quiero comentarte que intenté esta misma solución usando las casillas de verificación pero VBA no captura el cambio en la casilla aunque estuviera asociado a una celda en la columna C.
En caso de que esta solución te pareciera superadora, te agrego una pantalla para que veas como colocar un descolgable que te permita elegir entre Si/No en una celda:
Luego puedes copiar y pegar la celda con ese menú a todas las celdas que necesites (Proceso lejos más simple que copiar una casilla y reasignar la celda vinculada;)
Es más: Puede ser que con esta solución -adicionalmente- las fórmulas de la columna D no sean necesarias. Pero tu sabrás.
Bien, Luis, espero que esta solución te satisfaga.
Un abrazo
Fernando
.
Hola Fernando:
Te agradezco nuevamente tu molestia.
El código que me has enviado esta bien salvo una cosilla.
Cada trabajador tiene dos líneas.
Horario normal..."NO"... no hay cambio de horario
Horario cambiado..."SI"... se le ha realizado un cambio.
Normalmente los trabajadores tendrán un NO por lo que la fila primera es su horario normal
Si le doy a SI la primera fila debería ocultarse y la segunda verse.
y si le doy a NO... viceversa. Con lo que mi objetivo era que cada trabajador solo tuviera una línea visible... o la primera... horario normal (NO) ... o la segunda... horario cambiado (SI).
En la columna DE te he puesto 1 y 2 para que veas a lo que me refiero.
.
Bien, parece que estamos más cerca.
Entiendo lo que mencionas y la misma rutina adaptada hace eso que solicitas.
Private Sub Worksheet_Change(ByVal Target As Range) Set isect = Application.Intersect(Range("C:C"), Target) If Not isect Is Nothing Then If UCase(Target.Value) = "SI" Then Target.Offset(0).EntireRow.Hidden = True Target.Offset(1).EntireRow.Hidden = False Else Target.Offset(0).EntireRow.Hidden = False Target.Offset(1).EntireRow.Hidden = True End If End If Set isect = Nothing End Sub
En caso de que la celda cambie a Sí ocultará esa y mostrará la inferior. En cambio si la colocas en No mostrará esa y ocultará la inferior.
En este punto me ofrece duda que la celda que comanda si mostrar o ocultar puede quedar, precisamente, oculta porque elegiste sí. A menos que tu proceso prevéa mostrar todas las filas antes de hacer estas selecciones.
Cualquier duda, consultame de nuevo.
Abrazo
Fernando
No en principio solo me interesa que muestre una fila por trabajador desde el principio.
este ultimo codigo funciona bien al principio pero como todos los trabajadores van uno detrás de otro se va comiendo filas en el segundo cambio de la casilla "SI" "NO". casillas que ya no correspon den a ese trabajador.
un saludo.
Me ha pasad el código que aparece abajo que pinchando en la fila DE se muestra o no se muestra la fila pero me daja todos los valores en si y o se como poner que el cambio esta activado o no
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Dim rng As Range Dim y& Set rng = Range("D11:D24") Application.ScreenUpdating = False If Not Intersect(Target, rng) Is Nothing Then With Target y = IIf(.Row Mod 2, 1, -1) If .Value = "SI" Then .Value = "SI" .EntireRow.Hidden = True .Offset(y).Value = "SI" .Offset(y).EntireRow.Hidden = False Else .Value = "SI" .EntireRow.Hidden = False .Offset(y).Value = "NO" .Offset(y).EntireRow.Hidden = True End If End With Cancel = True End If Application.ScreenUpdating = True End Sub
.
Buenos días, Luis
Me parece que hubo un problema de interpretación.
Si te oculta lineas de otro empleado, es que también pusiste el selector SI/NO en la segunda fila; en realidad sólo debería haber uno por cada par de líneas colocado en la primera de ellas.
Comentame si no es así como lo tienes configurado.
Respecto al otro código, poco puedo opinar por respeto a quien te lo haya pasado. Pero me parece que no va a funcionar. De todos modos para resolver el problema del SI, reemplaza la segunda línea:
... Else .Value = "SI" ...
por:
... Else .Value = "NO" ...
Tal vez te funcione así.
Saludos
Fernando
.
Hola Fernando:
Si lo tengo en la primera línea de las dos de cada trabajador pero al ocultarse ya no me deja volver a cambiar del SI al NO.
No se si estoy haciendo algo mal...
.
Claro, Luis, por eso te había comentado antes:
En este punto me ofrece duda que la celda que comanda si mostrar o ocultar puede quedar, precisamente, oculta porque elegiste sí. A menos que tu proceso prevea mostrar todas las filas antes de hacer estas selecciones.
Me parece que podemos resolver el funcionamiento de la planilla simplemente colocando el selector en ambas celdas y con una tercera opción que es <blanco>. Es decir que si borras el contenido de la celda, se muestren ambas líneas para que puedas elegir qué hacer.
Si estuvieras de acuerdo, procede como te indico a continuación:
1.- Borra la rutina de VBA que tengas para esa hoja. Para que no se actives mientras haces el paso 2.
2.- Coloca el selector SI/NO en todas las celdas.
3.- Activa "Ver Código" con botón derecho sobre la pestaña de esa hoja y pega este código:
Private Sub Worksheet_Change(ByVal Target As Range) If Target.Rows.Count = 1 Then Qlin = IIf(Target.Offset(0, 2).Value = Target.Offset(-1, 2).Value, 2, 1) Set isect = Application.Intersect(Range("C:C"), Target) If Not isect Is Nothing Then If UCase(Target.Value) = "SI" Then If Qlin = 2 Then Target.Offset(-1).EntireRow.Hidden = True Target.Offset(0).EntireRow.Hidden = False Else Target.Offset(1).EntireRow.Hidden = False Target.Offset(0).EntireRow.Hidden = True End If ElseIf UCase(Target.Value) = "NO" Then If Qlin = 2 Then Target.Offset(-1).EntireRow.Hidden = False Target.Offset(0).EntireRow.Hidden = True Else Target.Offset(1).EntireRow.Hidden = True Target.Offset(0).EntireRow.Hidden = False End If Else If Qlin = 2 Then Target.Offset(-1).EntireRow.Hidden = False Target.Offset(0).EntireRow.Hidden = False Else Target.Offset(1).EntireRow.Hidden = False Target.Offset(0).EntireRow.Hidden = False End If End If End If Set isect = Nothing End If End Sub
Es un poco más compleja, pero prevé todos los casos y no afecta a las celdas de otra persona.
Ante cualquier problema, recuerda que presionando la tecla "supr" o "Del", la rutina te mostrará ambas líneas de esa persona.
Espero que ahora sí esté resuelto.
Abrazo
Fernando
.
- Compartir respuesta