При разработке логики в 1С часто возникает необходимость изменять реквизиты документа (например, ставить текущего пользователя в поле Ответственный) только в том случае, когда документ открыт человеком и записывается из формы. Если же документ записывается массово через групповую обработку, проведением списком или программным методом Записать(), менять подобные реквизиты не требуется.
В платформе 1С прямого встроенного флага «ЗаписаноИнтерактивно» в событии ПриЗаписи объекта нет. Рассмотрим подробнее основные архитектурные подходы, которые позволяют красиво и глобально решить эту задачу.
Событие ОбработкаПроверкиЗаполнения вызывается расширением формы, когда пользователь интерактивно записывает или проводит документ из формы (а также при явном вызове метода ПроверитьЗаполнение()). Это делает его удобной точкой для выполнения действий, предназначенных исключительно для интерактивного режима.
Разберем, как настраивается подписка на это событие:
ОбработкаПроверкиЗаполнения.Посмотрим на пример кода в общем модуле:
Процедура ПодпискаОбработкаПроверкиЗаполнения(Источник, Отказ, ПроверяемыеРеквизиты) Экспорт
// Меняем ответственного только при интерактивном действии
Источник.Ответственный = Пользователи.ТекущийПользователь();
КонецПроцедуры
Нюансы метода:
Проанализируем особенности поведения этого события:
Разрешить, данное событие вызывается только при проведении документа. При нажатии кнопки «Записать» без проведения проверка заполнения и данный обработчик вызваны не будут.Объект.ПроверитьЗаполнение(), событие сработает и при таком программном вызове.Если нам нужно отлавливать запись именно в событии ПередЗаписью или ПриЗаписи, стандартным механизмом платформы является структура ДополнительныеСвойства объекта.
Чтобы не вносить изменения в форму каждого документа, заменим подходы: будем считать любую запись по умолчанию интерактивной, а при выполнении групповых обработок или программного проведения будем явно передавать признак групповой записи.
Разберем по шагам реализацию этой схемы:
Шаг 1. В коде групповой обработки перед вызовом метода Записать() добавляем флаг в дополнительные свойства объекта:
ДокументОбъект = СсылкаНаДок.ПолучитьОбъект();
ДокументОбъект.ДополнительныеСвойства.Вставить("ГрупповаяОбработка", Истина);
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Шаг 2. В подписке на событие ПриЗаписи или ПередЗаписью проверяем наличие этого флага:
Процедура ПодпискаПриЗаписи(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
ГрупповаяЗапись = Ложь;
Источник.ДополнительныеСвойства.Свойство("ГрупповаяОбработка", ГрупповаяЗапись);
Если Не ГрупповаяЗапись Тогда
// Логика, выполняемая только при интерактивной записи
Источник.Ответственный = Пользователи.ТекущийПользователь();
КонецЕсли;
КонецПроцедуры
Если задача состоит в том, чтобы отсечь записи, происходящие в фоновых заданиях, интеграциях или внешних соединениях, можно проанализировать тип текущего сеанса с помощью системной функции ИмяПриложения().
Выясним, как проверить контекст выполнения в обработчике события:
Процедура ПодпискаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
ТекущееПриложение = ИмяПриложения();
// Проверяем, что запись идет из тонкого, толстого или веб-клиента
ИнтерактивныйРежим = (ТекущееПриложение = "1CV8")
Или (ТекущееПриложение = "1CV8C")
Или (ТекущееПриложение = "WebClient");
Если ИнтерактивныйРежим Тогда
// Запись выполняется пользователем из клиента
КонецЕсли;
КонецПроцедуры
Если требуется хранить подробные данные о том, кто и как менял документ, без постоянной перезаписи основного реквизита Ответственный, рассмотрим следующие решения: