При работе с платформой 1С:Предприятие разработчики и пользователи часто сталкиваются с различными типами прикладных объектов, каждый из которых имеет свои особенности и назначение. Одним из таких объектов является регистр сведений. В отличие от справочников, которые хранят относительно статические данные и обладают «объектной природой» с уникальными ссылками на каждый элемент, регистры сведений предназначены для хранения динамической информации. Возникает закономерный вопрос: как же обращаться к данным регистра, если у них нет привычных «элементов» и «ссылок»?
Давайте подробно разберем, в чем заключаются ключевые отличия справочников и регистров сведений, и как правильно взаимодействовать с записями регистров.
Начнем с того, что справочники и регистры сведений — это два совершенно разных типа прикладных объектов в системе 1С:Предприятие, каждый из которых разработан для решения определенных задач и обладает своей спецификой. Именно непонимание этих базовых различий часто приводит к попыткам применить неподходящие методы.
ПолучитьОбъект().Таким образом, когда мы говорим об «элементах регистра» или «ссылках на элемент регистра», мы используем терминологию справочников, которая неприменима к регистрам сведений. У регистров есть записи, которые идентифицируются не ссылкой, а ключом записи.
Поскольку у записей регистра сведений нет прямых ссылок, их уникальность определяется именно ключом записи.
Ключ записи — это комбинация значений всех измерений регистра сведений. Если регистр сведений является периодическим (то есть хранит данные с привязкой ко времени), то поле «Период» также входит в состав ключа записи. Эта совокупность значений гарантирует уникальность каждой записи в регистре. Мы не можем создать две записи в одном регистре сведений с одинаковым ключом. Если мы попытаемся записать новую запись с существующим ключом, старая запись будет перезаписана.
Представим, что у нас есть регистр сведений «КурсыВалют» с измерениями «Валюта» и «Период», и ресурсом «Курс». Ключом записи будет комбинация значений «Валюта» + «Период». Например, курс доллара (USD) на 01.01.2023 будет идентифицироваться как уникальная запись по ключу ("USD", "01.01.2023").
РегистрСведенийМенеджерЗаписи)Для работы с отдельными записями регистра сведений (чтения, изменения, удаления) мы используем специальный объект — РегистрСведенийМенеджерЗаписи. Этот менеджер позволяет нам указать значения измерений (и периода, если регистр периодический), чтобы найти и прочитать конкретную запись.
Разберем процесс по шагам:
СоздатьМенеджерЗаписи() у объекта регистра сведений.Период), которые образуют ключ искомой записи.Прочитать(): После установки всех необходимых значений, вызываем метод Прочитать(). Он пытается найти запись с указанным ключом. Если запись найдена, данные этой записи будут загружены в свойства менеджера записи (ресурсы), и метод вернет Истина. В противном случае, метод вернет Ложь.Посмотрим на пример из обсуждения, как получить курс валюты:
КурсМенеджер = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи();
КурсМенеджер.Валюта = ВыбВалюта; // ВыбВалюта - это значение измерения "Валюта", например, Справочники.Валюты.НайтиПоКоду("USD")
КурсМенеджер.Период = ТекущаяДата(); // Указываем период, если регистр периодический
Если КурсМенеджер.Прочитать() Тогда
Сообщить("Курс валюты на " + ТекущаяДата() + ": " + КурсМенеджер.Курс);
Иначе
Сообщить("Запись о курсе для выбранной валюты на текущую дату не найдена.");
КонецЕсли;
В этом примере переменная КурсМенеджер после успешного вызова Прочитать() содержит все данные конкретной записи (включая ресурсы, такие как Курс). Именно этот объект КурсМенеджер и является тем, что автор изначально называл «элементом регистра». Он позволяет нам получить доступ к значениям ресурсов и ресурсов данной записи.
Еще один пример, показывающий работу с произвольным регистром сведений:
МойРегистрМенеджер = РегистрыСведений.МойРегистр.СоздатьМенеджерЗаписи();
МойРегистрМенеджер.Измерение1 = ЗначениеИзмерения1;
МойРегистрМенеджер.Измерение2 = ЗначениеИзмерения2;
// ...и так далее для всех измерений, включая Период, если он есть
Если МойРегистрМенеджер.Прочитать() Тогда
// Теперь можем получить доступ к ресурсам, например:
Сообщить("Значение ресурса1: " + МойРегистрМенеджер.Ресурс1);
Иначе
Сообщить("Запись не найдена.");
КонецЕсли;
Важно: для корректного чтения записи необходимо установить значения всех измерений (и Период для периодических регистров), составляющих ключ записи. Если какое-либо измерение не будет установлено, система не сможет однозначно идентифицировать запись.
РегистрСведенийНаборЗаписей)Для пакетной работы с группами записей регистра сведений (массовое считывание, запись, удаление) используется объект РегистрСведенийНаборЗаписей. Он позволяет нам работать не с одной записью, а сразу с целой коллекцией, отобранной по определенным критериям (например, по значениям некоторых измерений или по периоду). Это особенно полезно, когда нужно обработать много записей за одну транзакцию.
Например, чтобы получить все курсы для определенной валюты за некоторый период:
НаборЗаписей = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Валюта.Установить(Справочники.Валюты.НайтиПоКоду("USD"));
// Можно также установить отбор по периоду:
// НаборЗаписей.Отбор.Период.Установить(НачалоГода(ТекущаяДата()), КонецГода(ТекущаяДата()));
НаборЗаписей.Прочитать(); // Считываем все записи, соответствующие отбору
Для Каждого ЗаписьКурса Из НаборЗаписей Цикл
Сообщить("Дата: " + ЗаписьКурса.Период + ", Курс: " + ЗаписьКурса.Курс);
КонецЦикла;
Объект РегистрСведенийЗапись, который мы получаем при итерации по НаборЗаписей, предоставляет доступ к полям отдельной записи и является аналогом «элемента» в контексте работы с регистром.
Одним из наиболее эффективных и гибких способов получения данных из регистров сведений, особенно при необходимости сложной выборки, фильтрации, группировки или соединения с другими таблицами, является использование запросов. Язык запросов 1С предоставляет мощные возможности для работы с данными регистров.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КурсыВалютСрезПоследних.Период,
| КурсыВалютСрезПоследних.Валюта,
| КурсыВалютСрезПоследних.Курс
|ИЗ
| РегистрСведений.КурсыВалют.СрезПоследних(&Период, Валюта = &ВыбВалюта) КАК КурсыВалютСрезПоследних";
Запрос.УстановитьПараметр("Период", ТекущаяДата());
Запрос.УстановитьПараметр("ВыбВалюта", Справочники.Валюты.НайтиПоКоду("USD"));
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Если Выборка.Следующий() Тогда
Сообщить("Курс доллара на " + Выборка.Период + ": " + Выборка.Курс);
Иначе
Сообщить("Курс доллара не найден.");
КонецЕсли;
Запросы позволяют получить данные регистра в виде таблиц значений или выборок, с которыми потом удобно работать.
Как же быть, если нам нужно «ссылаться» на запись регистра сведений в отчете или открывать её форму, как если бы это была ссылка на элемент справочника? Для этого мы используем именно ключ записи.
В отчетах мы можем формировать и выводить комбинацию значений измерений (и периода) таким образом, чтобы пользователь мог по ним перейти к нужной записи. Например, в пользовательском отчете мы можем сделать колонку с кнопкой или гиперссылкой, при нажатии на которую будет выполняться специальная процедура.
Рассмотрим шаги для открытия формы записи регистра сведений по ее ключу:
ОткрытьФорму() или ОткрытьЗначение(), передав в него имя формы и параметры, содержащие ключ записи. Наиболее удобный способ — использовать метод ОткрытьЗначение() или ПолучитьФормуЗаписи().Пример, как можно открыть форму записи регистра сведений «КурсыВалют» по заданным значениям:
// Предположим, у нас есть ВалютаСсылка и ДатаКурса
// и нам нужно открыть форму записи для этих значений.
// 1. Формируем ключ записи (структуру с измерениями и периодом)
КлючЗаписи = Новый Структура();
КлючЗаписи.Вставить("Валюта", ВалютаСсылка); // Измерение "Валюта"
КлючЗаписи.Вставить("Период", ДатаКурса); // Измерение "Период" для периодического регистра
// 2. Получаем менеджер записи и заполняем его значениями из ключа
МенеджерЗаписи = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(МенеджерЗаписи, КлючЗаписи);
// 3. Открываем форму записи.
// Если запись существует, она откроется для редактирования.
// Если нет, откроется новая форма с предзаполненными измерениями.
ФормаЗаписи = МенеджерЗаписи.ПолучитьФормуЗаписи();
Если ФормаЗаписи <> Неопределено Тогда
ФормаЗаписи.Открыть();
Иначе
Сообщить("Не удалось открыть форму записи регистра сведений КурсыВалют.");
КонецЕсли;
// Альтернативный способ для открытия формы существующей записи:
// Если МенеджерЗаписи.Прочитать() Тогда
// // Открываем форму существующей записи
// ФормаЗаписиСуществующей = МенеджерЗаписи.ПолучитьФормуЗаписи();
// ФормаЗаписиСуществующей.Открыть();
// Иначе
// Сообщить("Запись не найдена, создать новую?");
// // Если нужно создать новую запись, можно использовать
// // ФормаНовойЗаписи = РегистрыСведений.КурсыВалют.ПолучитьФормуЗаписи();
// // ФормаНовойЗаписи.КлючЗаписи = КлючЗаписи; // Предзаполняем измерения
// // ФормаНовойЗаписи.Открыть();
// КонецЕсли;
Таким образом, мы можем программно сформировать ключ записи на основании значений измерений и периода, а затем использовать этот ключ для открытия формы записи регистра сведений. Такой подход позволяет перейти к просмотру или редактированию конкретной записи, эффективно заменяя прямую «ссылку».
Отсутствие ссылок у записей регистров сведений обусловлено их основным назначением и архитектурными решениями платформы 1С:Предприятие. Представьте, что у каждой записи, например, курса валюты на каждый день, была бы своя уникальная ссылка (GUID). Это привело бы к следующим проблемам:
Дизайн регистров сведений с использованием ключа записи, состоящего из измерений, является более эффективным для хранения динамической, зависящей от контекста (измерений и периода) информации. Это позволяет системе быть гибкой и производительной при работе с большими объемами изменяющихся данных.
Итак, мы выяснили, что в системе 1С:Предприятие нет такого понятия, как «элемент регистра» или «ссылка на элемент регистра» в том смысле, в каком они существуют для справочников. У регистров сведений есть записи, которые уникально идентифицируются с помощью ключа записи, образованного совокупностью их измерений (и Периода для периодических регистров). Для работы с этими записями мы используем:
РегистрСведенийМенеджерЗаписи для чтения, изменения или удаления одной записи по ее полному ключу.РегистрСведенийНаборЗаписей для пакетной работы с группами записей.Если вам нужно «ссылаться» на запись регистра в отчете или открывать ее форму, вы должны оперировать ключом записи, программно формируя его и используя методы для открытия формы записи. Понимание этих принципов критически важно для корректной и эффективной разработки решений на платформе 1С:Предприятие.