Как заблокировать определенные ячейки, но разрешить фильтрацию и сортировку

Я использую следующий код для блокировки содержимого определенных ячеек

Sub LockCell(ws As Worksheet, strCellRng As String)
  With ws
   .Unprotect
   .Cells.Locked = False
   .Range(strCellRng).Locked = True
   .Protect Contents:=True, AllowFormattingCells:=True, AllowFormattingColumns:=True, AllowFormattingRows:=True, AllowInsertingColumns:=True, AllowInsertingRows:=True, AllowSorting:=True, AllowFiltering:=True, AllowUsingPivotTables:=True, DrawingObjects:=True
  End With
End Sub

Он блокирует содержимое этих конкретных столбцов. Проблема в том, что пользователи не могут сортировать, ни фильтровать, ни применять границы к ячейкам, так как эти пункты меню Excel отключены.

Я думал, что AllowSorting:=True, AllowFiltering:=True и DrawingObjects:=True позволят так же, как AllowFormattingColumns:=True и AllowFormattingRows:=True позволили AllowFormattingRows:=True размер.

Ответ 1

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

1) Разрешить редактирование и сортировку: (

2) Примените защиту и создайте кнопки с кодом для сортировки с помощью VBA. Есть и другие сообщения, объясняющие, как это сделать. Я думаю, что существует два метода: (1) получить код для снятия защиты с листа, применить сортировку, затем повторно защитить лист или (2) защитить лист, используя UserInterfaceOnly:=True.

3) Ответ Лори, который не позволяет пользователям выбирать ячейки (fooobar.com/questions/479426/...)

4) Одно из решений, о котором я не видел, - это использование VBA для обеспечения некоторой базовой защиты. Например, обнаруживайте и возвращайте изменения с помощью Worksheet_Change. Однако это далеко не идеальное решение.

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

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If (Target.row = HEADER_ROW) Then
        wsMainTable.Unprotect Password:=PROTECTION_PASSWORD
    Else
        wsMainTable.Protect Password:=PROTECTION_PASSWORD, UserInterfaceOnly:=True
    End If
End Sub

Ответ 2

Это была серьезная проблема для меня, и я нашел следующую ссылку с относительно простым ответом. Спасибо Voyager!!!

Обратите внимание, что я назвал диапазон, который я хотел, чтобы другие могли сортировать

  • Снять защитный лист
  • Перейдите в раздел "Защита". "Разрешить пользователям изменять диапазоны" (если вкладка "Excel 2007", "Обзор" )
  • Добавить "Новый" диапазон
  • Выберите диапазон, который вы хотите разрешить пользователям сортировать
  • Нажмите "Защитить лист"
  • На этот раз * не позволяют пользователям выбирать "заблокированные ячейки" **
  • OK

http://answers.yahoo.com/question/index?qid=20090419000032AAs5VRR

Ответ 3

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

Добавьте в рабочий лист следующее:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Locked = True Then
        Application.EnableEvents = False
        Application.Undo
        Application.EnableEvents = True
    End If
End Sub

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

Сортировка и фильтрация не запускают событие "Изменить", поэтому эти функции остаются включенными.

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

Ответ 4

Вот статья, которая объясняет проблему и решение более подробно:

Сортировка заблокированных ячеек в защищенных листах

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

Ответ 5

Ответ Лори хорош, но если пользователь выбирает диапазон, содержащий заблокированные и разблокированные ячейки, данные в заблокированных/защищенных ячейках могут быть удалены.

Ответ Айзека великолепен, но не работает, если пользователь выделяет диапазон, в котором есть как заблокированные, так и разблокированные ячейки.

Я немного изменил код Айзека, чтобы отменить изменения, если ЛЮБОЙ из ячеек в целевом диапазоне заблокирован. Также отображается сообщение, объясняющее, почему действие было отменено. В сочетании с ответом Лори, я смог достичь желаемого результата, имея возможность сортировать/фильтровать защищенный лист, в то же время позволяя пользователю вносить изменения в незащищенную ячейку.

Следуйте инструкциям в ответе Лори, затем поместите следующий код в модуль листа:

Private Sub Worksheet_Change(ByVal Target As Range)
    For Each i In Target
       If i.Locked = True Then
            Application.EnableEvents = False
            Application.Undo
            Application.EnableEvents = True
            MsgBox "Your action was undone because it made changes to a locked cell.", , "Action Undone"
        Exit For
        End If
    Next i
End Sub

Ответ 6

Если автофильтр является частью операции подпрограммы, вы можете использовать

BioSum.Unprotect "letmein"

'<Your function here>

BioSum.Cells(1, 1).Activate
BioSum.Protect "letmein" 

чтобы мгновенно снять защиту с листа, отфильтровать ячейки и затем повторно воспроизвести.

Ответ 7

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

Ответ 8

Это очень старая, но все же очень полезная тема. Я пришел сюда недавно с той же проблемой. Я предлагаю защищать лист, когда это уместно, и снимать его, когда выбран ряд фильтров (например, Ряд 1). Мое решение не использует защиту паролем - она мне не нужна (это защита, а не функция безопасности). Я не могу найти обработчик событий, который распознает выбор кнопки фильтра - поэтому я дал своим пользователям указание сначала выбрать ячейку фильтра, а затем нажать кнопку фильтра. Вот что я защищаю (я меняю защиту только в том случае, если она должна быть изменена, это может сэкономить или не сэкономить время - я не знаю, но это "кажется" правильным):

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  Const FilterRow = 1
  Dim c As Range
  Dim NotFilterRow As Boolean
  Dim oldstate As Boolean
  Dim ws As Worksheet
  Set ws = ActiveSheet
  oldstate = ws.ProtectContents
  NotFilterRow = False
  For Each c In Target.Cells
     NotFilterRow = c.Row <> FilterRow
     If NotFilterRow Then Exit For
  Next c
  If NotFilterRow <> oldstate Then
     If NotFilterRow Then
        ws.Protect
     Else
        ws.Unprotect
     End If
  End If
  Set ws = Nothing
End Sub

Ответ 9

В Excel 2007 разблокируйте ячейки, в которые вы хотите ввести свои данные. Перейти к обзору

 > Protect Sheet
 > Select Locked Cells (already selected)
 > Select unlocked Cells (already selected)
 > (and either) select Sort (or) Auto Filter 

Нет необходимости в VB