Cómo permitir Agrupar/Desagrupar en hoja protegida?

Estiamd@s,

Tengo una hoja que está protegida (para que los usuarios no modifiquen las celdas que tienen fórmulas), pero necesito que se permita agrupar y desagrupar filas.

¿Alguna idea?

Agradecido desde ya.

2 respuestas

Respuesta
1

[Hola

Excel no tiene la opción de proteger las hojas y permitir agrupar/desagrupar (no sé si ya se puede en Excel 2019) así que sugiero usar VBA.

En el módulo del libro (el que lleva "Thisworkbook" como nombre por defecto) pega lo siguiente:

Private Sub Workbook_Open()
    With Worksheets("Nombredelahoja")
        .EnableOutlining = True
        .Protect Password:="tuclave", _
        Contents:=True, UserInterfaceOnly:=True
    End With
End Sub

Comentas

Abraham Valencia

Hola Abraham, gracias por tu respuesta.

lo hice pero no funcionó...

Desprotegí la hoja antes de cerrar el archivo (luego de incluir la macro) lo abrí pero aún no me permite habilitar esas opciones... utilizo excel 365. Alguna idea?

Saludos!

JM

[Hola

Pues a mí me resulta. Coloca tu archivo en algún "drive" y comparte el enlace por aquí.

Abraham Valencia

Respuesta
1

Podrías en lugar de Agruparlas/DesAgruparlas simplemente hacerlas Ocullas/Visibles asignando el rango que deseas ver o ocultar en un Imputbox

Sub AgruFilas()
    On Error GoTo Fin
    ActiveSheet.Unprotect "excel"
    Valor = Application.InputBox(prompt:="Indique el rango que desea ocultar", Title:="AGRUPACION DE RANGOS", Default:="", Type:=2)
    Range(Valor).Select
    Selection.EntireRow.Hidden = True
    ActiveSheet.Protect "excel"
Fin:
    Exit Sub
End Sub
Sub DesAgruFilas()
    On Error GoTo Fin
    ActiveSheet.Unprotect "excel"
    Valor = Application.InputBox(prompt:="Indique el rango que desea hacer visible", Title:="DESAGRUPACION DE RANGOS", Default:="", Type:=2)
    Range(Valor).Select
    Selection.EntireRow.Hidden = False
    ActiveSheet.Protect "excel"
Fin:
    Exit Sub
End Sub

Asigna esas macros a 2 botones y cuando la ejecutes se te abrira un Imput box pidiendote el rango

Hola Sebas, gracias por tu respuesta.

Me gustó tu idea pero para la funcionalidad de la planilla una pregunta por favor.

Cómo podría adecuar tu macro para que, por ejemplo, me sitúo en una celda que tiene un nombre por ejemplo "grupo 1" (la idea es que no dependa del nombre de la celda) y al aplicar la macro oculte/muestre todas las filas por debajo de esa celda hasta la próxima celda que indique categoría, por ej. "grupo 2"

Se me ocurre que cada fila que defina una categoría o grupo tenga en alguna celda algún distintivo por ej.  "Grupo", y que la macro vaya ocultando filas entre esas dos líneas...

Qué opinas?

Algo así dices tu

Sub RutOculta()
Dim xcel, xcelx As Object
For Each xcel In Range("C1:C10")
    If xcel.Value = "Grupo1" Then
        p00 = xcel.Row
        For Each xcelx In Range("C1:C100")
            If xcelx.Value = "Grupo2" Then
            u00 = xcelx.Row
            Range(Cells(p00, 3), Cells(u00, 3)).Select
            Selection.EntireRow.Hidden = True
            End If
        Next xcelx
    End If
Next xcel
Exit Sub
xcel = Nothing
xcelx = Nothing
End Sub

Esta seria para que haga un "For each" sobre el rango C1:C10 y si encuentra la palabra "Grupo1" vuelve a hacer otro "For each" para buscar la palabra "Grupo2" cuando localiza ambas palabras esconde todas las filas que hay desde Grupo1 hasta Grupo2

y asi es a la inversa para que las muestre

Sub RutOculta()
Dim xcel, xcelx As Object
For Each xcel In Range("C1:C10")
    If xcel.Value = "Grupo1" Then
        p00 = xcel.Row
        For Each xcelx In Range("C1:C100")
            If xcelx.Value = "Grupo2" Then
            u00 = xcelx.Row
            Range(Cells(p00, 3), Cells(u00, 3)).Select
            Selection.EntireRow.Hidden = False
            End If
        Next xcelx
    End If
Next xcel
Exit Sub
xcel = Nothing
xcelx = Nothing
End Sub

Como puedes observar solo cambia la palabra "TRUE" por "FALSE"

[quote]

Si te a sido útil no olvides valorar la respuesta -

Puedes dejar más practico el rango para posterior modificación

Agregando la línea

Set Rng = Range("C1:C10") 
' Recuerda cambiar el rango por el tuyo

y donde esta el rango en la macro(en los for each) solo pon "Rng"

Para que si más adelante quieres cambiarlo solo lo cambias en la línea principal

Lo probé con varios "Grupo 1 y Grupo2" y note que ocultaba todo je je

Ahora si lo modifique para que no haga eso :P

Sub RutOculta()
Dim xcel, xcelx As Object
Set Rng = Range("C1:C100")
Application.ScreenUpdating = False
Vuelta:
For Each xcel In Rng
    If xcel.Value = "Grupo1" Then
        xcel.Select
        If (Selection.EntireRow.Hidden) = True Then
            GoTo Sigue1
        Else
        p00 = xcel.Row
        End If
        For Each xcelx In Rng
            If xcelx.Value = "Grupo2" Then
                xcelx.Select
                If (Selection.EntireRow.Hidden) = True Then
                    GoTo Sigue2
                    Else
                    u00 = xcelx.Row
                    Range(Cells(p00, 3), Cells(u00, 3)).Select
                    Selection.EntireRow.Hidden = True
                End If
            GoTo Vuelta
            End If
Sigue2:
        Next xcelx
    End If
Sigue1:
Next xcel
Exit Sub
xcel = Nothing
xcelx = Nothing
Application.ScreenUpdating = True
End Sub

Dime si te sirvio

Gracias por tu tiempo, de verdad agradecido.

Me gusta tu idea, pero el problema es que el nombre "grupo1" o "grupo2" puede cambiar a cualquier otro nombre... al igual que el rango.

La idea es emular el agrupar y desagrupar con tu macro.

Entonces tengo mi planilla con categorías (o grupos) y datos bajo cada una de esas categorías todos listados hacia abajo y que no son fijos pueden ir variando a medida que voy agregando categorias y datos:

Por ej. en una columna (Columna C) 

Grupo1

datos

datos

Grupo_excel

datos

datos

datos

GRupo 3565..... etc

Así en palabras podría describir la rutina de la siguiente forma:

Me sitúo en una celda que tiene un nombre cualquiera (Esta sería la cabeza de la categoría)

Ejecuto la macro

se ocultan todas las filas por debajo de la fila donde estaba situado hasta el final de la planilla o hasta que encuentre la fila que tiene la Próxima categoría y así cada vez que me sitúe en una categoría pueda ocultar o mostrar los datos de esa categoría...

Espero me explique mejor....

Saludos y nuevamente gracias!

Podrías repetir está línea con cada palabra

If xcel.Value = "Grupo1" Then
        xcel.Select
        If (Selection.EntireRow.Hidden) = True Then
            GoTo Sigue1
        Else
        p00 = xcel.Row

Algo así 

If xcel.Value = "Grupo1" Then
        xcel.Select
        If (Selection.EntireRow.Hidden) = True Then
            GoTo Sigue1
ElseIf xcel.Value = "Datos1" Then
        xcel.Select
        If (Selection.EntireRow.Hidden) = True Then
           GoTo Sigue1
ElseIf xcel.Value = "Grupo Excel" Then
        xcel.Select
        If (Selection.EntireRow.Hidden) = True Then
            GoTo Sigue1
        Else
        p00 = xcel.Row

Tendrias que hacer algo asi, sino encuentra una que busque otra en la misma celda 

Gracias de nuevo, el tema es que la palabra puede ser cualquiera...

y si hay una fila en que hay una celda que se llame "grupo", luego le siguen filas sin datos en esa columna y luego hay otra fila con una celda en la misma columna que se llama "grupo", cómo sería la macro para ocultar la(s) fila(s) entre esas dos, pero sin ocultar las filas con la celda "grupo"?

¿Tu quieres ocultar las filas entre grupo1 y grupo2 pero sin ocultar las filas que tienen esos nombres?

De ser así intenta esto

Reemplaza está línea

Range(Cells(p00, 3), Cells(u00, 3)).Select

Por está 

Range(Cells(p00, 3). Offset(1,0), Cells(u00, 3).offset(-1,0).Select

Perdón le faltó un ")"

Range(Cells(p00, 3). Offset(1,0), Cells(u00, 3).offset(-1,0)).Select

Ahora si

Gracias Sebas, por tu aporte, lo pensé de otra manera, dándole un valor 2 a la celda de la fila que quiero agrupar(ocultar) y al final lo dejé así:

Sub Agrupar()

ActiveSheet.Unprotect "PASWORD"
Application.ScreenUpdating = False
Dim UltimaFila As Integer
UltimaFila = Range("A1").End(xlDown).Row 
Dim fila As Integer
fila = ActiveCell.Row
Dim f As Integer
For f = fila To UltimaFila
If Cells(f, 1).Value = 2 Then Cells(f, 1).EntireRow.Hidden = True
If Cells(f + 1, 1).Value = 3 Then GoTo fin
Next
Exit Sub
fin:
Application.ScreenUpdating = True
ActiveSheet.Protect "PASSWORD"
End Sub

Si notas algún error o si esto se puede mejorar, quedo atento.

Saludos!

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas