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

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

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

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

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

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

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

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

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

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

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

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

// Объект ещё не записан — можно задать значения по умолчанию

НовыйЭлемент.УстановитьНовыйКод();

КонецЕсли;

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

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

// После успешной записи объект перестаёт быть новым

КонецЕсли;

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

Метод нельзя вызвать у ссылки (СправочникСсылка, ДокументСсылка) — попытка обращения вызовет ошибку времени выполнения. Для ссылок используются другие приёмы, описанные ниже.

Проверка нового объекта в форме

Через параметр Ключ формы

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

&НаСервере

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

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

// Форма открыта для нового объекта

ЭтотОбъект.Заголовок = "Новый элемент";

КонецЕсли;

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

Через Объект.Ссылка

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

События ПриКопировании и ОбработкаЗаполнения

Если элемент создаётся копированием, срабатывает событие модуля объекта ПриКопировании. В нём объект формально новый, но часть реквизитов уже заполнена — это важно учитывать, чтобы не перезаписать скопированные данные значениями по умолчанию. Событие ОбработкаЗаполнения вызывается только для новых объектов и подходит для установки начальных значений.

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

Как определить новизну, если есть только ссылка

Часто в процедуру передаётся не объект, а ссылка. В этом случае применяются три подхода:

  • Ссылка.Пустая() — возвращает Истина для пустой ссылки. Подходит, когда «новый объект» означает «ссылка ещё не присвоена».
  • Сравнение с пустой ссылкой конкретного типа: Если Ссылка = Справочники.Номенклатура.ПустаяСсылка() Тогда.
  • Проверка уникального идентификатора: Ссылка.УникальныйИдентификатор() — для пустой ссылки вернёт GUID из нулей.

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

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

Сравнение вариантов

ЭтоНовый()

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

Ссылка.Пустая()

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

Параметры.Ключ.Пустая()

Для форм при открытии. Надёжен при создании, но после записи в форме ключ уже заполнен.

Запрос к базе

Проверка существования ссылки в БД. Нужен для поиска битых ссылок, но требует обращения к базе.

Новые записи в регистрах сведений и наборах записей

У регистров нет метода ЭтоНовый() в привычном виде, потому что запись регистра сведений не имеет ссылки. Для менеджера записи (РегистрСведенийМенеджерЗаписи) новизна определяется косвенно: если запись с таким набором измерений ещё не существует в базе, то при записи она будет создана, иначе — перезаписана.

Чтобы заранее узнать, существует ли запись, выполните чтение методом Прочитать() и проверьте свойство Выбран():

МенеджерЗаписи = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Номенклатура = ТекНоменклатура;

МенеджерЗаписи.Прочитать();

Если МенеджерЗаписи.Выбран() Тогда

// Запись существует — будет обновление

Иначе

// Записи нет — будет создана новая

КонецЕсли;

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

Проверка новизны в запросах и при обмене данными

В языке запросов метода «это новый» нет — запрос работает только с данными, уже сохранёнными в базе. Поэтому в запросе проверяют не новизну, а факт существования: например, соединение с таблицей справочника и условие ГДЕ Таблица.Ссылка ЕСТЬ NULL покажет отсутствующие объекты.

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

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

Типичные ошибки при проверке нового объекта

  • Вызов ЭтоНовый() у ссылки. Приводит к ошибке времени выполнения. Проверяйте тип значения: для ссылки используйте Пустая().
  • Проверка после записи. После Записать() объект уже не новый, и ветка логики «для новых» не выполнится. Сохраняйте признак заранее.
  • Путаница между копированием и созданием. При копировании объект новый, но заполненный — сброс реквизитов в ОбработкаЗаполнения может затереть нужные данные.
  • Сравнение с Неопределено вместо пустой ссылки. Ссылочное поле по умолчанию содержит пустую ссылку, а не Неопределено; проверка Если Ссылка = Неопределено не сработает.
  • Использование ЭтоНовый() для регистров сведений. У менеджера записи этого метода нет — проверяйте существование через Прочитать() и Выбран().
Типичные ошибки
01
Вызов ЭтоНовый() у ссылки — ошибка выполнения, используйте Ссылка.Пустая()
02
Проверка новизны после Записать() — ветка логики никогда не сработает
03
Сравнение ссылки с Неопределено вместо ПустаяСсылка() — условие всегда ложно
04
Запись объекта только ради получения ссылки — мусорные объекты в базе

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

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

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

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

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

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

Создание нового элемента
Норма

Ветка ЭтоНовый() = Истина срабатывает до записи

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

Условие не выполняется — возможно, проверка идёт после Записать()

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

ЭтоНовый() возвращает Ложь, логика для новых не срабатывает

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

Объект снова считается новым — где-то создаётся дубликат

Работа со ссылкой
Норма

Пустая() корректно определяет незаполненную ссылку

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

Ошибка «Метод не обнаружен» — вызван ЭтоНовый() у ссылки

Итог

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

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

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

Чем ЭтоНовый() отличается от проверки Ссылка.Пустая()?

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

Можно ли получить ссылку нового объекта до записи?

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

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

Такое возможно, если объект не создан через СоздатьЭлемент()/СоздатьДокумент(), а получен методом ПолучитьОбъект() из существующей ссылки. Проверьте, откуда пришла переменная: вероятно, в неё уже попал объект, прочитанный из базы.

Как определить новый объект в управляемой форме до её открытия?

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

Работает ли ЭтоНовый() для планов обмена и бизнес-процессов?

Да, метод доступен для всех ссылочных объектных типов: планов обмена, бизнес-процессов, задач, планов видов расчёта и других. Логика одинаковая — Истина до первой записи, Ложь после.

Как проверить, существует ли объект в базе, если ссылка не пустая?

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