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

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

1С: как проверить, новый документ или нет

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

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

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

Метод ЭтоНовый() — основной способ проверки

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

Типичный пример в модуле объекта документа:

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

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

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

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

КонецЕсли;

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

Важно понимать: у нового объекта ссылка уже может быть назначена (метод УстановитьСсылкуНового() или автоматическое получение ссылки при открытии формы), но ЭтоНовый() всё равно вернёт Истина, пока не выполнена физическая запись в базу. Метод опирается на факт записи, а не на наличие ссылки.

Проверка через ссылку: ПустаяСсылка и ЗначениеЗаполнено

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

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

// Ссылка ещё не назначена — документ новый

КонецЕсли;

Если НЕ ЗначениеЗаполнено(ДокументСсылка) Тогда

// Передан пустой параметр или ссылка нового объекта

КонецЕсли;

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

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

В управляемой форме документа объект доступен через реквизит Объект. Проверка на новый документ обычно выполняется в обработчике ПриОткрытии или ПриСозданииНаСервере:

&НаКлиенте

Процедура ПриОткрытии(Отказ)

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

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

УстановитьВидимостьЭлементов();

КонецЕсли;

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

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

Сценарий: запретить изменение реквизитов после записи

Частая задача — разрешить редактирование некоторых полей только у нового документа. Для этого в ПриОткрытии проверяют ссылку и устанавливают доступность элементов формы. Учтите, что после первой записи форма не переоткрывается автоматически, поэтому блокировку нужно выполнять и в обработчике ПослеЗаписи.

Проверка в обработчиках записи и проведения

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

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

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

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

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

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

Если ДополнительныеСвойства.Свойство("ЭтоНовый")

И ДополнительныеСвойства.ЭтоНовый Тогда

// Действия при первой записи

КонецЕсли;

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

Как выполнить код только при первой записи
  1. 1
    В обработчике ПередЗаписью сохраните ЭтоНовый() в ДополнительныеСвойства
  2. 2
    В ПриЗаписи проверьте сохранённое значение через ДополнительныеСвойства.Свойство()
  3. 3
    Выполните нужные действия только если признак равен Истина
  4. 4
    Проверьте поведение при копировании документа — оно тоже считается новым

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

Когда у вас есть только ссылка (например, получена из параметра, регистра или обмена), определить, существует ли документ, можно запросом:

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

Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 ИСТИНА

|ИЗ Документ.РеализацияТоваровУслуг КАК Док

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

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

ДокументСуществует = НЕ Запрос.Выполнить().Пустой();

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

Способы проверки: что выбрать

ЭтоНовый()

Лучший вариант в модуле объекта и ПередЗаписью. Не работает со ссылками и в ПриЗаписи.

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

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

Запрос к базе

Единственный надёжный способ проверить существование по ссылке извне. Затратнее по производительности.

ПолучитьОбъект() = Неопределено

Простая проверка существования, но вычитывает весь объект — не для массовых операций.

Особенности: копирование, обмен данными и установка номера

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

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

Номер документа не является признаком новизны: у нового документа номер может быть ещё не присвоен, а при ручной нумерации — заполнен пользователем до записи. Не используйте пустой номер как индикатор нового документа.

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

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

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

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

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

Как проверить корректность логики

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

Возвращает Истина

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

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

ЭтоНовый() в ПриЗаписи
Норма

Всегда Ложь — это норма

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

Ожидание Истина — признак ошибки проектирования

Поведение при копировании
Норма

Документ-копия определяется как новый

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

Копия обрабатывается как существующий документ

Итог

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

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

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

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

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

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

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

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

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

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

Выполните запрос вида «ВЫБРАТЬ ПЕРВЫЕ 1 ... ГДЕ Ссылка = &Ссылка» и проверьте результат на пустоту. Для единичной проверки допустимо Ссылка.ПолучитьОбъект() = Неопределено, но в циклах это медленно.

Считается ли скопированный документ новым?

Да. Копирование создаёт новый объект, который не записан в базу, поэтому ЭтоНовый() вернёт Истина. Если нужно отличить копию от «чистого» нового документа, проверяйте параметр формы ЗначениеКопирования.

Можно ли использовать пустой номер как признак нового документа?

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