К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как в 1С при записи понять, что документ новый

Как в 1С при записи документа понять, что он новый: метод ЭтоНовый(), события ПриЗаписи и ОбработкаПроведения, типичные ошибки и примеры кода.

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

Основной инструмент — метод ЭтоНовый(), доступный у объекта документа. Он возвращает Истина, если у объекта ещё нет ссылки в базе данных, то есть документ создаётся впервые. Важно понимать: метод проверяет не «открыта ли форма нового документа», а физический факт наличия записи в базе. Поэтому его поведение различается в разных событиях жизненного цикла документа.

Ниже разобраны все рабочие способы: в обработчиках модуля объекта, в событиях формы, в подписках на события, а также типовые ошибки, из-за которых проверка «не срабатывает».

Как работает метод ЭтоНовый()

Метод ЭтоНовый() принадлежит объекту типа ДокументОбъект (а также справочникам, задачам и другим ссылочным объектам). Он сравнивает внутреннее состояние объекта с базой данных: если ссылка объекта ещё не существует в информационной базе, возвращается Истина.

Ключевой момент — когда именно ссылка появляется. При вызове Записать() платформа сначала генерирует ссылку для нового объекта (это происходит ещё до события ПередЗаписью), но физически запись в базу выполняется между событиями ПередЗаписью и ПриЗаписи. Из-за этого поведение метода в разных обработчиках отличается.

Простейший пример проверки в модуле объекта:

Если ЭтоНовый() Тогда

// Документ записывается впервые

Ответственный = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;

КонецЕсли;

Обратите внимание: если вызывать ЭтоНовый() у ссылки (например, Документы.РеализацияТоваров.НайтиПоНомеру(...)), метода там нет — он существует только у объектов. Это частая причина ошибки «Метод объекта не обнаружен».

Проверка в событиях ПередЗаписью и ПриЗаписи

Самая частая ловушка: разработчик помещает проверку ЭтоНовый() в обработчик ПриЗаписи и удивляется, что условие никогда не выполняется. Причина в том, что к моменту ПриЗаписи запись в базу уже выполнена, и метод возвращает Ложь.

Правильный порядок событий при записи документа:

  1. ПередЗаписью — объект ещё не в базе, ЭтоНовый() для нового документа вернёт Истина;
  2. физическая запись в базу данных;
  3. ПриЗаписи — документ уже существует, ЭтоНовый() всегда вернёт Ложь.

Если действие нужно выполнить именно в ПриЗаписи (например, отправить письмо уже после фиксации документа), признак новизны сохраняют в коллекции ДополнительныеСвойства:

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)

Если ЭтоНовый() Тогда

ДополнительныеСвойства.Вставить("ЭтоНовыйДокумент", Истина);

КонецЕсли;

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

Процедура ПриЗаписи(Отказ)

Если ДополнительныеСвойства.Свойство("ЭтоНовыйДокумент") Тогда

// Действия для только что созданного документа

КонецЕсли;

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

Коллекция ДополнительныеСвойства живёт в течение одного вызова записи и передаётся между всеми обработчиками, включая подписки на события. Это штатный механизм для передачи контекста между событиями.

Определение нового документа в ОбработкеПроведения

В событии ОбработкаПроведения ситуация аналогична ПриЗаписи: документ уже записан, и ЭтоНовый() вернёт Ложь. Если нужно отличить первое проведение от перепроведения, есть два подхода.

Первый — тот же приём с ДополнительныеСвойства из ПередЗаписью, поскольку проведение происходит в рамках той же цепочки записи. Второй — проверка наличия движений по регистрам: если у документа нет записей в регистре, значит, он проводится впервые. Второй способ надёжнее, когда документ мог быть записан без проведения, а проводится позже отдельной командой.

Маршрут решения

Как выбрать способ проверки

Логика нужна до фиксации документа в базеИспользуйте ЭтоНовый() в обработчике ПередЗаписью
Действие должно выполниться после записи (уведомление, интеграция)Сохраните признак в ДополнительныеСвойства и проверьте его в ПриЗаписи
Нужно отличить первое проведение от перепроведенияПроверяйте наличие движений по регистрам или признак из ПередЗаписью
Проверка выполняется в форме документаИспользуйте Параметры.Ключ.Пустая() или свойство Объект.Ссылка.Пустая()

Проверка в модуле формы документа

В управляемой форме документа объект доступен через реквизит Объект, и у него тоже можно вызвать Объект.ЭтоНовый() — но только на сервере и с осторожностью, так как реквизит формы типа ДанныеФормыСтруктура не всегда поддерживает этот метод напрямую. Надёжнее проверять ссылку: у нового, ещё не записанного документа ссылка пустая.

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Если Параметры.Ключ.Пустая() Тогда

// Открыта форма нового документа

КонецЕсли;

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

Проверка Параметры.Ключ.Пустая() в ПриСозданииНаСервере — стандартный способ понять, что форма открыта для нового объекта. После первой записи из формы ключ уже заполнен, поэтому для события ПослеЗаписи на клиенте признак новизны нужно передавать через параметр записи:

&НаКлиенте

Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)

