Excel макрос на защищенном листе

Правильная защита макросом

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

Worksheets("Лист1").Unprotect Password:="123"
'тут макрос делает действия
Worksheets("Лист1").Protect Password:="123"

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

Есть гораздо более легкий и красивый способ решить задачу.

Нажмите Alt+F11, чтобы попасть в редактор Visual Basic. Затем найдите в левом верхнем углу в окне Project Explorer (если его не видно, то нажмите Ctrl+R) модуль ЭтаКнига (ThisWorkbook) и откройте двойным щелчком:

smart_protection1.gif

Скопируйте туда этот код:

Private Sub Workbook_Open()
    'включаем защиту первого листа для пользователя, но не макроса
    Worksheets("Лист1").Protect Password:="123", UserInterfaceOnly:=True
    
    'второй лист защищаем аналогично, но с возможностью пользоваться группировкой
    Worksheets("Лист2").EnableOutlining = True
    Worksheets("Лист2").Protect Password:="555", UserInterfaceOnly:=True
End Sub

Эта процедура будет автоматически запускаться при открытии файла и ставить защиту на заданные листы книги. Причем параметр UserInterfaceOnly, который мы дополнительно ввели, указывает Excel, что защита не должна распространяться на действия выполняемые макросом, а только на операции пользователя. Для второго листа все еще веселее — строка с параметром EnableOutlining разрешает пользоваться группировкой (символы плюс-минус для сворачивания-разворачивания строк и столбцов) на защищенном листе.

Всего три строчки кода, зато как удобно!

Ссылки по теме

  • Что такое макросы и куда копировать их код
  • Как поставить защиту листа, книги или всего файла

0 / 0 / 0

Регистрация: 14.07.2019

Сообщений: 35

1

Работа макроса на защищённом листе

04.08.2019, 10:25. Показов 12419. Ответов 19


Студворк — интернет-сервис помощи студентам

Здравствуйте!
Хотел применить поиск. Но вот беда при защите листа, он не работает.
Во вложенном файле, поиск в столбце H. Ставил Worksheets(«Лист1″).Unprotect Password:=»123»
Worksheets(«Лист1″).Protect Password:=»123». Всё равно не работает. Как сделать так, чтобы макрос работал, а всё остальное было защищено?



0



1811 / 1134 / 345

Регистрация: 11.07.2014

Сообщений: 3,999

04.08.2019, 13:05

2

spasen1973, ну и в каком месте ваши защищённые листы, попробовал вводить данные — вводятся.
Да это не главное. Где ваш поиск, который не работает или вы считаете, что мы должны разобрать ваш код по косточкам, восхитится им и сообразить где этот поиск?

Добавлено через 10 минут
и интересно, почему ваш выпадающий фруктовый список выпадает на листе городов, а на листе с фруктами (Списки) не выпадает?



0



0 / 0 / 0

Регистрация: 14.07.2019

Сообщений: 35

04.08.2019, 13:42

 [ТС]

3

Burk, может не правильно объяснил. Не надо так строго судить. В столбце H при выборе любой ячейки выпадает форма поиска. Смыл не в этой форме, а как заставить работать этот макрос, если поставить защиту на лист1?



0



Burk

1811 / 1134 / 345

Регистрация: 11.07.2014

Сообщений: 3,999

04.08.2019, 15:51

4

со списками разобрался, даже изменил код листов, мне кажется что так будет удобнее. Хотите — воспользуйтесь, нет так нет.
Я там к тому же сделал, чтобы в комбобокс сразу вставлялся заголовок столбца и сразу выводится соответственный список.
Кстати река Иртыш пишется без мягкого знака. А теперь давайте поговорим за поиск

Visual Basic
1
2
3
4
5
6
7
8
'Кол листа1
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = 8 And Target.Row > 1 Then
      MainForm.cbList.Value = Cells(1, 8)
      Call MyFormShow(Target)
  End If
End Sub
Visual Basic
1
2
3
4
5
6
7
8
9
10
'Кол листа2
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim Col As Integer
Col = Target.Column
If Col < 6 And Target.Row > 1 Then
      MainForm.cbList.Value = Cells(1, Col)
      Call MyFormShow(Target)
  End If
End Sub



1



0 / 0 / 0

Регистрация: 14.07.2019

Сообщений: 35

04.08.2019, 16:14

 [ТС]

5

Burk, опять Вы меня не поняли, спасибо что отрихтовали сам сам макрос поиска. Но как бы написать деликатно, мне надо чтобы это работало при защите листа1, хочу запаролить изменения, но чтобы это посик работал именно в столбце H и нигде более. Иртышь я тоже заметил, этот комбокс не я создавал и списки тоже



