Как настроить автозаполнение реквизита «Ответственный» без возможности дальнейшего изменения?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке конфигураций на базе Библиотеки Стандартных Подсистем (БСП) часто возникает задача: необходимо автоматически подставлять текущего пользователя в реквизит Ответственный при создании нового документа, а также заблокировать данное поле от дальнейших правок при открытии документа другими пользователями.

Рассмотрим детально, как правильно реализовать этот механизм как в модуле объекта, так и в форме управляемого документа.

Способ 1. Заполнение в модуле объекта (Рекомендуемый подход)

С точки зрения архитектуры 1С правильнее всего заполнять реквизиты объекта в обработчике ОбработкаЗаполнения модуля объекта. Это гарантирует, что реквизит заполнится не только при создании документа через форму, но и при его программном формировании.

Для получения текущего авторизованного пользователя в конфигурациях с БСП используются методы стандартного модуля Пользователи, например Пользователи.АвторизованныйПользователь() или Пользователи.ТекущийПользователь().

Разберем пример кода в модуле объекта документа:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
	
	// Если реквизит еще не заполнен, подставляем текущего пользователя
	Если Не ЗначениеЗаполнено(Ответственный) Тогда
		Ответственный = Пользователи.АвторизованныйПользователь();
	КонецЕсли;
	
КонецПроцедуры

Если в конфигурации используется общий модуль для централизованного заполнения документов, логику вызова можно вынести туда:


// В общем модуле ЗаполнениеДокументов Сервер
Процедура Заполнить(ДокументОбъект, ДанныеЗаполнения = Неопределено) Экспорт
	
	МетаданныеДокумента = ДокументОбъект.Метаданные();
	
	Если ОбщегоНазначения.ЕстьРеквизитОбъекта("Ответственный", МетаданныеДокумента) Тогда
		Если Не ЗначениеЗаполнено(ДокументОбъект.Ответственный) Тогда
			ДокументОбъект.Ответственный = Пользователи.АвторизованныйПользователь();
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

Способ 2. Заполнение и блокировка реквизита на форме документа

Если задача заключается только в управлении интерфейсом управляемой формы, заполнение и ограничение редактирования можно настроить в серверном событии формы ПриСозданииНаСервере.

Проанализируем пример кода формы документа:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	// Заполняем ответственного, если объект новый или поле пустое
	Если Объект.Ссылка.Пустая() Или Не ЗначениеЗаполнено(Объект.Ответственный) Тогда
		Объект.Ответственный = Пользователи.АвторизованныйПользователь();
	КонецЕсли;
	
	// Запрещаем редактирование поля для записанных документов
	Если ЗначениеЗаполнено(Объект.Ссылка) Тогда
		Элементы.Ответственный.ТолькоПросмотр = Истина;
	КонецЕсли;

КонецПроцедуры

Поясним ключевые особенности этого кода:

  1. Проверка Объект.Ссылка.Пустая() позволяет узнать, создается ли новый документ или открывается ранее записанный.
  2. Свойство ТолькоПросмотр = Истина блокирует элемент формы Ответственный от изменений пользователем, при этом поле остается визуально доступным для чтения.
  3. Если требуется заблокировать поле даже на этапе создания документа (чтобы пользователь не мог выбрать другого ответственного вручную), строку блокировки Элементы.Ответственный.ТолькоПросмотр = Истина; можно выполнять безусловно, вне зависимости от того, новый документ или нет.

Способ 3. Серверная защита от программного изменения

Визуальный запрет на форме не защищает от изменения реквизита через внешние обработки или групповые изменения. Для надежной защиты данных добавим проверку в событие ПередЗаписью модуля объекта:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
	
	// Проверяем попытку изменения ответственного у ранее записанного документа
	Если Не ЭтоНовый() Тогда
		ОтветственныйВБазе = Ссылка.Ответственный;
		Если ЗначениеЗаполнено(ОтветственныйВБазе) И Ответственный <> ОтветственныйВБазе Тогда
			ВызватьИсключение "Запрещено изменять ответственного у записанного документа!";
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

Благодаря сочетанию двух уровней защиты (интерфейсного в форме и программного в модуле объекта) реквизит Ответственный будет корректно заполняться при создании и надежно защищен от любых изменений в будущем.

← На главную