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

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

Как в 1С проверить, что объект новый

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

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

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

Ниже разобраны рабочие способы проверки, типичные сценарии использования в обработчиках, отличия проверки объекта от проверки ссылки, а также ошибки, которые чаще всего приводят к неправильной логике в коде.

Метод ЭтоНовый(): как работает и когда возвращает Истина

Метод ЭтоНовый() доступен у всех объектных типов данных: СправочникОбъект, ДокументОбъект, ПланВидовХарактеристикОбъект, ПланСчетовОбъект, БизнесПроцессОбъект, ЗадачаОбъект и других. Он возвращает булево значение: Истина — объект создан в памяти, но ещё не записан в базу данных; Ложь — объект уже существует в базе и был прочитан или записан.

Важно понимать момент переключения: метод начинает возвращать Ложь только после фактической записи объекта. Если объект создан, заполнен реквизитами, но команда Записать() ещё не выполнялась, ЭтоНовый() вернёт Истина. После успешной записи в той же переменной метод уже вернёт Ложь.

НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();

НовыйЭлемент.Наименование = "Тестовая позиция";

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

Сообщить("Объект ещё не записан в базу");

КонецЕсли;

НовыйЭлемент.Записать();

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

Сообщить("Объект записан, ссылка: " + НовыйЭлемент.Ссылка);

КонецЕсли;

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

Проверка нового объекта в обработчиках событий формы

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

В модуле формы объект доступен через реквизит формы (обычно «Объект»), и проверка выглядит так:

&НаСервере

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

Если Объект.ЭтоНовый() Тогда

Объект.Ответственный = Пользователи.ТекущийПользователь();

КонецЕсли;

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

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

Проверка в модуле объекта: ПередЗаписью и ПриЗаписи

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

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

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

СтатусДокумента = Перечисления.СтатусыДокументов.Черновик;

КонецЕсли;

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

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

Как проверить, новый ли объект, если есть только ссылка

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

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

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 ИСТИНА ИЗ Справочник.Номенклатура

|ГДЕ Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", ПроверяемаяСсылка);

Если Запрос.Выполнить().Пустой() Тогда

Сообщить("Объекта с такой ссылкой в базе нет");

КонецЕсли;

Способы проверки

ЭтоНовый()

Для объекта в памяти. Возвращает Истина до первой записи. Не работает у ссылок и на клиенте управляемой формы.

Пустая ссылка / ЗначениеЗаполнено()

Проверяет, заполнено ли значение ссылки. Не говорит ничего о том, записан ли объект в базу.

Запрос к базе по ссылке

Проверяет фактическое существование записи в базе. Подходит для проверки битых ссылок и внешних данных.

Практические сценарии использования

Заполнение реквизитов по умолчанию при создании

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

Обработчики подписок на события

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

Защита от дублирования при программном создании

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

Порядок действий для проверки нового объекта
  1. 1
    Определите, с чем работаете: с объектом (СоздатьЭлемент/СоздатьДокумент/ПолучитьОбъект) или со ссылкой
  2. 2
    Если это объект — вызовите Объект.ЭтоНовый() до выполнения Записать()
  3. 3
    Если проверка нужна в форме — разместите её в серверном обработчике ПриСозданииНаСервере или ПередЗаписьюНаСервере
  4. 4
    Если проверка нужна в ПриЗаписи — заранее сохраните признак в ДополнительныеСвойства в обработчике ПередЗаписью
  5. 5
    Если есть только ссылка — проверьте существование записи запросом к базе
  6. 6
    Выполните тестовую запись и убедитесь, что логика срабатывает только при первом сохранении

Типичные ошибки и ограничения

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

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

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

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

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

Чтобы убедиться, что проверка работает правильно, достаточно создать тестовый элемент в режиме предприятия и проследить поведение кода. Быстрый способ — временно вывести значение через Сообщить() в обработчике ПередЗаписью: при первом сохранении должно быть Истина, при повторном — Ложь.

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

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

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

Первое сохранение объекта
Норма

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

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

Возвращает Ложь при первом сохранении — объект был записан ранее или проверка не там

Повторное сохранение
Норма

ЭтоНовый() возвращает Ложь, реквизиты по умолчанию не перезаписываются

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

Значения по умолчанию затирают введённые данные при каждой записи

Работа в форме
Норма

Проверка выполняется в серверном обработчике без ошибок

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

Ошибка «метод не обнаружен» на клиенте

Итог

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

Метод ЭтоНовый() — единственный штатный способ определить, записан ли объект в базу. Он работает только у объектов, только до первой записи и только на сервере. Для ссылок используйте проверку заполненности или запрос к базе, а признак новизны для ПриЗаписи сохраняйте заранее в ДополнительныеСвойства.

Часто задаваемые вопросы

Почему ЭтоНовый() возвращает Ложь, хотя элемент только что создан?

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

Можно ли проверить ЭтоНовый() у ссылки?

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

Чем новый объект отличается от пустой ссылки?

Новый объект — это заполненный в памяти экземпляр данных, ожидающий записи. Пустая ссылка — это отсутствие значения, «нулевой» идентификатор. Новый объект после записи получит реальную ссылку, пустая ссылка в базе никогда не существует как запись.

Работает ли ЭтоНовый() после УстановитьСсылкуНового?

Да, метод продолжает возвращать Истина. Установка ссылки нового объекта лишь заранее назначает идентификатор, но не записывает объект в базу. Статус изменится только после Записать().

Где правильно проверять новизну в подписке на событие?

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

Есть ли альтернатива ЭтоНовый() для определения первого сохранения?

Можно проверить, что реквизиты, заполняемые при записи (номер, дата у документа), ещё пустые, но это менее надёжно. Штатный и рекомендуемый способ — именно ЭтоНовый(), вызванный до записи объекта.