В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача ограничить доступ пользователя к редактированию документов, которые относятся к уже закрытым периодам. Это критически важно для соблюдения целостности бухгалтерского и управленческого учета. Рассмотрим подробнее, как реализовать такую проверку программно, какие инструменты предоставляет Библиотека стандартных подсистем (БСП) и почему выбор правильного события формы играет ключевую роль.
Если вы работаете с типовой конфигурацией (например, Бухгалтерия предприятия 3.0, ЗУП 3.1, ERP 2.5 или УТ 11), в них уже интегрирована подсистема «Даты запрета изменения». Программисту не нужно писать сложные запросы к регистрам вручную — достаточно воспользоваться готовым программным интерфейсом общего модуля ДатыЗапретаИзменения.
Разберем основной метод, который позволяет мгновенно получить ответ, запрещено ли редактирование конкретного объекта:
// В модуле формы документа
&НаСервере
Функция ПроверитьЗапретРедактирования(ТекущийОбъект)
// Метод возвращает Истина, если дата документа попадает в закрытый период
Возврат ДатыЗапретаИзменения.ИзменениеЗапрещено(ТекущийОбъект);
КонецФункции
Этот метод удобен тем, что он автоматически учитывает все настройки системы: разрезы по организациям, индивидуальные настройки для пользователей или групп пользователей, а также специфические правила для различных разделов учета.
Проанализируем ситуацию: автор вопроса предлагал использовать процедуру ПриОткрытии. Однако, с точки зрения производительности и корректности интерфейса управляемых форм, это не самое удачное решение. Рассмотрим, почему событие ПриЧтенииНаСервере является приоритетным:
ПриЧтенииНаСервере выполняется на сервере в момент получения данных объекта. Нам не нужно делать дополнительный контекстный вызов с клиента на сервер, который неизбежен при использовании ПриОткрытии.ТолькоПросмотр. Если форма открывается для просмотра старого документа, система сразу заблокирует все элементы управления до того, как они будут отрисованы на клиенте.ПриЧтенииНаСервере нам доступен ТекущийОбъект, что позволяет методам БСП корректно проанализировать дату, организацию и другие реквизиты, влияющие на запрет.Посмотрим на пример реализации в модуле формы:
&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
// Проверяем, не является ли объект новым (для новых документов проверка обычно не требуется)
Если Не ТекущийОбъект.ЭтоНовый() Тогда
// Вызываем стандартную функцию БСП
Если ДатыЗапретаИзменения.ИзменениеЗапрещено(ТекущийОбъект) Тогда
// Блокируем форму для редактирования
ЭтаФорма.ТолькоПросмотр = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Хотя визуальная блокировка формы в интерфейсе — это отличная практика, важно обеспечить и программную защиту. Выясним причину: документ может быть изменен не только через форму, но и программно (обработкой или при обмене данными). Для этого в БСП существует процедура, которая не просто возвращает Истина или Ложь, а выдает исключение, прерывая транзакцию записи.
Эту проверку рекомендуется размещать в модуле объекта в обработчике ПередЗаписью или использовать соответствующие подписки на события, которые уже есть в типовых конфигурациях:
// В модуле объекта
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Если запись инициирована обменом данными, проверку обычно пропускают
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Программная проверка с выдачей сообщения пользователю
ДатыЗапретаИзменения.ПроверитьДатуЗапретаИзменения(ЭтотОбъект);
КонецПроцедуры
Если в вашей конфигурации не используется БСП, вам придется реализовать проверку самостоятельно. Данные о границах запрета обычно хранятся в регистре сведений. В старых конфигурациях (на обычных формах, таких как УПП 1.3) это регистр ГраницыЗапретаИзмененияДанных. В новых — ДатыЗапретаИзменения.
Проанализируем алгоритм, который необходимо реализовать в запросе:
Рассмотрим пример упрощенного запроса к регистру (предположим, что мы ищем общую дату):
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДатыЗапрета.ДатаЗапрета КАК ДатаЗапрета
|ИЗ
| РегистрСведений.ДатыЗапретаИзменения КАК ДатыЗапрета
|ГДЕ
| ДатыЗапрета.Пользователь = &ПустойПользователь"; // Условие для общей даты
Запрос.УстановитьПараметр("ПустойПользователь", Справочники.Пользователи.ПустаяСсылка());
// ... выполнение запроса и сравнение с ТекущийОбъект.Дата
При реализации проверки важно помнить о нескольких аспектах:
1. Полные права: Обычно пользователи с ролью ПолныеПрава игнорируют даты запрета изменения. В коде БСП это учитывается автоматически. Если вы пишете свой код, не забудьте добавить проверку РольДоступна("ПолныеПрава").
2. Привилегированный режим: Проверка дат запрета часто требует доступа к регистрам, к которым у рядового пользователя может не быть прав на чтение. Поэтому функции проверки часто выносятся в привилегированные модули.
3. Изменение даты документа: Если пользователь пытается изменить дату документа с "открытой" на "закрытую" (или наоборот), система должна проверять обе даты — и старую, и новую. Метод ДатыЗапретаИзменения.ПроверитьДатуЗапретаИзменения(ЭтотОбъект) делает это автоматически, анализируя данные, записанные в базе, и текущие данные в памяти.
Подведем итог: для программной проверки даты запрета в 1С 8.3 наиболее правильным и современным способом является вызов функции ДатыЗапретаИзменения.ИзменениеЗапрещено() в серверном событии формы ПриЧтенииНаСервере. Это обеспечивает надежную защиту данных и корректное поведение пользовательского интерфейса.