Как сделать индикатор защиты листа

Помогите, пожалуйста.

Хочу сделать индикатор того, что лист защищен или не защищен, т.е. если я защищаю лист, то ячейка A1 становится красной, если снимаю защиту, зеленой.

Private Sub Индикатор()
    If ActiveSheet.Protect Then
        ActiveSheet.Range("AL1").Interior.Color = vbRed
    Else
        ActiveSheet.Range("AL1").Interior.Color = vbGreen
    End If
End Sub

Мой код не работает... Подскажите, что не так.

Заранее благодарен.


Ответы (1 шт):

Автор решения: vikttur

В VBA есть понятие событий листа. Это действия, на которые может реагировать код в VBA. Защита листа или ее снятие не являются событиями, макрос не сможет отслеживать эти действия. Условное форматировани тоже не поймет их.

Можно проверять свойство листа ProtectContents (установлена ли защита):

If ProtectContents = True Then
    Range("AL1").Interior.Color = vbRed
Else
    Range("AL1").Interior.Color = vbGreen
End If

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

Запускать проверку состояния защиты листа событиями... Можно, но нежелательно. Например, событием изменения на листе Worksheet_Change:

Private Sub Worksheet_Change(ByVal Target As Range)
......
End Sub

При любом изменении будет срабатывать код проверки. 1000 раз за рабочий день что-то поменяли на листе - столько же раз макрос проверил состояние защиты.

О индикации заливкой. На защищенном листе можно менять заливку ячеек, если разрешено форматирование, т.е. при защите листа нужно устанавливать галку Разрешить форматирование ячеек. Забыли - получили ошибку при попытке поменять заливку.

Лучше вместо заливки менять значение ячейки. Она должна быть незащищенной (Формат ячейки-Защита, снять галку Защищаемая ячейка), а заливку сделать условным форматированием.

Но даже на защищенном листе сотрудник-шутник сможет изменить заливку на обратную )

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

Sub СheckProtectSheet()
    Dim sTxt As String
    
    With ActiveSheet
        If .ProtectContents = True Then
            sTxt = Application.InputBox("Впишите пароль для снятия защиты листа")
            
            On Error GoTo err_
            .Unprotect (sTxt)
            .Range("AL1").Interior.Color = vbGreen
err_:
            If Err Then MsgBox "Неверный пароль", 64, "ОШИБКА"
        Else
            sTxt = Application.InputBox("Впишите пароль для защиты листа")
            
            If sTxt = Application.InputBox("Повторите пароль еще раз") Then
                .Range("AL1").Interior.Color = vbRed
                .Protect (sTxt)
            Else
                MsgBox "Второй пароль не совпал с первым", 64, "ОШИБКА"
            End If
        End If
    End With
End Sub

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

→ Ссылка