При настройке дат запрета изменения данных в программе 1С:ERP многие сталкиваются с неожиданным ограничением: требуется предоставить пользователям возможность редактировать документы за последние несколько дней (например, за 5 дней до текущей даты), однако при выборе варианта относительной даты Предыдущий день поле Вступает в действие с отсрочкой в... дней становится недоступным для редактирования. В то же время для значений вроде «Конец прошлого месяца» или «Конец прошлого квартала» отсрочка прекрасно работает. Разберем, почему платформа ведет себя именно так и какими способами можно реализовать требуемое скользящее окно редактирования.
Проанализируем архитектуру подсистемы дат запрета изменения, входящей в состав «Библиотеки стандартных подсистем» (БСП). В типовых конфигурациях функционал отсрочки задумывался исключительно для закрываемых отчетных периодов: месяца, квартала, года или недели.
Основное назначение механизма отсрочки — предоставить бухгалтерии и финансовым службам льготный интервал (к примеру, 5–10 календарных дней в начале нового месяца) для сведения итогов и сдачи отчетности за прошлый период. Пока льготные дни не истекли, граница запрета удерживается на уровне предпредыдущего периода.
Для варианта Предыдущий день отчетный интервал равен одним суткам. С точки зрения разработчиков БСП понятие «отсрочки закрытия отчетного периода» к суточному интервалу не применимо, поэтому поле программно блокируется на форме настройки. В типовом функционале отсутствует концепция «скользящего окна редактирования» назад на N дней от текущей даты. Кроме того, относительные даты запрета не рассчитываются динамически «на лету» при каждой записи документа: в регистре сведений ДатыЗапретаИзменения хранятся фиксированные абсолютные значения, которые ежедневно сдвигаются регламентным заданием Пересчет текущих значений относительных дат запрета изменения.
Рассмотрим вариант решения, предложенный на практике: создание отдельной дополнительной обработки, выполняющейся по расписанию раз в сутки (ночью). Эта обработка рассчитывает границу запрета для требуемых пользователей или групп пользователей по формуле ТекущаяДата() - КоличествоДней * 86400 и записывает значение в базу данных.
Однако здесь важно учитывать критический технический нюанс: значения дат запрета изменения кэшируются в сеансах пользователей в параметре сеанса ДействующиеДатыЗапретаИзменения. Если просто записать новую дату в регистр сведений ДатыЗапретаИзменения напрямую через менеджер набора записей, в уже открытых сеансах пользователей кэш не сбросится, и новые ограничения вступят в силу только после перезапуска программы пользователем.
Разберем по шагам, как правильно выполнить программную установку даты запрета через программный интерфейс БСП:
ДатыЗапретаИзмененияСлужебный, чтобы обновить данные в регистре и корректно инвалидировать кэш в параметрах сеанса.Посмотрим на пример кода, который рассчитывает и устанавливает границу запрета на 5 дней назад:
КоличествоДнейСмещения = 5;
НоваяДатаЗапрета = НачалоДня(ТекущаяДатаСеанса() - КоличествоДнейСмещения * 86400);
// Запись значений должна выполняться с учетом служебных механизмов БСП
НаборЗаписей = РегистрыСведений.ДатыЗапретаИзменения.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Пользователь.Установить(ВыбранныйПользователь);
НаборЗаписей.Отбор.Раздел.Установить(ПланыВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка());
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Пользователь = ВыбранныйПользователь;
НоваяЗапись.Раздел = ПланыВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка();
НоваяЗапись.ДатаЗапрета = НоваяДатаЗапрета;
НаборЗаписей.Записать();
// Обязательно вызываем обновление параметров работы программы для сброса сеансового кэша дат запрета
ДатыЗапретаИзмененияСлужебный.ОбновитьПараметрыОграниченияДоступа();
Более чистое и бесшовное решение, не требующее снятия основной конфигурации с поддержки, — использование механизма расширений конфигурации. Выясним причину, почему этот путь предпочтительнее: вся инфраструктура отчетов, штатного регламентного пересчета и интерфейса остается целостной.
ДатыЗапретаИзмененияПереопределяемый или перехватываем процедуру пересчета дат в модуле ДатыЗапретаИзмененияСлужебный с помощью аннотации &После или &Вместо.ТекущаяДатаСеанса().При таком подходе типовое фоновое задание Пересчет текущих значений относительных дат запрета изменения само выполняет обновление дат каждую ночь по штатному расписанию, автоматически управляя актуализацией кэша в активных пользовательских сеансах.
Если доработка конфигурации и добавление внешних заданий нежелательны, проанализируем доступные альтернативы без изменения кода:
Где Дата >= ДобавитьКДате(ТекущаяДата(), "ДЕНЬ", -5). Однако следует помнить, что использование RLS для контроля дат документов повышает нагрузку на СУБД по сравнению со штатным механизмом дат запрета.