Чтение регистров сведений 1С 8.3: методы менеджера, запросы, срезы и просмотр данных

· 9 мин

Содержание

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

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

Виды регистров сведений и что от них зависит при чтении

Перед тем как писать код, откройте регистр в конфигураторе и посмотрите на две настройки на вкладке «Данные» и «Основные».

📌 Периодичность. Регистр бывает непериодическим или периодическим: по секунде, дню, месяцу, кварталу, году или по позиции регистратора. У периодического появляется поле Период, и у каждой комбинации измерений может быть история значений.

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

От этих настроек зависит набор доступных методов:

Что нужноНепериодическийПериодический
Одно значение по ключуПолучить(Отбор)ПолучитьПоследнее(Период, Отбор), ПолучитьПервое(Период, Отбор)
Перебор записейВыбрать(Отбор, Порядок)Выбрать(Начало, Конец, Отбор, Порядок)
Виртуальные таблицы в запросенетСрезПоследних, СрезПервых
Менеджер записитолько для независимоготолько для независимого
Набор записейестьесть

Все методы чтения работают на сервере. В управляемой форме вызывайте их из процедуры с директивой &НаСервере или из общего модуля с флажком «Сервер».

Чтение регистра сведений встроенным языком через менеджер

Менеджер регистра — это объект РегистрыСведений.ИмяРегистра. У него есть методы для быстрого точечного чтения.

Значение на дату: ПолучитьПоследнее и ПолучитьПервое

ПолучитьПоследнее() возвращает структуру ресурсов из последней записи с периодом не позже указанного. ПолучитьПервое() — из первой записи с периодом не раньше указанного.

&НаСервере
Функция КурсНаДату(Валюта, Дата)

    Отбор = Новый Структура("Валюта", Валюта);
    Данные = РегистрыСведений.КурсыВалют.ПолучитьПоследнее(Дата, Отбор);

    Если Данные.Кратность = 0 Тогда
        Возврат 0; // записи нет — ресурсы пустые
    КонецЕсли;

    Возврат Данные.Курс / Данные.Кратность;

КонецФункции

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

В конфигурациях на БСП для курсов есть готовая функция РаботаСКурсамиВалют.ПолучитьКурсВалюты(Валюта, Дата). Свой код для типового регистра не пишите — используйте её.

Непериодический регистр: метод Получить

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

Отбор = Новый Структура;
Отбор.Вставить("Организация", Организация);
Отбор.Вставить("Номенклатура", Номенклатура);
Данные = РегистрыСведений.МойРегистр.Получить(Отбор); // МойРегистр — имя вашего регистра
Значение = Данные.Значение;

Перебор записей: метод Выбрать

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

Отбор = Новый Структура("Валюта", Валюта);
Выборка = РегистрыСведений.КурсыВалют.Выбрать(
    НачалоГода(ТекущаяДатаСеанса()), КонецДня(ТекущаяДатаСеанса()), Отбор);

Пока Выборка.Следующий() Цикл
    Сообщить(СтрШаблон("%1: %2 за %3",
        Формат(Выборка.Период, "ДФ=dd.MM.yyyy"), Выборка.Курс, Выборка.Кратность));
КонецЦикла;

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

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

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

Набор записей: все строки по отбору

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

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

Для Каждого Запись Из Набор Цикл
    Сообщить(СтрШаблон("%1 — %2", Запись.Номенклатура, Запись.Значение));
КонецЦикла;

Для независимого регистра ставьте отбор по измерениям: Набор.Отбор.Организация.Установить(Организация). У периодического независимого регистра доступен ещё отбор по Период.

Не вызывайте Набор.Записать() после чтения «на всякий случай». Запись набора заменяет все строки по отбору тем, что лежит в коллекции. Пустой отбор при этом может стереть весь регистр.

Менеджер записи: одна строка по точному ключу

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

МЗ = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи();
МЗ.Период = '20261001';
МЗ.Валюта = Валюта;
МЗ.Прочитать();

Если МЗ.Выбран() Тогда
    Курс = МЗ.Курс;
Иначе
    Курс = 0; // записи ровно на эту дату нет
КонецЕсли;

Разница с ПолучитьПоследнее() важная. Менеджер записи ищет запись ровно на 1 октября. Если курс установлен 30 сентября, Выбран() вернёт Ложь, хотя курс на эту дату по смыслу есть.

Выборка данных регистра сведений запросом

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

К регистру можно обратиться двумя способами:

  • 📋 РегистрСведений.КурсыВалют — физическая таблица, все записи со всей историей;
  • ⏱ РегистрСведений.КурсыВалют.СрезПоследних(...) — виртуальная таблица, по одной актуальной записи на каждую комбинацию измерений.

Пример чтения всей истории курсов за период:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Курсы.Период КАК Период,
|    Курсы.Валюта КАК Валюта,
|    Курсы.Курс КАК Курс,
|    Курсы.Кратность КАК Кратность
|ИЗ
|    РегистрСведений.КурсыВалют КАК Курсы
|ГДЕ
|    Курсы.Период МЕЖДУ &Начало И &Конец
|
|УПОРЯДОЧИТЬ ПО
|    Валюта,
|    Период";

Запрос.УстановитьПараметр("Начало", НачалоМесяца(Дата));
Запрос.УстановитьПараметр("Конец", КонецМесяца(Дата));

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    // Выборка.Период, Выборка.Валюта, Выборка.Курс
КонецЦикла;

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

Работа с периодами: срез последних и срез первых

Виртуальные таблицы срезов — главное отличие периодических регистров. Они отвечают на вопрос «какое значение действовало на дату».

Срез последних на одну дату

