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