0



Burk

1811 / 1134 / 345

Регистрация: 11.07.2014

Сообщений: 3,999

04.08.2019, 18:50

6

Лучший ответ Сообщение было отмечено spasen1973 как решение

Решение

spasen1973, т.е.лист Списки вам не нужен?
В код макроса MyFormShow вставляете unprotect

Visual Basic
1
2
Sub MyFormShow(Target As Range)
If ActiveSheet.Name = "Лист1" Then Worksheets("Лист1").Unprotect Password:="123"

в код вашей MainForm ставите обработчик события закрытия форму по крестику

Visual Basic
1
2
3
4
5
6
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If ActiveSheet.Name = "Лист1" Then Worksheets("Лист1").Protect Password:="123"
'  закрытие окна через крест
End Sub
'и перед выходом из макроса кнопки OkButton_Click (перед End Sub) тоже ставите
If ActiveSheet.Name = "Лист1" Then Worksheets("Лист1").Protect Password:="123"

я там переделывал страницы у себя, посмотрите мой Лист1 соответствует вашему?

Добавлено через 11 минут
spasen1973, ещё можно выводить вашу форму только на существующих значениях столбца и на первом пустом внизу столбца, чтобы не было реакции на любую пустую ячейку столбца и ваши категории будут вводиться подряд без пустых в средине. Тогда это будет так для лист1

Visual Basic
1
2
3
4
5
6
7
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = 8 And Target.Row > 1 Then
  If Cells(Rows.Count, 8).End(xlUp).Row + 1 >= Target.Row Then
    MainForm.cbList.Value = Cells(1, 8): Call MyFormShow(Target)
  End If
End If
End Sub

Добавлено через 24 минуты
в коде кнопки закрыть тоже лучше восстановить защиту листа. Т.е на всех кнопках, из которых возможен выход из формы.

Добавлено через 42 минуты
проверил в кнопае закрыть восстановление защиты можно не ставить, всё равно идет закрытие через QueryClose



1



0 / 0 / 0

Регистрация: 14.07.2019

Сообщений: 35

05.08.2019, 04:20

 [ТС]

7

Спасибо Burk! Мир кажется намного сложнее, когда начинаешь изучать VBA.
Почти всё понятно, за исключением

Цитата
Сообщение от Burk
Посмотреть сообщение

в код вашей MainForm ставите обработчик события закрытия форму по крестику

Куда это код вставить?

Цитата
Сообщение от Burk
Посмотреть сообщение

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If ActiveSheet.Name = «Лист1» Then Worksheets(«Лист1″).Protect Password:=»123»



0



1811 / 1134 / 345

Регистрация: 11.07.2014

Сообщений: 3,999

05.08.2019, 05:35

8

spasen1973, да вроде всё вам объяснил ( код вашей MainForm) — входите в вба-проект (Разработчик — Visual Basic), встаете на вашу форму MainForm, вверху слева View Code. Открывается модуль кода формы. Вот в него и вставляйте, хотите в начало, хотите в середину или в конец.
Ещё, на всякий случай, посылаю свой файл, на котором проверял.
Интересно, у вас достаточно серьезный код, а вопросы детские, код не ваш? Это просто, чтобы оценить на каком уровне с вами говорить.



1



0 / 0 / 0

Регистрация: 14.07.2019

Сообщений: 35

05.08.2019, 06:05

 [ТС]

9

Burk, спасибо! Да код не мой, я только учусь. Спасибо! Да и спасибо за файл. Лучше один раз увидеть!



0



1811 / 1134 / 345

Регистрация: 11.07.2014

Сообщений: 3,999

05.08.2019, 06:45

10

Цитата
Сообщение от spasen1973
Посмотреть сообщение

Лучше один раз увидеть

не уверен, что это так. Если бы вы сами всё проделали по моей инструкции, ну ошиблись, тогда снова попытаться и у вас бы получилось, то запомнили бы.



0



pashulka

4131 / 2235 / 940

Регистрация: 01.12.2010

Сообщений: 4,624

05.08.2019, 12:29

11

Лучший ответ Сообщение было отмечено spasen1973 как решение

Решение

spasen1973, Строго в модуль книги ThisWorkbook(ЭтаКнига), сохраните и при следующем открытии книги получите желаемое, только нужно убрать проверку на защищённость листа. Если не хотите ждать, то просто выполните событие.

Visual Basic
1
2
3
4
Private Sub Workbook_Open()
    'Лист1.Protect "123", , , , True
    Лист1.Protect Password:="123", UserInterfaceOnly:=True
End Sub



0



0 / 0 / 0

Регистрация: 14.07.2019

Сообщений: 35

05.08.2019, 12:48

 [ТС]

12

pashulka, здравствуйте! В том то и дело, так делал и ничего не получалось. Этот вариант мне попадался на других форумах.



0



4131 / 2235 / 940

Регистрация: 01.12.2010

Сообщений: 4,624

05.08.2019, 13:16

13

spasen1973, Скажите, что я делаю не так ? Почему у меня при защищённом листе и ячейках, кнопка Вставить в ячейку выполняет возложенные на неё обязанности.



1



0 / 0 / 0

Регистрация: 14.07.2019

Сообщений: 35

05.08.2019, 13:41

 [ТС]

14

pashulka, я думаю эти ячейки не защищены. Наверно в формате ячеек, отключена защита.



0



4131 / 2235 / 940

Регистрация: 01.12.2010

Сообщений: 4,624

05.08.2019, 13:48

15

spasen1973, Вы можете ввести/изменить текст в ячейках столбца H ? ( в моём примере )



0



0 / 0 / 0

Регистрация: 14.07.2019

Сообщений: 35

05.08.2019, 14:07

 [ТС]

16

pashulka, в вашем могу, но только как я и говорил, надо зайти в формат ячеек столбца H и убрать галочку с зашиты.



0



4131 / 2235 / 940

Регистрация: 01.12.2010

Сообщений: 4,624

05.08.2019, 15:05

17

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



0



0 / 0 / 0

Регистрация: 14.07.2019

Сообщений: 35

05.08.2019, 15:52

 [ТС]

18

pashulka, конечно Вы правы. Но в данном случае, я знаю пароль, поэтому сначала сниму лист с защиты, а потом доберусь до формата ячеек. Не зная пароля ничего бы не смог сделать.



0



4131 / 2235 / 940

Регистрация: 01.12.2010

Сообщений: 4,624

05.08.2019, 16:16

19

Хорошая шутка Значит UserInterfaceOnly всё-таки работает и дело не в поиске, который вообще не зависит от наличия или отсутствия защиты, а в пароле. Тогда можно «защитить» VBProject и пароль будет скрыт. Если и этого мало, то, наверное, это уже отдельная тема, типа, как защитить чужой код в моей книге.



1



0 / 0 / 0

Регистрация: 14.07.2019

Сообщений: 35

05.08.2019, 16:23

 [ТС]

20

pashulka, да, поиздевались надо мной на славу.



0



Макросы Excel представляют собой замечательный способ экономии времени и исключения ошибок. Однако рано или поздно вы пытаетесь выполнить ваш любимый макрос Excel на рабочем листе, к которому была применена защита, с паролем или без, и получаете ошибку выполнения. Избежать ее можно при помощи следующего трюка.

Если вы когда-либо пытались выполнить макрос Excel на защищенном рабочем листе, то знаете, что, как только этот рабочий лист упоминается в макросе, макрос, вероятнее всего, перестает работать и появляется ошибка выполнения. Перед началом работы рекомендуем хорошенько отдохнуть, к вашим услугам гостиницы краснодара недорого и с полным пансионом. А теперь к делу. Один из способов обойти это — использовать код, например, следующий, чтобы снять защиту, а потом снова защитить рабочий лист, как это показано в листинге 7.21.

1
2
3
4
5
6
//Листинг 7.21
Sub MyMacro()
Sheet1.Unprotect Password:="Secret"
//ВАШ КОД
Sheet1.Protect Password:="Secret"
End Sub

Как можно видеть, этот код снимает защиту листа Sheet1 с паролем Secret, выполняет код, а затем снова включает защиту паролем. Этот код работает, но у него есть несколько недостатков. Например, он может вызвать ошибку и остановиться до того, как дойдет до строки кода Sheet1.Protect Password:=«Secret». Это, конечно же, приведет к тому, что рабочий лист останется незащищенным. Еще один недостаток заключается в том, что потребуется похожий код для всех макросов и всех рабочих листов.

Еще один способ обойти проблему — использовать UserlnterFaceOnly, необязательный аргумент метода Protect, которому можно присвоить значение True (значение по умолчанию равно False). Если значение этого аргумента равно True, Excel позволяет всем макросам Excel VBA выполняться на рабочих листах, защищенных с паролем или без пароля.

