В процессе разработки и сопровождения нетиповых конфигураций 1С часто возникает задача ограничить возможность редактирования документов задним числом. Это критически важно для соблюдения целостности учета, особенно перед закрытием месяца. В этой статье мы подробно разберем, как реализовать гибкий механизм даты запрета, который можно настраивать в разрезе пользователей, организаций или видов документов.
Для начала нам необходимо определить, где система будет хранить информацию о датах запрета. Существует два основных подхода: использование констант (для одной общей даты на всю базу) или использование справочников/регистров сведений (для гибкой настройки).
Разберем более продвинутый вариант — создание справочника ДатыЗапрета. В этом справочнике мы можем создать следующие реквизиты:
Чтобы не дублировать код в каждом документе, вынесем логику проверки в Общий модуль (например, с именем РаботаСДатамиЗапрета). У модуля должны быть установлены флаги "Сервер" и "Вызов сервера".
Проанализируем пример функции, которая будет выполнять запрос к нашему справочнику и определять, попадает ли дата документа в закрытый период:
Функция ПроверитьДатуЗапрета(ДатаДокумента, ПользовательСсылка) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДатыЗапрета.ДатаЗапрета КАК ДатаЗапрета
|ИЗ
| Справочник.ДатыЗапрета КАК ДатыЗапрета
|ГДЕ
| ДатыЗапрета.Пользователь = &Пользователь";
Запрос.УстановитьПараметр("Пользователь", ПользовательСсылка);
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
// Если дата документа меньше или равна установленной дате запрета
Если ДатаДокумента <= КонецДня(Выборка.ДатаЗапрета) Тогда
Возврат Истина; // Редактирование запрещено
КонецЕсли;
КонецЕсли;
Возврат Ложь; // Редактирование разрешено
КонецФункции
Обратите внимание: при сравнении дат важно использовать КонецДня или НачалоПериода, чтобы избежать ошибок, связанных с разницей в часах и секундах.
Для удобства пользователя форму документа лучше сразу открывать в режиме "Только просмотр", если дата попадает под запрет. Рассмотрим, как это реализовать в процедуре ПриСозданииНаСервере модуля формы документа.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем, что это не новый документ (для новых запрет обычно не действует)
Если НЕ Объект.Ссылка.Пустая() Тогда
// Вызываем нашу экспортную функцию
Если РаботаСДатамиЗапрета.ПроверитьДатуЗапрета(Объект.Дата, Пользователи.ТекущийПользователь()) Тогда
ЭтаФорма.ТолькоПросмотр = Истина;
// Дополнительно можно скрыть кнопки проведения
ЭтаФорма.Доступность = Ложь;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Использование свойства ТолькоПросмотр позволяет пользователю видеть данные документа, но запрещает любые изменения в полях формы.
Важно понимать, что ограничение на уровне формы — это лишь интерфейсное решение. Продвинутый пользователь или внешняя обработка могут изменить объект программно, минуя форму. Чтобы сделать запрет "железным", необходимо добавить проверку в модуль объекта документа в обработчик ПередЗаписью.
Выясним, как это выглядит на практике:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Если запись инициирована обменом данными, проверку обычно пропускают
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Проверяем дату
Если РаботаСДатамиЗапрета.ПроверитьДатуЗапрета(ЭтотОбъект.Дата, ПользователиИнформационнойБазы.ТекущийПользователь()) Тогда
Отказ = Истина;
Сообщить("Ошибка: Период редактирования для данного документа закрыт!");
Возврат;
КонецЕсли;
КонецПроцедуры
При реализации собственного механизма даты запрета мы рекомендуем учитывать следующие моменты:
ПараметрыСеанса. Это значительно повысит производительность.ПередЗаписью для типа ДокументОбъект. Это позволит управлять логикой запрета для всей конфигурации из одного места.РольДоступна("ПолныеПрава").Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), обязательно проанализируйте подсистему "Даты запрета изменения". Она уже содержит весь описанный функционал, включая автоматический перенос даты (например, "конец прошлого месяца + 5 дней") и разделение по разделам учета.