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