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

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

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

Способы получения данных из регистра сведений 1С: запросы, менеджер записи, срез последних и первых. Примеры кода, сравнение методов, типичные ошибки и FAQ.

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

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

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

Что важно знать о структуре регистра перед чтением

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

У периодического регистра есть служебное поле Период, и для него доступны виртуальные таблицы СрезПоследних и СрезПервых. У регистра, подчинённого регистратору, дополнительно есть поля Регистратор, НомерСтроки и Активность — при чтении почти всегда нужен отбор Активность = Истина.

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

Способ 1. Запрос к основной таблице регистра

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

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

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

"ВЫБРАТЬ

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

| Цены.ТипЦен,

| Цены.Цена

|ИЗ

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

|ГДЕ

| Цены.ТипЦен = &ТипЦен";

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

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

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

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

"ГДЕ

| Данные.Активность

| И Данные.Организация = &Организация"

Способ 2. Срез последних и срез первых

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

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

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

"ВЫБРАТЬ

| Срез.Валюта,

| Срез.Курс

|ИЗ

| РегистрСведений.КурсыВалют.СрезПоследних(&Период, Валюта = &Валюта) КАК Срез";

Запрос.УстановитьПараметр("Период", ДатаСреза);

Запрос.УстановитьПараметр("Валюта", Валюта);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

Курс = Выборка.Курс;

КонецЕсли;

Первый параметр виртуальной таблицы — период среза, второй — условие отбора по измерениям. Отбор внутри параметров виртуальной таблицы работает быстрее, чем отбор в секции ГДЕ после неё, потому что применяется до формирования среза. Это критично для больших регистров.

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

Способ 3. Менеджер записи для точечного чтения

Когда известна точная комбинация измерений (и периода для периодического регистра), быстрее и нагляднее использовать объектную модель — менеджер записи. Он читает ровно одну строку.

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

МенеджерЗаписи.Организация = Организация;

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

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

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

Ответственный = МенеджерЗаписи.Сотрудник;

КонецЕсли;

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

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

Способ 4. Набор записей с отбором

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

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

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

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

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

// обработка записи

КонецЦикла;

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

Сравнение способов чтения

Запрос к таблице

Массовое чтение, соединения, группировки. Самый быстрый для больших выборок, но результат не привязан к объектной модели.

СрезПоследних/СрезПервых

Актуальные значения периодического регистра на дату. Не работает с непериодическими регистрами.

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

Одна запись по точному ключу измерений. Не подходит для регистров с регистратором.

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

Несколько строк по отбору с возможностью изменения и записи. Требует обязательного отбора.

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

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

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

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

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

Количество строк выборки
Норма

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

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

Выборка пустая или содержит явно лишние строки — проверьте отборы и активность

Период записей в срезе
Норма

Дата каждой записи не позже даты среза

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

Записи будущей датой — параметр периода не передан или равен Неопределено

Значения ресурсов
Норма

Заполнены осмысленными значениями

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

Нули и пустые ссылки там, где данные должны быть, — возможно, читается не та ветка отбора

Типичные ошибки при чтении регистров сведений

Типичные ошибки
01
Чтение периодического регистра напрямую вместо среза — в результат попадают устаревшие значения за все периоды
02
Отсутствие проверки МенеджерЗаписи.Выбран() — программа использует пустые значения несуществующей записи
03
Отбор по измерениям в секции ГДЕ вместо параметров виртуальной таблицы — срез строится по всей таблице и работает в разы медленнее
04
Чтение набора записей без отбора — в память загружается весь регистр, на больших базах это приводит к нехватке памяти
05
Игнорирование поля Активность у регистра с регистратором — в выборку попадают отменённые движения

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

Ещё одна ошибка — использование ТекущаяДата() на клиенте для среза при клиент-серверной работе: часы клиента могут расходиться с сервером. Для срезов и отборов по периоду применяйте ТекущаяДатаСеанса().

Итог

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

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

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

Чем отличается СрезПоследних от обычного запроса с МАКСИМУМ(Период)?

По результату они эквивалентны, но виртуальная таблица оптимизирована платформой и обычно выполняется быстрее, особенно при отборе в параметрах. Ручная группировка с МАКСИМУМ оправдана, когда нужна нестандартная логика — например, срез в разрезе дополнительного условия по ресурсу.

Как получить данные регистра сведений в СКД или отчёте?

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

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

Да, через COM-connector доступны те же объекты: РегистрыСведений, запросы и виртуальные таблицы. Для интеграций чаще используют HTTP-сервисы, OData или планы обмена — они безопаснее и не требуют установки COM-компоненты.

Почему срез последних возвращает меньше строк, чем записей в регистре?

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

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

Создайте набор записей, установите отбор по регистратору со ссылкой на документ и вызовите Прочитать(). Альтернатива — запрос с условием Регистратор = &Ссылка и Активность = Истина, если изменять данные не требуется.

Что быстрее: запрос или обход набора записей?

Для чтения запрос почти всегда быстрее, потому что выполняется на сервере СУБД одним обращением и не создаёт объектную обёртку для каждой строки. Набор записей оправдан, только когда после чтения данные нужно изменить и записать обратно.