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