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

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

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

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

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

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

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

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

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

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

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

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

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

Комментарий = "Создан автоматически";

КонецЕсли;

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

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

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

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

&НаСервере

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

Если Объект.ЭтоНовый() Тогда

Объект.Склад = Справочники.Склады.ОсновнойСклад;

КонецЕсли;

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

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

Альтернативные способы: пустая ссылка и запрос к базе

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

Ещё один вариант — запрос к базе: если поиск документа по уникальному идентификатору ничего не вернул, документа в базе нет. Такой подход применяют в обменах данными, когда нужно понять, пришёл ли документ впервые. Однако для обычной прикладной логики это избыточно: ЭтоНовый() решает задачу без лишних обращений к СУБД.

Сравнение способов проверки

ЭтоНовый()

Основной способ для объекта документа. Быстро, без запроса к базе. Не работает у ссылки.

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

Проверяет, присвоено ли значение ссылке. Подходит для реквизитов и переменных, но не говорит о записи в базу.

Запрос по GUID

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

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

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

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

Учтите разницу между ПередЗаписью и ПриЗаписи: в первом случае документ ещё не записан, и ЭтоНовый() вернёт Истина; во втором запись уже выполнена, поэтому проверку на новизну нужно делать заранее — например, сохранив результат в переменную в ПередЗаписью.

Перем ЭтоНовыйДокумент;

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

ЭтоНовыйДокумент = ЭтоНовый();

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

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

Если ЭтоНовыйДокумент Тогда

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

КонецЕсли;

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

Как отличить новый документ от скопированного

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

&НаСервере

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

Если Объект.ЭтоНовый() Тогда

Если Параметры.Свойство("ЗначениеКопирования")

И ЗначениеЗаполнено(Параметры.ЗначениеКопирования) Тогда

// документ создан копированием

Иначе

// документ создан "с нуля"

КонецЕсли;

КонецЕсли;

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

Типичные ошибки
01
Вызов ЭтоНовый() у ссылки документа — метод недоступен у ДокументСсылка, возникает ошибка выполнения
02
Проверка ЭтоНовый() в обработчике ПриЗаписи — документ уже записан, условие никогда не сработает
03
Путаница между новым и непроведённым документом — логика срабатывает не на тех документах
04
Проверка на новизну в ПриОткрытии формы после автосохранения — документ мог быть уже записан программно

Проверка в обработке проведения и при интерактивной работе

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

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

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

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

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

Условие Если ЭтоНовый() срабатывает, действия выполняются

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

Условие пропускается — проверьте, не вызван ли метод после записи

Повторная запись того же документа
Норма

Действия внутри условия не выполняются повторно

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

Код срабатывает снова — вероятно, объект пересоздаётся

Вызов метода
Норма

Метод вызван у ДокументОбъект или реквизита формы Объект

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

Ошибка «Метод не обнаружен» — метод вызван у ссылки

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

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

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

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

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

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

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

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

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

Что делать, если действие должно выполниться при первом проведении, а не при первой записи?

ЭтоНовый() здесь не поможет — при проведении документ уже записан. Используйте дополнительный реквизит-признак (например, булево «Обработан»), который устанавливается при первом успешном проведении, либо проверяйте наличие связанных записей в регистрах до формирования новых движений.

Итог

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

Основной способ проверить, что документ новый, — метод ЭтоНовый() у объекта документа. В модуле формы вызывайте Объект.ЭтоНовый(), в модуле объекта — ЭтоНовый(). Помните: новый — значит ни разу не записанный в базу, а не «непроведённый». Для действий при первой записи сохраняйте результат проверки в ПередЗаписью, так как в ПриЗаписи документ уже не новый.