В процессе эксплуатации систем на базе 1С:Предприятие 8 (таких как ERP, Комплексная автоматизация или Управление торговлей) часто возникает бизнес-задача: ограничить возможность редактирования документов пользователями по прошествии определенного времени. Например, если документ был проведен, у пользователя есть 2-3 дня на внесение правок, после чего документ должен стать доступен только для просмотра. Это необходимо для обеспечения неизменности данных после закрытия оперативного периода или расчета себестоимости.
В данной статье мы подробно разберем, как реализовать этот механизм, используя как штатные средства конфигураций на базе БСП (Библиотеки стандартных подсистем), так и способы программной доработки для специфических случаев.
Прежде чем приступать к написанию кода, проанализируем возможности типового функционала. В современных конфигурациях 1С (ERP, КА 2, УТ 11, БП 3.0) встроен мощный механизм Даты запрета изменения. Он позволяет устанавливать ограничения не только на фиксированную дату, но и использовать динамические (относительные) значения.
Рассмотрим по шагам, как настроить автоматический сдвиг даты запрета:
Важное уточнение: типовой механизм проверяет дату документа. Если документ создан «задним числом» (например, сегодня создали документ за прошлый месяц), он будет заблокирован сразу, если дата запрета уже наступила для того периода.
Если типовой механизм по каким-то причинам не подходит (например, требуется очень сложная логика проверки прав), можно воспользоваться программным методом. Проанализируем вариант с изменением свойства формы ТолькоПросмотр.
Этот метод часто используется начинающими разработчиками. В модуле формы документа в процедуре ПриОткрытии (на клиенте) или в ПриЧтенииНаСервере (на сервере) прописывается условие проверки даты:
&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
// Проверяем, что документ не новый и проведен
Если ТекущийОбъект.Проведен И (ТекущийОбъект.Дата + (3 * 24 * 60 * 60) < ТекущаяДата()) Тогда
ЭтаФорма.ТолькоПросмотр = Истина;
КонецЕсли;
КонецПроцедуры
Однако разберем недостатки этого подхода. Свойство ТолькоПросмотр на форме защищает только от интерактивного изменения пользователем. Если другой программист напишет обработку, которая меняет этот документ программно, или документ будет изменен через «Групповое изменение реквизитов», проверка в форме не сработает. Поэтому для надежной защиты данных следует использовать следующий метод.
Для реализации гарантированного запрета редактирования (как интерактивного, так и программного) лучше всего использовать Подписки на события. Это позволяет не снимать документ с поддержки и внедрить логику через расширение конфигурации.
Разберем алгоритм реализации:
рш_ЗапретРедактированияСервер).ДокументОбъект (можно выбрать конкретные типы документов).ПередЗаписью.
Процедура рш_ПроверитьДатуЗапретаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Исключаем проверку при загрузке данных
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Наша логика: запрет редактирования через 3 дня после даты документа
КоличествоДнейСекунд = 3 * 24 * 60 * 60; // 3 дня в секундах
Если Источник.Проведен И (Источник.Дата + КоличествоДнейСекунд < ТекущаяДата()) Тогда
// Проверяем, не является ли пользователь администратором (опционально)
Если Не РольДоступна("ПолныеПрава") Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Редактирование документа запрещено, так как прошло более 3-х дней с момента его создания.";
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Этот метод считается наиболее профессиональным, так как он срабатывает на уровне сервера непосредственно перед записью данных в базу.
Проанализируем ситуацию, упомянутую в обсуждении: что если бизнес требует считать 3 дня не от даты документа (которая может быть изменена), а от момента фактического проведения? Стандартная «Дата запрета» ориентируется именно на дату документа.
Если нам нужно блокировать изменения именно через 3 дня после того, как пользователь физически нажал кнопку «Провести», нам потребуется дополнительный реквизит. Выясним, как это реализовать:
ДатаПервогоПроведения (тип: Дата).ПередЗаписью будем заполнять этот реквизит только один раз при первом проведении.Дата, а по полю ДатаПервогоПроведения.Альтернативный вариант без добавления реквизитов — использование подсистемы Версионирование объектов. Мы можем программно обратиться к истории версий документа, найти самую раннюю версию со статусом «Проведен» и узнать её дату. Однако этот способ более трудозатратный и создает дополнительную нагрузку на систему при записи каждого документа.
Рассмотрим подробнее возможности настройки в ERP. Часто бывает нужно запретить редактирование складских документов через 2 дня, а финансовых — через 10. Типовой механизм позволяет это сделать:
Подведем итог: для решения задачи в 90% случаев достаточно штатного механизма «Даты запрета изменения» с использованием относительных дат (Конец дня/недели) и настройки отсрочки. К программной разработке стоит прибегать только в тех случаях, когда условие блокировки зависит от специфических реквизитов документа или фактического времени работы пользователя, не совпадающего с учетным периодом.