При разработке и доработке конфигураций на платформе 1С часто возникает задача проверить, открыт ли период для внесения изменений конкретным пользователем. Рассмотрим подробнее, как программно получить дату запрета редактирования для текущего сеанса и пользователя. Проанализируем несколько способов решения: от прямого чтения параметров сеанса до правильного использования современных механизмов Библиотеки стандартных подсистем (БСП).
В типовых конфигурациях прошлых поколений (и в некоторых текущих, где алгоритм еще не сильно усложнен) информацию о границах запрета можно извлечь прямо из параметров сеанса. Давайте посмотрим на пример, как получить общую дату запрета:
СоответствиеГраницЗапрета = ПараметрыСеанса.ГраницыЗапретаИзмененияДанных.Получить();
ОбщаяГраница = СоответствиеГраницЗапрета["ОбщаяДатаЗапретаРедактирования"];
Но что делать, если нам нужна дата для конкретного пользователя? Многие разработчики допускают одну и ту же ошибку — пытаются передать в соответствие пользователя информационной базы. Проанализируем типичный неверный код:
// ОШИБОЧНЫЙ ВАРИАНТ:
СоответствиеГраницЗапрета = ПараметрыСеанса.ГраницыЗапретаИзмененияДанных.Получить();
Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
ДатаЗапретаРедактированияПользователя = СоответствиеГраницЗапрета[Пользователь]; // Вернет пустоту!
Важный момент: выясним причину, почему возвращается пустое значение. Для поиска в структуре или соответствии границ запрета нужно использовать ссылку на элемент справочника Пользователи, а не объект пользователя информационной базы! Разберем исправленный вариант:
// ПРАВИЛЬНЫЙ ВАРИАНТ:
СоответствиеГраницЗапрета = ПараметрыСеанса.ГраницыЗапретаИзмененияДанных.Получить();
ПользовательСсылка = ПараметрыСеанса.ТекущийПользователь;
ДатаЗапретаРедактированияПользователя = СоответствиеГраницЗапрета[ПользовательСсылка];
Однако даже с правильной ссылкой мы можем получить пустое значение. Почему это происходит? В современных системах дата запрета может назначаться не только персонально пользователю, но и группе пользователей. Если дата установлена для группы, система при прямом поиске по ссылке пользователя ничего не найдет. Поэтому данный метод считается устаревшим и ненадежным для сложных баз.
Для конфигураций уровня 1С:ERP или УТ 11, где настройки хранятся в специализированном регистре сведений ДатыЗапретаИзменения, можно использовать прямой запрос. Посмотрим на пример запроса, который выбирает максимальную (самую строгую) дату запрета с учетом того, что для пользователя может не быть индивидуальной записи (тогда берется общая):
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДатыЗапретаИзменения.ДатаЗапрета КАК ДатаЗапрета,
| ДатыЗапретаИзменения.Пользователь КАК Пользователь,
| ДатыЗапретаИзменения.Пользователь.ИдентификаторПользователяИБ КАК Идентификатор,
| ДатыЗапретаИзменения.Пользователь.Предопределенный КАК Предопределенный
|ПОМЕСТИТЬ ВременнаяТаблица
|ИЗ
| РегистрСведений.ДатыЗапретаИзменения КАК ДатыЗапретаИзменения
|;
|ВЫБРАТЬ
| ВременнаяТаблица.ДатаЗапрета КАК ДатаЗапрета,
| ВременнаяТаблица.Пользователь КАК Пользователь
|ПОМЕСТИТЬ ВТ_ДатаБезГруппировки
|ИЗ
| ВременнаяТаблица КАК ВременнаяТаблица
|ГДЕ
| ВременнаяТаблица.Идентификатор ЕСТЬ NULL
| И ВременнаяТаблица.Предопределенный ЕСТЬ NULL
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ
| ВременнаяТаблица.ДатаЗапрета,
| ВременнаяТаблица.Пользователь
|ИЗ
| ВременнаяТаблица КАК ВременнаяТаблица
|ГДЕ
| ВременнаяТаблица.Пользователь = &Пользователь
|;
|ВЫБРАТЬ
| МАКСИМУМ(ВТ_ДатаБезГруппировки.ДатаЗапрета) КАК ДатаЗапрета
|ИЗ
| ВТ_ДатаБезГруппировки КАК ВТ_ДатаБезГруппировки";
Запрос.УстановитьПараметр("Пользователь", ПараметрыСеанса.ТекущийПользователь);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ДатаЗапрета = Выборка.ДатаЗапрета;
Иначе
ДатаЗапрета = '19990101'; // Если ограничений нет
КонецЕсли;
Этот метод работает, но он не учитывает разрез организаций, разделов учета и принадлежность пользователя к группам, хотя для УТ 11.5 существует готовый запрет проведения с даты документов по определенным организациям. Поэтому перейдем к самому правильному методу.
В современных решениях 1С (ERP, БП 3.0, ЗУП 3.1) настоятельно не рекомендуется получать эти данные прямыми запросами или чтением параметров сеанса. Алгоритмы расчета дат довольно сложны, система сама высчитывает результирующую дату, сравнивая общую дату, дату группы и персональную дату пользователя.
Вместо того чтобы изобретать велосипед, воспользуемся программным интерфейсом БСП. Обычно нам не нужно выводить саму дату на экран, нам нужно лишь узнать, разрешено ли изменение объекта — есть гибкая настройка ограничений на редактирование объектов. Проанализируем, как это сделать:
Проверка возможности изменения документа: (поможет контроль периода запрета изменения данных) Используйте функцию общего модуля ДатыЗапретаИзмененияСлужебный или ДатыЗапретаИзменения (зависит от версии БСП) или примените блокировку записи объекта по условию.
// Проверка при загрузке данных или программном проведении
Результат = ДатыЗапретаИзмененияСлужебный.ПроверитьДатыЗапретаИзмененияЗагрузкиДанных(ДокументОбъект, Ложь, Истина, Ложь);
Если Не Результат.ИзменениеЗапрещено Тогда
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Иначе
Сообщить("Изменение документа запрещено датой запрета!");
КонецЕсли;
Проверка произвольных данных: Вы можете проверить, закрыт ли период для конкретной организации, передав её в стандартный метод:
Отказ = Ложь;
ДатыЗапретаИзменения.ПроверитьДатыЗапретаИзмененияДанных(Источник, Отказ);
Система сама определит текущего пользователя, его группы доступа и проверит пересечение дат. Дополнительно может пригодиться блокировка и отслеживание изменений объектов 1С с формы — для этого есть универсальный контроль ввода данных и блокировка записи.
Получение самих рассчитанных дат: Если по бизнес-логике всё-таки нужно извлечь саму дату (например, чтобы настроить доступ и видимость реквизитов справочников), используйте специальные функции возврата действующих ограничений:
// Получаем структуру всех рассчитанных и закэшированных дат
РассчитанныеДаты = ДатыЗапретаИзмененияСлужебный.РассчитанныеДатыЗапретаИзменения();
Подводя итоги, настоятельно рекомендуем использовать именно методы БСП. Такой подход защитит ваш код от поломок при обновлениях конфигурации и избавит от необходимости самостоятельно программировать сложную логику пересечения прав групп, разделов учета и конкретных пользователей.