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