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

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

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

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

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

Для работы с набором используется менеджер регистра, доступный через свойство глобального контекста РегистрыСведений. Метод СоздатьНаборЗаписей() возвращает пустой набор, который затем заполняется отбором и читается из базы методом Прочитать(). Без установленного отбора чтение вернёт все записи регистра, что на больших таблицах может занять значительное время и память.

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

Как создать набор записей через менеджер регистра

Точка входа — менеджер конкретного регистра сведений. Обращение строится по имени регистра, заданному в конфигураторе:

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

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

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

МенеджерРегистра = РегистрыСведений[ИмяРегистра];

НаборЗаписей = МенеджерРегистра.СоздатьНаборЗаписей();

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

Установка отбора перед чтением

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

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

НаборЗаписей.Отбор.Валюта.Установить(ВалютаСсылка);

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

Для периодического регистра доступен отбор по периоду. Чтобы получить записи за конкретную дату, устанавливают равенство, а для диапазона используют вид сравнения:

НаборЗаписей.Отбор.Период.ВидСравнения = ВидСравнения.БольшеИлиРавно;

НаборЗаписей.Отбор.Период.Значение = НачалоМесяца(ТекущаяДатаСеанса());

НаборЗаписей.Отбор.Период.Использование = Истина;

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

Чтение и перебор записей набора

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

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

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

Сообщить("Курс: " + Запись.Курс + " на " + Запись.Период);

КонецЦикла;

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

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

bsl
НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Номенклатура.Установить(НоменклатураСсылка);
НаборЗаписей.Прочитать();
Если НаборЗаписей.Количество() = 0 Тогда
    Сообщить("Записей по отбору не найдено");
КонецЕсли;

Изменение и запись набора: замещение и добавление

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

Чтобы добавить записи без удаления существующих, используют параметр Замещение = Ложь:

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

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

НоваяЗапись.Период = ТекущаяДатаСеанса();

НоваяЗапись.Валюта = ВалютаСсылка;

НоваяЗапись.Курс = 92.5;

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

При записи с замещением по отбору, который не был прочитан, набор считается пустым — и все записи по этому отбору будут удалены. Это стандартный способ очистки данных: установить отбор и записать пустой набор. Используйте его осознанно.

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

Особенности периодических и подчинённых регистров

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

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

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

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

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

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

Чем получить данные регистра

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

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

Запрос к таблице или СрезПоследних

Оптимален для чтения и анализа, отбор по любым полям, соединения с другими таблицами. Не изменяет данные

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

Для чтения, изменения или удаления одной записи по полному ключу измерений

Частые ошибки и проверка результата

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

Для отладки полезно выводить состояние набора до и после операций: количество записей, установленные элементы отбора, признак модифицированности (Модифицированность()). Это позволяет отличить «записей нет в базе» от «записи не прочитались из-за неверного отбора».

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

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

Количество записей после Прочитать()
Норма

Совпадает с ожидаемым по данным регистра

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

Ноль при заведомо существующих данных — проверьте значения отбора

Состав отбора перед Записать()
Норма

Установлены все нужные измерения или регистратор

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

Отбор пуст — запись затронет всю таблицу

Данные в базе после Записать()
Норма

Изменены только записи по отбору

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

Пропали записи, которые не должны были затрагиваться

FAQ

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

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

Можно ли получить набор записей с отбором по ресурсу?

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

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

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

Почему после Прочитать() набор пустой, хотя данные в регистре есть?

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

Нужно ли вызывать Прочитать() перед добавлением новых записей?

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

Работает ли СоздатьНаборЗаписей() на клиенте?

В тонком и веб-клиенте объект доступен только в серверном контексте. Код с набором записей следует размещать в серверных процедурах общих модулей или модулей объектов, а с клиента вызывать серверные методы.

Итог

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

Набор записей создаётся через РегистрыСведений.ИмяРегистра.СоздатьНаборЗаписей(), отбор устанавливается до Прочитать(), а Записать() по умолчанию замещает данные по отбору. Контроль отбора и количества записей — главная защита от потери данных.