Однако если вы используете на рабочем листе метод Protect, аргумент UserlnterfaceOnly которого равен True, а затем сохраните рабочую книгу, весь рабочий лист (а не только интерфейс) будет полностью защищен при очередном открытии рабочей книги. Чтобы снова присвоить аргументу UserlnterfaceOnly значение True после открытия рабочей книги, необходимо еще раз применить метод Protect, присваивающий истинное значение UserlnterfaceOnly.

Чтобы избежать неразберихи, используйте событие Workbook_Open, которое выполняется при открытии рабочей книги. Так как это событие принадлежит объекту Workbook ЭтаКнига (ThisWorkbook), необходимо поместить следующий код в частный модуль объекта ЭтаКнига (ThisWorkbook). Для этого в версиях Excel для Windows правой кнопкой мыши щелкните значок Excel и в контекстном меню выберите команду Исходный текст (View Code). На Macintosh откройте объект Workbook в окне Projects в VBE. Затем введите код, показанный в листинге 7.22.

1
2
3
4
5
6
7
8
//Листинг 7.22
Private Sub WorkbookOpen()
//Если у вас разные пароли для всех рабочих листов.
 
Sheets(l).Protect Password:="Secret". UserInterFaceOnly:=True
Sheets(2).Protect Password:="Carrot". UserInterFaceOnly:=True
//Повторить необходимое количество раз.
End Sub

Предыдущий код подходит для случаев, когда для всех рабочих листов, на которых вы хотите выполнить этот макрос, выбраны разные пароли или если вы не хотите защищать все рабочие листы. Можно присвоить аргументу UserlnterfaceOnly значение True, не снимая перед этим защиту листа. Если вы хотите присвоить аргументу UserlnterfaceOnly значение True для всех рабочих листов и у всех рабочих листов одинаковые пароли, используйте следующий код, который нужно поместить туда же, куда и предыдущий.

1
2
3
4
5
6
7
8
//Листинг 7.23
Private Sub WorkbookOpen()
Dim wSheet As Worksheet
 
	For Each wSheet In Worksheets
		wSheet.Protect Password:="Secret", UserInterFaceOnly:=True
	Next wSheet
End Sub

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

Skip to content

Как защитить все листы в файле

На чтение 2 мин. Просмотров 2.8k.

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

Содержание

  1. Как макрос работает
  2. Код макроса
  3. Как работает этот код
  4. Как использовать

Как макрос работает

В этом макросе вы выбираете листы и просто применяете защиту с помощью пароля.
Пароль аргумент определяет пароль, необходимый для снятия защиты. Аргумент Пароль не является обязательным. Если его вообще опустить, лист по-прежнему будет защищен; вам просто не нужно будет вводить пароль для снятия его защиты. Кроме того, следует помнить, что пароли Excel чувствительны к регистру.

Код макроса

Sub ZaschititVseListi()
 'Шаг 1: Объявляем переменные
 Dim ws As Worksheet
 'Шаг : Запускаем цикл через все рабочие листы
 For Each ws In ActiveWorkbook.Worksheets
 'Шаг 3: Ставим защиту и переходим к следующему листу
 ws.Protect Password:="КРАСНЫЙ"
 Next ws
 End Sub

Как работает этот код

  1. Шаг 1 объявляет объект под названием WS. Он создает контейнер памяти для каждого рабочего листа.
  2. Шаг 2 начинает процесс в Excel — проходит через все рабочие листы.
  3. На шаге 3, макрос применяет защиту с данным паролем, а затем возвращается обратно, чтобы получить рабочий лист.

Как использовать

  1. Активируйте редактор Visual Basic, нажав ALT + F11.
  2. Щелкните правой кнопкой мыши personal.xlb в окне Project.
  3. Выберите Insert➜Module.
  4. Введите или вставьте код во вновь созданном модуле.

Работа макроса на защищенном листе

mitox

Дата: Пятница, 16.03.2018, 13:02 |
Сообщение № 1

Группа: Пользователи

Ранг: Новичок

Сообщений: 26


Репутация:

0

±

Замечаний:
0% ±


Excel 2016

есть файл с макросом на листе
отформатировал ячейки — разрешив в них вносить данные при защищенном листе
защитил лист

Макрос выдает ошибку. Поискал в инете решения — нашел пару. Не помогли. В чем я ошибаюсь.

[vba]

Код

Private Sub Workbook_Open()

    Dim Sh As Worksheet, i As Integer
    For i = 1 To Sheets.Count
        With Sheets(i)
            .Unprotect Password (123)
            .Protect Scenarios:=True, UserInterfaceOnly:=True
        End With
    Next

        End Sub

[/vba]

Все равно выдает ошибку. Помогите разобраться. У меня в файле все листы будут защищены, с отдельных ячеек на листах будут сняты защиты. Макросы будут идентичны на каждом листе

 

Ответить

Mikael

Дата: Пятница, 16.03.2018, 13:28 |
Сообщение № 2

Группа: Пользователи

Ранг: Участник

Сообщений: 80


Репутация:

31

±

Замечаний:
0% ±


Excel 2010

mitox, добрый день.

[vba]

Код

Private Sub Workbook_Open()

    Dim Sh As Worksheet, i As Integer
    For i = 1 To Sheets.Count
        With Sheets(i)
            .Unprotect «123»
            .Protect Password:=»123″, Scenarios:=True, UserInterfaceOnly:=True
        End With
    Next

        End Sub

[/vba]

К сообщению приложен файл:

5610276.xlsm
(22.0 Kb)

Сообщение отредактировал MikaelПятница, 16.03.2018, 13:36

 

Ответить

mitox

Дата: Пятница, 16.03.2018, 15:09 |
Сообщение № 3

Группа: Пользователи

Ранг: Новичок

Сообщений: 26


Репутация:

0

±

Замечаний:
0% ±


Excel 2016

Спасибо. Я и сам затупил — макрос то срабатывает после открытия файла? Я прав?

 

Ответить

Mikael

Дата: Пятница, 16.03.2018, 15:20 |
Сообщение № 4

Группа: Пользователи

Ранг: Участник

Сообщений: 80


Репутация:

31

±

Замечаний:
0% ±


Excel 2010

Да, это обработчик события открытие книги.
Но ошибка вылетала из-за вот этой строчки
[vba]

Код

.Unprotect Password (123)

[/vba]
Правильно будет так:
[vba]

Код

.Unprotect Password:=»123″

[/vba]
или как у меня.
Так же, после снятия защиты, Вы ставите защиту, но без пароля, поэтому я добавил в следующую строчку еще и пароль.

Сообщение отредактировал MikaelПятница, 16.03.2018, 15:39

 

Ответить

mitox

Дата: Пятница, 23.03.2018, 06:32 |
Сообщение № 5

Группа: Пользователи

Ранг: Новичок

Сообщений: 26


Репутация:

0

±

Замечаний:
0% ±


Excel 2016

Подскажите что в коде нужно дописать чтобы макрос менял цвета ячеек на защищенном листе
[vba]

Код

Private Sub Workbook_Open()

    Dim Sh As Worksheet, i As Integer
    For i = 1 To Sheets.Count
        With Sheets(i)
            .Unprotect «пароль»
            .EnableOutlining = True
            .Protect Password:=»пароль», Scenarios:=True, UserInterfaceOnly:=True
        End With
    Next

        End Sub

[/vba]

 

Ответить

Mikael

Дата: Пятница, 23.03.2018, 10:41 |
Сообщение № 6

Группа: Пользователи

Ранг: Участник

Сообщений: 80


Репутация:

31

±

Замечаний:
0% ±


Excel 2010

что в коде нужно дописать чтобы макрос менял цвета ячеек

Нужно написать код который будет менять цвета ячеек.
[vba]

Код

Range(«a1:b2»).Interior.Color = RGB(0, 255, 0)

[/vba]
Какие ячейки вы хотите менять при открытии книги?

 

Ответить

mitox

Дата: Пятница, 23.03.2018, 11:40 |
Сообщение № 7

Группа: Пользователи

Ранг: Новичок

Сообщений: 26


Репутация:

0

±

Замечаний:
0% ±


Excel 2016

Код который меняет цвет имеется и другой.
А проблему снял добавив в строку
[vba]

Код

,AllowFormattingCells:=True

[/vba]

 

Ответить

Mikael

Дата: Пятница, 23.03.2018, 14:36 |
Сообщение № 8

Группа: Пользователи

Ранг: Участник

Сообщений: 80


Репутация:

31

±

Замечаний:
0% ±


Excel 2010

Код который меняет цвет имеется и другой.

Тогда не понимаю в чем был Ваш вопрос.
Для того чтобы процедура могла менять цвет ячеек достаточно параметра UserInterfaceOnly:=True
Параметр AllowFormattingCells:=True нужен чтобы пользователь мог менять цвет заливки/шрифта.

Рад, что у Вас все получилось.

 

Ответить

Понравилась статья? Поделить с друзьями:
  • Excel макрос на добавление ячейки
  • Excel макрос на добавление строки в таблицу
  • Excel макрос на добавление макроса
  • Excel макрос на выделение цветом ячеек
  • Excel макрос на вставку строки