Я использую Excel, где определенные поля разрешены для ввода пользователя, а другие ячейки должны быть защищены. Я использовал Tools Protect sheet, но после этого я не могу изменить значения в VBA script. Мне нужно ограничить лист, чтобы остановить ввод пользователя, в то же время разрешить код VBA изменять значения ячеек на основе определенных вычислений.
Попробуйте использовать
Worksheet.Protect "Password", UserInterfaceOnly := True
Если для параметра UserInterfaceOnly установлено значение true, код VBA может изменять защищенные ячейки.
Вы можете изменить лист через код, выполнив следующие действия.
В коде это будет:
Sub UnProtect_Modify_Protect()
ThisWorkbook.Worksheets("Sheet1").Unprotect Password:="Password"
'Unprotect
ThisWorkbook.ActiveSheet.Range("A1").FormulaR1C1 = "Changed"
'Modify
ThisWorkbook.Worksheets("Sheet1").Protect Password:="Password"
'Protect
End Sub
слабость этого метода заключается в том, что если код прерван, а обработка ошибок не захватит его, рабочий лист можно оставить в незащищенном состоянии.
Код может быть улучшен, выполнив следующие действия
Код для этого:
Sub Re-Protect_Modify()
ThisWorkbook.Worksheets("Sheet1").Protect Password:="Password", _
UserInterfaceOnly:=True
'Protect, even if already protected
ThisWorkbook.ActiveSheet.Range("A1").FormulaR1C1 = "Changed"
'Modify
End Sub
Этот код обновляет защиту на рабочем листе, но с параметром UserInterfaceOnly равным true. Это позволяет VBA-коду изменять рабочий лист, сохраняя личный лист защищенным от пользовательского ввода через пользовательский интерфейс, даже если выполнение прерывается.
Этот параметр потерян, когда рабочая книга закрыта и повторно открыта. Защита рабочего листа сохраняется.
Поэтому код "Повторная защита" должен быть включен в начале любой процедуры, которая пытается изменить рабочий лист или может быть запущена только один раз, когда рабочая книга будет открыта.
Я не думаю, что вы можете установить любую часть листа для редактирования только VBA, но вы можете сделать что-то, что имеет в основном тот же эффект - вы можете снять защиту листа в VBA прежде чем вам нужно внести изменения:
wksht.Unprotect()
и повторно защитите его после того, как вы закончите:
wksht.Protect()
Edit: Похоже, что это обходное решение, возможно, решило ближайшую проблему Dheer, но для тех, кто сталкивается с этим вопросом/ответом позже, я ошибся в первой части моего ответа, как указывает Джо. Вы можете защитить лист, подлежащий редактированию только VBA, но, похоже, опция "UserInterfaceOnly" может быть установлена только при вызове "Worksheet.Protect" в коде.
Основной, но простой для понимания ответ:
Sub Example()
ActiveSheet.Unprotect
Program logic...
ActiveSheet.Protect
End Sub
Я выбрал ячейки, которые я хотел заблокировать в листе 1, и поместил предлагаемый код в функцию open_workbook() и работал как шарм.
ThisWorkbook.Worksheets("Sheet1").Protect Password:="Password", _
UserInterfaceOnly:=True
В качестве обходного пути вы можете создать скрытый рабочий лист, который сохранит измененное значение. Ячейка на видимом, защищенном листе должна отображать значение со скрытого листа с использованием простой формулы.
Вы сможете изменить отображаемое значение с помощью скрытого рабочего листа, в то время как ваши пользователи не смогут его редактировать.