Версия для печати

Как оставить возможность работать со структурой на защищенном листе?

Что умеет Excel

 

Если Вы хотите защитить лист от внесения изменений и на листе имеется сгруппированные в структуру данные, то при установке обычной защиты теряется возможность работы с этой структурой. Для тех, кто не совсем понимает, что такое структура(еще её называют группировка): это такие плюсики левее строк, при нажатии на которые раскрываются скрытые строки. Так вот частенько очень необходимо, чтобы наряду с защитой листа можно было еще и структурой пользоваться. Т.е. чтобы пользователь мог просмотреть все в удобной форме, но не смог ничего изменить. Так как же защитить лист и оставить возможность работы со структурой? Очень просто.

Если Вы не знакомы с макросами и VBA, то Вам сначала необходимо:

  1. создать стандартный модуль
  2. разместить в нем нижеприведенный код:
    Sub Protect_and_Structure()
        ActiveSheet.EnableOutlining = True
        ActiveSheet.Protect Contents:=True, Scenarios:=True, UserinterfaceOnly:=True
    End Sub
    Sub Protect_and_Structure()
        ActiveSheet.EnableOutlining = True
        ActiveSheet.Protect Contents:=True, Scenarios:=True, UserinterfaceOnly:=True
    End Sub

Выполнив данный код, Вы защитите активный лист, не потеряв возможности работать со структурой.Естественно можно указать любой лист вместо активного.

Примечание: данный макрос лучше всего прописывать на событие открытия книги(модуль ЭтаКнига(ThisWorkbook)), т.к. сразу после закрытия и открытия книги данная защита снимается.

Можно ставить защиту сразу на все листы книги при открытии таким кодом:

Private Sub Workbook_Open()
    Dim wsSh As Object
    For Each wsSh In Me.Sheets
        Protect_and_Structure wsSh
    Next wsSh
End Sub
Sub Protect_and_Structure(wsSh As Object)
    wsSh.Unprotect
    wsSh.EnableOutlining = True
    wsSh.Protect Contents:=True, Scenarios:=True, UserinterfaceOnly:=True
End Sub
Private Sub Workbook_Open()
    Dim wsSh As Object
    For Each wsSh In Me.Sheets
        Protect_and_Structure wsSh
    Next wsSh
End Sub
Sub Protect_and_Structure(wsSh As Object)
    wsSh.Unprotect
    wsSh.EnableOutlining = True
    wsSh.Protect Contents:=True, Scenarios:=True, UserinterfaceOnly:=True
End Sub

Данный код вставляется в модуль ЭтаКнига.

Ну и если Вам только на один лист надо установить, то убираем цикл и вызываем процедуру только для нужного листа:

Private Sub Workbook_Open()
       Protect_and_Structure Me.Sheets("Лист1")
End Sub
Sub Protect_and_Structure(wsSh As Object)
       wsSh.Unprotect
       wsSh.EnableOutlining = True
       wsSh.Protect Contents:=True, Scenarios:=True, UserinterfaceOnly:=True
End Sub
Private Sub Workbook_Open()
       Protect_and_Structure Me.Sheets("Лист1")
End Sub
Sub Protect_and_Structure(wsSh As Object)
       wsSh.Unprotect
       wsSh.EnableOutlining = True
       wsSh.Protect Contents:=True, Scenarios:=True, UserinterfaceOnly:=True
End Sub

Чтобы помимо этого можно было разрешить пользователям производить иные стандартные операции(форматирование ячеек, форматирование строк, форматирование столбцов, вставка строк и т.д.) достаточно просто записать макрос по установке защиты листа и посмотреть как будет выглядеть код. Код ниже вставлен в основной после записи макрорекордером установки защиты с возможностью форматировать столбцы:

Sub Protect_and_Structure(wsSh As Object)
       wsSh.Unprotect
       wsSh.EnableOutlining = True
       wsSh.Protect Contents:=True, Scenarios:=True, AllowFormattingColumns:=True, UserinterfaceOnly:=True
