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