Если Объект.Ссылка.Пустая() Тогда

ПараметрыЗаписи.Вставить("ЭтоНовый", Истина);

КонецЕсли;

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

Подписки на события и обмен данными

В подписках на события (ПередЗаписью, ПриЗаписи документов) логика идентична модулю объекта: источником является ДокументОбъект, и метод Источник.ЭтоНовый() работает по тем же правилам. Подписка удобна, когда не хочется менять модуль типового документа в конфигурации на поддержке.

Отдельный сценарий — загрузка данных через обмен. При обмене у объекта устанавливается ОбменДанными.Загрузка = Истина, и бизнес-логика обычно пропускается. Если ваш код в ПередЗаписью должен работать только при интерактивном создании документа, добавьте проверку:

Если ОбменДанными.Загрузка Тогда

Возврат;

КонецЕсли;

Если ЭтоНовый() Тогда

// Логика только для ручного создания

КонецЕсли;

Типичные ошибки и как их избежать

Первая ошибка — проверка ЭтоНовый() в ПриЗаписи или ОбработкеПроведения, где она заведомо вернёт Ложь. Симптом: код «ни разу не выполняется», хотя синтаксически всё верно. Решение — перенос проверки в ПередЗаписью с сохранением признака.

Вторая ошибка — попытка вызвать ЭтоНовый() у ссылки, а не у объекта. У типов ДокументСсылка этого метода нет. Если у вас есть только ссылка, проверяйте её на пустоту (Ссылка.Пустая()) или получайте объект через Ссылка.ПолучитьОбъект() — но помните, что это дорогая операция.

Третья ошибка — использование ЭтоНовый() для определения первого проведения. Документ может быть записан без проведения и проведён позже: тогда в ПередЗаписью при проведении метод уже вернёт Ложь, хотя проведение первое. Для этого сценария анализируйте движения по регистрам.

Типичные ошибки
01
Проверка ЭтоНовый() в ПриЗаписи — всегда Ложь, логика не выполняется
02
Вызов ЭтоНовый() у ссылки вместо объекта — ошибка «Метод объекта не обнаружен»
03
Смешение признака «новый документ» и «первое проведение» — это разные состояния
04
Отсутствие проверки ОбменДанными.Загрузка — логика срабатывает при обмене и портит данные

Проверка результата и отладка

Чтобы убедиться, что проверка работает, временно добавьте вывод в журнал регистрации или сообщение пользователю в обоих обработчиках:

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)

Сообщить("ПередЗаписью: ЭтоНовый = " + ЭтоНовый());

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

Создайте документ, запишите его, затем перезапишите повторно: при первой записи сообщение должно показать Истина, при повторной — Ложь. Если значение не меняется, проверьте, не открыта ли копия документа через «Скопировать» — копия до записи тоже является новой, и это нормальное поведение.

Контрольные точки

Как проверить результат

Первая запись документа
Норма

ЭтоНовый() в ПередЗаписью возвращает Истина

Тревожный признак

Возвращает Ложь — проверьте, не записывается ли документ программно до этого

Повторная запись
Норма

ЭтоНовый() возвращает Ложь

Тревожный признак

Возвращает Истина — возможно, объект создаётся заново вместо редактирования существующего

Признак в ПриЗаписи
Норма

ДополнительныеСвойства содержат признак из ПередЗаписью

Тревожный признак

Признак отсутствует — обработчики вызываются в разных экземплярах объекта

Итог

Что важно запомнить

ЭтоНовый() работает только у объекта и только до физической записи в базу. В ПередЗаписью — проверяйте напрямую, в ПриЗаписи и ОбработкеПроведения — используйте признак из ДополнительныеСвойства. В форме ориентируйтесь на Параметры.Ключ.Пустая().

Частые вопросы

Почему ЭтоНовый() в ПриЗаписи всегда возвращает Ложь?

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

Как отличить первое проведение от перепроведения?

Метод ЭтоНовый() для этого не подходит: документ мог быть записан раньше без проведения. Проверяйте наличие движений по регистрам документа — если записей нет, проведение выполняется впервые.

Можно ли вызвать ЭтоНовый() у ссылки документа?

Нет, метод существует только у объектов (ДокументОбъект и аналоги). Для ссылки используйте проверку Ссылка.Пустая() — пустая ссылка означает, что объект ещё не записан.

Как понять в форме, что открыт новый документ?

В обработчике ПриСозданииНаСервере проверьте Параметры.Ключ.Пустая() — для нового документа ключ пустой. После первой записи из формы ссылка уже заполнена, поэтому для ПослеЗаписи передавайте признак через ПараметрыЗаписи.

Срабатывает ли проверка при обмене данными?

Обработчики вызываются и при обмене, но обычно бизнес-логику там отключают. Проверяйте ОбменДанными.Загрузка в начале обработчика и завершайте выполнение, если установлено значение Истина.

Документ создан копированием — ЭтоНовый() вернёт Истина?

Да. Копия документа до первой записи не имеет ссылки в базе, поэтому для платформы это новый документ. Если нужно отличать копирование от создания «с нуля», проверяйте заполненность реквизитов или параметр формы ЗначениеКопирования.