End Sub
Sub Protect_and_Structure(wsSh As Object)
       wsSh.Unprotect
       wsSh.EnableOutlining = True
       wsSh.Protect Contents:=True, Scenarios:=True, AllowFormattingColumns:=True, UserinterfaceOnly:=True
End Sub

Чтобы добавить в код установку пароля, записать его следует так:

Sub Protect_and_Structure(wsSh As Object)
       wsSh.Unprotect "1234"
       wsSh.EnableOutlining = True
       wsSh.Protect Password:="1234", Contents:=True, Scenarios:=True, UserinterfaceOnly:=True
End Sub
Sub Protect_and_Structure(wsSh As Object)
       wsSh.Unprotect "1234"
       wsSh.EnableOutlining = True
       wsSh.Protect Password:="1234", Contents:=True, Scenarios:=True, UserinterfaceOnly:=True
End Sub

Хочу обратить внимание, что тогда и снимать защиту тоже следует с указанием пароля, как показано выше(wsSh.Unprotect "1234"). Если изначально пароль не установлен, то следует его установить вручную и запустить код, либо просто удалить строку wsSh.Unprotect "1234".

Также см.:
Как защитить лист от пользователя, но не от макроса?
Защита листов/снятие защиты



Поддержать автора сайта
Поделиться ссылкой
  1. alx74
    13 Август 2012 в 20:58 | #1

    Дмитрий, добрый день. Вставил Ваш код в файл. При запуске файла все работает (лист защищен), но можно зайти в Редактирование-Снять защиту листа и далее просто снять защиту и редактировать любую информацию на листе. Я в макросах не силен, подскажите, пжлста, что можно добавить в макрос или иные действия, способные защитить информацию?

  2. 13 Август 2012 в 21:15 | #2

    alx74, я бы посоветовал Вам дочитать статью до конца. Последний код демонстрирует возможность кодом установки пароля на защиту. Тогда не зная пароля никто защиту не снимет.

  3. alx74
    13 Август 2012 в 21:36 | #3

    Дмитрий(Админ) :
    alx74, я бы посоветовал Вам дочитать статью до конца. Последний код демонстрирует возможность кодом установки пароля на защиту. Тогда не зная пароля никто защиту не снимет.

    Дочитал, попробовал, получилось. Спасибо.
    Если с функциями более или менее, то с макросами знания «стерильны» . Все методом проб и ошибок.
    Еще раз, Спасибо.

  4. Janis
    8 Октябрь 2012 в 15:32 | #4

    Может кому пригодится-просто и удобно!!!
    Код позволяет пользоваться группировкой (символы плюс-минус для сворачивания-разворачивания строк и столбцов) на всей защищенной книге!!!

    Private Sub Workbook_Open()
    Dim ProtectAllSheets()
    Dim MyPassWord As String
    Dim wsh As Worksheet
    MyPassWord = "123456"
    For Each wsh In ThisWorkbook.Worksheets
    wsh.EnableOutlining = True
    wsh.Protect Password:=MyPassWord, _
    DrawingObjects:=True, Contents:=True, Scenarios:=True, _
    AllowFiltering:=True, UserInterfaceOnly:=True
    Next
    End Sub
    Private Sub Workbook_Open()
    Dim ProtectAllSheets()
    Dim MyPassWord As String
    Dim wsh As Worksheet
    MyPassWord = "123456"
    For Each wsh In ThisWorkbook.Worksheets
    wsh.EnableOutlining = True
    wsh.Protect Password:=MyPassWord, _
    DrawingObjects:=True, Contents:=True, Scenarios:=True, _
    AllowFiltering:=True, UserInterfaceOnly:=True
    Next
    End Sub

    Код вставляется в основу самой книги.

  5. 8 Октябрь 2012 в 15:40 | #5

    Janis, а Вы не прочитали статью, да? Если прочитали, то не вникали, я полагаю? Там уже есть код, позволяющий ставить защиту на все листы книги…
    Притом Ваш код выдаст ошибку при как минимум втором открытии книги. Потому что отсутствует строка снятия защиты с листов перед установкой.

  6. Janis
    8 Октябрь 2012 в 16:02 | #6

    Статью я читал, но данный в статье код мне не подошёл, на каждый лист просит пароль!!! На моих книгах мною указанный код пока действует без проблем, можно работать вводить данные и сохранять их, при этом никто не видит ни формулы ни макроса и не нужен никакой пароль чтоб вводить и сохранять информацию, хотя листы защищены.@Дмитрий(Админ)

  7. 8 Октябрь 2012 в 16:27 | #7

    Не буду переубеждать(тем более, что статью Вы все же не дочитали до конца и не свели воедино информацию в ней). Просто вглядитесь в свой код и посмотрите — где Вы там снимаете защиту с листов, прежде чем изменить параметры этой защиты? Если Вы, конечно, не забыли указать, что перед закрытием книги снимаете защиту с листов. Закройте свою книгу, откройте и попробуйте воспользоваться группировкой.
    А за запись в защищенные листы информации макросом отвечает параметр UserinterfaceOnly:=True. Об этом я писал в другой статье (в этой он тоже применяется, если Вы, конечно, заметили).

  8. Janis
    8 Октябрь 2012 в 16:47 | #8

    Дмитрий, как мне Вам лично отправить пример .xls, может Вы меня переубедите@Дмитрий(Админ)

  9. 8 Октябрь 2012 в 16:53 | #9

    The-Prist@yandex.ru

    Хотя не вижу смысла. Я так понимаю, что Вы не особо еще в кодах разбираетесь. Я вот не вижу смысла в строке Вашего кода: Dim ProtectAllSheets()

  10. Евгений
    6 Ноябрь 2012 в 23:33 | #10

    Спасибо! Оч.полезная статья- помогла!

  11. гость
    5 Декабрь 2012 в 13:23 | #11

    Janis прав. Дело в том, что команда UserinterfaceOnly:=True не распространяет защиту на выполнение макроса, а только на действия пользователя. И поэтому снимать защиту при запуске не надо.

  12. Александр
    10 Декабрь 2012 в 01:10 | #12

    @Николай
    Николай вы гений пробовал разные коды подошел только ваш… спс

  13. Илья
    20 Декабрь 2012 в 14:38 | #13

    Добрый день! У меня не получается с код. Я воспользовался первым кодом

    Sub Protect_and_Structure()
        ActiveSheet.EnableOutlining = True
        ActiveSheet.Protect Contents:=True, Scenarios:=True, UserinterfaceOnly:=True
    End Sub
    Sub Protect_and_Structure()
        ActiveSheet.EnableOutlining = True
        ActiveSheet.Protect Contents:=True, Scenarios:=True, UserinterfaceOnly:=True
    End Sub

    Поставил его в новый модуль, у меня Module 3, защите листа через раздел Разрешить изменение диапазонов, но все равно не дает работать с группами. Почему?

  14. khmelae
    14 Апрель 2013 в 20:08 | #14

    Работает все отлично, но не получается добавить возможность обновления данных из внешнего источника.
    Необходимо подгружать данные с сайта. Пробовал добавить RefreshAll:=True, но ничего не получилось…

  15. 14 Апрель 2013 в 21:23 | #15

    khmelae, а какое вообще имеет отношение группировка к обновлению данных? Данная статья не предназначена для решения ВСЕХ Ваших проблем. Есть форум, есть другие статьи — советую почитать.

Страницы комментариев

Комментарии, не имеющие отношения к комментируемой статье, будут удаляться без уведомления и объяснения причин. Если есть вопрос по проблеме в Excel- добро пожаловаться на Форум

Комментарий будет добавлен после проверки администратором.