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

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

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

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

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

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

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

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

Ключ записи регистра сведений — это совокупность всех измерений. Для периодического регистра в ключ дополнительно входит поле Период. Две записи с одинаковыми значениями всех измерений (и периода) существовать не могут: платформа контролирует уникальность на уровне индекса.

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

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

Интерактивный поиск: форма списка регистра

Самый быстрый способ найти запись без программирования — открыть список регистра. В режиме предприятия регистр обычно доступен через меню «Все функции» (включается в настройках интерфейса): «Все функции» → «Регистры сведений» → нужный регистр. В типовых конфигурациях многие регистры также выведены в интерфейс разделов.

В форме списка используйте стандартный отбор: кнопка «Ещё» → «Настроить список» (или сочетание Ctrl+E в зависимости от версии платформы). Добавьте условия по измерениям — например, «Номенклатура = <значение>». После применения в списке останутся только подходящие записи.

Для поиска по части строки удобен поиск по строке (Ctrl+F) или отбор с видом сравнения «Содержит». Учтите: поиск «Содержит» по неиндексированному полю на большом регистре может выполняться долго, потому что платформа вынуждена просматривать все записи.

Поиск записи через форму списка
  1. 1
    Откройте «Все функции» → «Регистры сведений» → нужный регистр
  2. 2
    Нажмите «Ещё» → «Настроить список»
  3. 3
    Добавьте отбор по известным измерениям или ресурсу
  4. 4
    Примените отбор и проверьте, сколько записей найдено
  5. 5
    Откройте запись двойным щелчком для просмотра или правки

Программный поиск по ключу: МенеджерЗаписи

Когда известны все измерения (и период для периодического регистра), запись читается через менеджер записи. Последовательность: создать менеджер, заполнить поля ключа, вызвать Прочитать(), проверить Выбран().

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

Менеджер.Номенклатура = НужнаяНоменклатура;

Менеджер.ВидЦены = РозничныйВидЦены;

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

Если Менеджер.Выбран() Тогда

Сообщить("Цена: " + Менеджер.Цена);

Иначе

Сообщить("Запись не найдена");

КонецЕсли;

Проверка Выбран() обязательна. Если запись не найдена, метод Прочитать() не выдаст ошибку — менеджер просто останется пустым, а поля ресурсов будут содержать значения по умолчанию (ноль, пустая строка, пустая ссылка). Код, который не проверяет Выбран(), молча работает с пустышкой — это одна из самых коварных ошибок.

Поиск по произвольному отбору: НаборЗаписей

Если известна только часть измерений или условие задано по ресурсу, используйте набор записей с отбором. Отбор набора работает только на равенство — для неравенств, сравнений и «содержит» нужен запрос.

Набор = РегистрыСведений.ОтветственныеЛица.СоздатьНаборЗаписей();

Набор.Отбор.Организация.Установить(ТекОрганизация);

Набор.Прочитать();

Для Каждого Запись Из Набор Цикл

Сообщить(Запись.Сотрудник);

КонецЦикла;

После Прочитать() количество найденных записей доступно через Набор.Количество(). Ноль означает, что по заданному отбору записей нет. Помните: Прочитать() без установленного отбора загрузит в память весь регистр — на больших таблицах это может занять минуты и занять значительный объём оперативной памяти.

Типичные ошибки при поиске записей
01
Попытка использовать НайтиПоКоду() или ПолучитьСсылку() — у регистра сведений нет ссылок и этих методов
02
Чтение набора записей без отбора — загружается весь регистр, сервер «подвисает»
03
Отсутствие проверки Выбран() после Прочитать() — код работает с пустыми значениями, не подозревая об этом
04
Поиск по ресурсу через отбор набора — отбор поддерживает только равенство, сложные условия игнорируются логикой разработчика
05
Незаполненный период в ключе периодического регистра — ищется запись с пустой датой, а не актуальная

Поиск через запрос: гибкие условия и срез последних

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

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

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

"ВЫБРАТЬ

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

| Цены.Цена

|ИЗ

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

|ГДЕ

| Цены.Цена > &МинЦена";

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

Результат = Запрос.Выполнить().Выбрать();

Пока Результат.Следующий() Цикл

Сообщить(Результат.Номенклатура);

КонецЦикла;

Срез последних для периодического регистра

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

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

"ВЫБРАТЬ

| Срез.Номенклатура,

| Срез.Цена

|ИЗ

| РегистрСведений.ЦеныНоменклатуры.СрезПоследних(

| &ДатаСреза,

| Номенклатура = &Номенклатура) КАК Срез";

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

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

МенеджерЗаписи

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

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

Подходит для отбора по равенству одного-двух измерений. Не поддерживает неравенства и «содержит»

Запрос

Универсален: любые условия, срезы, соединения. Требует написания текста запроса, но оптимален по производительности

Форма списка

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

Производительность и ограничения

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

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

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

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

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

Менеджер записи
Норма

Выбран() = Истина, поля ресурсов заполнены ожидаемыми значениями

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

Выбран() = Ложь — запись с таким ключом не существует

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

Количество() больше нуля, значения соответствуют отбору

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

Количество() = 0 — проверьте значения отбора и типы данных

Запрос
Норма

Выборка содержит строки, условие ГДЕ соответствует данным

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

Пустой результат — проверьте параметры, дату среза и наличие данных в форме списка

Частые сценарии и практические уточнения

Подчинённый регистратору регистр сведений

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

Поиск по строковому измерению с учётом регистра

Сравнение строк в запросе зависит от настроек базы данных. Если поиск «не находит» заведомо существующую запись, проверьте наличие trailing-пробелов и невидимых символов в значении измерения — типичная ситуация после загрузки данных из внешних файлов. Функция СокрЛП() при записи данных избавляет от этой проблемы.

Проверка существования записи без чтения данных

Когда нужно только узнать, есть ли запись, не тяните все поля: в запросе выберите одно поле с ВЫБРАТЬ ПЕРВЫЕ 1 и проверьте Результат.Пустой. Это дешевле, чем чтение полной записи через менеджер.

Итог

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

Запись регистра сведений ищется по ключу измерений: полный ключ — через МенеджерЗаписи с проверкой Выбран(), частичный отбор — через НаборЗаписей, сложные условия и срезы — через запрос. У записи нет ссылки. Перед массовым изменением найденных записей делайте резервную копию.

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

Как найти запись регистра сведений, если известно только значение ресурса?

Используйте запрос с условием по ресурсу или отбор в форме списка. Учтите, что такой поиск не использует индекс ключа и на большом регистре может выполняться медленно. Если поиск по ресурсу нужен регулярно, рассмотрите включение индексирования для этого поля в конфигураторе.

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

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

Как найти актуальное значение периодического регистра на сегодня?

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

Можно ли получить ссылку на запись регистра сведений?

Нет, у записей регистра сведений нет ссылок — их идентифицирует ключ записи. Существует объект «КлючЗаписи», который можно передать в форму записи или использовать для навигации, но это не ссылка в привычном смысле: хранить его в реквизитах базы нельзя.

Как массово найти и удалить записи по условию?

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

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

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