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

Respuesta
1

.

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

.

¡Gracias! 

Voy a probarla

          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

.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas