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