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

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

Как в 1С проверить, что запись регистра сведений новая

Способы проверить, что запись регистра сведений 1С новая: методы Модифицированность, ЭтоНовый, запросы к таблице. Примеры кода, типичные ошибки и FAQ.

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

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

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

Что считается «новой» записью регистра сведений

Запись регистра сведений идентифицируется уникальной комбинацией значений измерений. Для периодического регистра в ключ дополнительно входит поле Период. Если в таблице регистра нет строки с такой комбинацией — запись новая. Если строка есть — запись существующая, и её запись фактически является обновлением.

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

Проверка через запрос к таблице регистра

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

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

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| Цены.Номенклатура КАК Номенклатура

|ИЗ

| РегистрСведений.ЦеныНоменклатуры КАК Цены

|ГДЕ

| Цены.Номенклатура = &Номенклатура

| И Цены.ВидЦены = &ВидЦены

| И Цены.Период = &Период";

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

Запрос.УстановитьПараметр("ВидЦены", ВидЦены);

Запрос.УстановитьПараметр("Период", Период);

ЗаписьНовая = Запрос.Выполнить().Пустой();

Если результат запроса пустой — записи с таким ключом нет, значит, запись новая. Для независимого регистра условие по периоду просто исключается. Используйте ПЕРВЫЕ 1, чтобы не выбирать лишние данные: интересует только факт наличия строки.

Для периодического регистра проверяйте точное совпадение периода, а не срез последних. Срез последних отвечает на другой вопрос — «какое значение действует на дату», и не подходит для определения новизны конкретной записи.

Проверка через набор записей и метод Выбрать

Альтернатива запросу — объектная модель. Установите отбор набора записей по ключу и прочитайте его: если набор пуст, записи не существует.

НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();

НаборЗаписей.Отбор.Номенклатура.Установить(Номенклатура);

НаборЗаписей.Отбор.ВидЦены.Установить(ВидЦены);

НаборЗаписей.Отбор.Период.Установить(Период);

НаборЗаписей.Прочитать();

ЗаписьНовая = (НаборЗаписей.Количество() = 0);

Также доступен менеджер записи: РегистрыСведений.ИмяРегистра.СоздатьМенеджерЗаписи(). Заполните его свойства ключом и вызовите Прочитать(). Если после чтения свойство Выбран() возвращает Ложь — записи в базе нет.

МенеджерЗаписи = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Номенклатура = Номенклатура;

МенеджерЗаписи.ВидЦены = ВидЦены;

МенеджерЗаписи.Период = Период;

МенеджерЗаписи.Прочитать();

ЗаписьНовая = Не МенеджерЗаписи.Выбран();

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

Запрос с ПЕРВЫЕ 1

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

Набор записей с отбором

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

Менеджер записи с Прочитать()

Подходит для работы с одной записью и последующего изменения; неудобен, если нужна только проверка факта существования

Проверка в форме записи

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

&НаСервере

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

ЭтоНоваяЗапись = Не Параметры.Свойство("Ключ")

Или Параметры.Ключ = Неопределено;

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

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

В обработчике ПередЗаписью или ПриЗаписи проверка новизны через запрос к таблице всё ещё корректна: на момент ПередЗаписью текущая запись в базу ещё не сохранена, поэтому пустой результат поиска по ключу означает новую запись. В ПриЗаписи запись уже может быть в транзакции записи — учитывайте это при чтении.

Проверка при программной записи и обмене данными

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

Если задача — не пропустить дубли, а просто «создать, если нет», можно обойтись без явной проверки: запись набора с установленным отбором по ключу сама перезапишет существующую строку. Но если бизнес-логика требует различать создание и обновление (например, разные уведомления или история изменений), проверка обязательна.

При обмене через планы обмена учитывайте, что признак новизны на стороне приёмника определяется состоянием базы-приёмника, а не отправителя. Запись, новая для отправителя, может уже существовать в приёмнике.

Порядок действий при программной записи
  1. 1
    Сформируйте ключ записи: значения всех измерений и периода
  2. 2
    Проверьте существование записи запросом или менеджером записи
  3. 3
    Если запись новая — заполните менеджер записи и вызовите Записать()
  4. 4
    Если запись существует — прочитайте её, измените нужные ресурсы и запишите
  5. 5
    Проверьте результат повторным чтением или в режиме предприятия

Типичные ошибки и как их избежать

Ошибки при такой проверке обычно приводят либо к дублям логики (запись считается новой, хотя существует), либо к ложным срабатываниям контроля. Большинство из них связано с неполным ключом или неверным моментом проверки.

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

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

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

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

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

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

Запись с заведомо новым ключом
Норма

Проверка возвращает «новая», запись создаётся

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

Проверка возвращает «существующая» — вероятно, лишнее условие в отборе

Запись с существующим ключом
Норма

Проверка возвращает «существующая», выполняется обновление

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

Возвращает «новая» — в отборе пропущено измерение или период

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

Дублей в регистре нет

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

Появляются строки с одинаковым смыслом, но разным периодом

Часто задаваемые вопросы

Есть ли у записи регистра сведений метод ЭтоНовый()?

Нет. Метод ЭтоНовый() существует у объектов со ссылкой (справочники, документы). У регистра сведений ссылки нет, поэтому новизна определяется поиском строки по ключу измерений и периода.

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

Только в форме: по отсутствию параметра Ключ при открытии. В прикладном коде без обращения к базе определить, существует ли строка с таким ключом, нельзя — эта информация хранится только в таблице регистра.

Чем отличается проверка для периодического и независимого регистра?

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

Почему проверка находит запись, хотя я её только что удалил?

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

Как проверить новизну при записи через набор записей с несколькими строками?

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

Можно ли полагаться на исключение при нарушении уникальности?

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

Итог

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

Новизна записи регистра сведений определяется отсутствием строки с таким же ключом измерений и периода. Проверяйте запросом с ПЕРВЫЕ 1 или менеджером записи с Прочитать(), включайте в отбор все измерения, выполняйте проверку до записи, а в форме ориентируйтесь на параметр Ключ.