"ВЫБРАТЬ
|    Курсы.Валюта КАК Валюта,
|    Курсы.Период КАК ДатаУстановки,
|    Курсы.Курс КАК Курс,
|    Курсы.Кратность КАК Кратность
|ИЗ
|    РегистрСведений.КурсыВалют.СрезПоследних(&НаДату, Валюта В (&Валюты)) КАК Курсы"

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

Срез берёт записи с периодом не позже переданной даты, включая время. Если передать '20261007' (это 00:00:00), запись, сделанная 7 октября в 10:15 у регистра с периодичностью «секунда», в срез не попадёт. Для конца дня передавайте КонецДня(Дата).

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

Значение на дату каждого документа

Частая задача: подставить курс на дату каждой реализации. Один срез на одну дату тут не подходит, потому что даты разные. Вызывать ПолучитьПоследнее() в цикле по документам — медленно.

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

"ВЫБРАТЬ
|    Док.Ссылка КАК Документ,
|    Док.ВалютаДокумента КАК Валюта,
|    МАКСИМУМ(Курсы.Период) КАК ПериодКурса
|ПОМЕСТИТЬ ВТ_Периоды
|ИЗ
|    Документ.РеализацияТоваровУслуг КАК Док
|        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК Курсы
|        ПО Курсы.Валюта = Док.ВалютаДокумента
|            И Курсы.Период <= Док.Дата
|ГДЕ
|    Док.Дата МЕЖДУ &Начало И &Конец
|
|СГРУППИРОВАТЬ ПО
|    Док.Ссылка,
|    Док.ВалютаДокумента
|;
|
|////////////////////////////////////////
|ВЫБРАТЬ
|    ВТ.Документ КАК Документ,
|    ЕСТЬNULL(Курсы.Курс, 0) КАК Курс,
|    ЕСТЬNULL(Курсы.Кратность, 1) КАК Кратность
|ИЗ
|    ВТ_Периоды КАК ВТ
|        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК Курсы
|        ПО Курсы.Период = ВТ.ПериодКурса
|            И Курсы.Валюта = ВТ.Валюта"

ЕСТЬNULL нужен для документов, у которых курса на дату нет: левое соединение вернёт для них NULL.

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

Иногда достаточно глазами проверить, что лежит в регистре. Для этого программировать не нужно.

Список регистра через «Все функции»

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

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

Консоль запросов

Консоль запросов — внешняя обработка, в которой пишут запрос и сразу видят результат. Её открывают в режиме предприятия через главное меню Файл → Открыть.

Порядок работы:

  1. Откройте файл обработки консоли (.epf).
  2. Если программа предупреждает о небезопасном действии, подтвердите открытие. Без права на интерактивное открытие внешних обработок файл не запустится — нужна роль администратора.
  3. Вставьте текст запроса или соберите его конструктором (правая кнопка → «Конструктор запроса»).
  4. Задайте параметры (&НаДату, &Валюты) в таблице параметров.
  5. Выполните запрос и посмотрите результат в нижней части формы.

Отлаживайте текст в консоли, а потом переносите в модуль. Так вы видите и данные, и время выполнения, не перезапуская сеанс.

В конфигураторе есть свой конструктор запроса: в модуле правая кнопка → «Конструктор запроса». Он помогает собрать текст, но данные не показывает.

В БП 3.0 для разовой выгрузки подойдёт и «Универсальный отчёт» из раздела «Отчёты»: в нём выбирают тип объекта «Регистр сведений», сам регистр и таблицу — основную или срез последних.

Как прочитать данные в вашем случае?

Ошибки и скорость чтения регистров сведений

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

❌ Условие среза в ГДЕ, а не в параметрах таблицы. Запрос СрезПоследних(&НаДату) ... ГДЕ Валюта = &Валюта сначала строит срез по всем валютам, потом фильтрует. Перенесите условие внутрь: СрезПоследних(&НаДату, Валюта = &Валюта).

❌ ПолучитьПоследнее() в цикле. Каждый вызов — отдельный запрос к базе. На 5 000 строк это 5 000 обращений. Замените одним пакетным запросом из раздела про периоды.

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

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

❌ Вызов с клиента. Код вида РегистрыСведений.КурсыВалют.ПолучитьПоследнее() в процедуре &НаКлиенте не скомпилируется: менеджеры регистров на клиенте недоступны.

❌ Пустой результат из-за времени. Дата среза без времени отсекает записи того же дня. Передавайте КонецДня(), если нужен итог на конец дня.

❌ Нет прав. Если у пользователя нет права «Чтение» на регистр, запрос упадёт с ошибкой доступа. Для служебного чтения в серверном коде применяют привилегированный режим — но только там, где это оправдано.

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

Чем срез последних отличается от физической таблицы регистра?
Физическая таблица содержит всю историю записей. Срез последних возвращает по одной записи на каждую комбинацию измерений — ту, что действовала на указанную дату.
Можно ли получить срез последних без даты?
Да. Если первый параметр не указан, срез строится на текущий момент по всем записям, включая сделанные будущими датами. Для расчётов надёжнее передавать дату явно.
Как узнать, когда было установлено значение?
Выберите поле Период из среза последних. В нём дата записи, из которой взято значение.
Как прочитать регистр сведений из внешней обработки?
Так же, как из конфигурации: через менеджер РегистрыСведений или запрос в серверной процедуре обработки. Обработка видит все объекты метаданных текущей базы.
Почему срез вернул несколько строк вместо одной?
Срез даёт строку на каждую комбинацию измерений. Если в условии задано только одно измерение из трёх, строк будет столько, сколько сочетаний остальных измерений есть в регистре.