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