При проектировании прикладных решений на платформе «1С:Предприятие 8» разработчики часто сталкиваются с важным архитектурным вопросом: где хранить подчиненные данные, которые привязаны к конкретному элементу справочника? Классический пример — справочник Пользователи и история их доступа к различным информационным системам.
На первый взгляд, самым простым решением кажется создание табличной части непосредственно внутри справочника. Однако на практике такой подход быстро приводит к снижению производительности, усложнению настройки прав доступа (RLS) и невозможности эффективно получать срезы данных на определенную дату. Профессиональный стандарт разработки в 1С требует вынесения подобных сведений в регистры сведений.
В этой статье мы подробно разберем, как связать справочник с регистром сведений, рассмотрим различные варианты реализации (от no-code настроек до программного управления) и выясним, как сделать интерфейс работы с регистром максимально удобным для пользователей.
---
Прежде чем перейти к технической реализации связи, давайте проанализируем, почему хранение истории доступов или периодических данных в регистре сведений является каноном разработки:
СрезПоследних. Реализовать подобное в табличной части справочника крайне затруднительно.Пользователи, но разрешить запись в регистр сведений для фиксации логов доступа.---
Это классический способ, который позволяет вывести записи регистра сведений прямо на форму элемента справочника в виде удобной таблицы. Данные будут считываться динамически, не нагружая основную форму объекта.
Разберем по шагам, как это реализовать:
ДС_Доступ.ДинамическийСписок.
ВЫБРАТЬ
РегистрДоступы.Период КАК Период,
РегистрДоступы.Пользователь КАК Пользователь,
РегистрДоступы.Система КАК Система,
РегистрДоступы.УровеньДоступа КАК УровеньДоступа
ИЗ
РегистрСведений.ДоступыПользователей КАК РегистрДоступы
ДС_Доступ на форму справочника. Платформа предложит создать таблицу — соглашайтесь.Теперь нам необходимо отфильтровать этот список, чтобы при открытии карточки пользователя показывались только его записи. Для этого перейдем в модуль формы и настроим событие ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверим, что элемент справочника уже записан в базу данных
Если ЗначениеЗаполнено(Объект.Ссылка) Тогда
// Добавляем программный отбор по текущему пользователю
ЭлементОтбора = ДС_Доступ.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Пользователь");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
ЭлементОтбора.ПравоеЗначение = Объект.Ссылка;
КонецЕсли;
КонецПроцедуры
Важная деталь: Чтобы при добавлении новой записи в регистр из этой таблицы поле Пользователь заполнялось автоматически, убедитесь, что в свойствах измерения Пользователь в самом регистре сведений стоит галочка «Заполнять из данных заполнения». Благодаря настроенному отбору на форме, платформа 1С автоматически передаст ссылку на текущего пользователя в форму создания новой записи регистра.
---
Если перед вами стоит задача связать объекты быстро и без написания программного кода, платформа 1С предоставляет мощный встроенный механизм связи через свойство измерения регистра.
Выясним, как работает свойство «Ведущее»:
Пользователь в вашем регистре сведений.Пользователи.Что это дает на практике?
---
По умолчанию динамический список (Способ 1) работает в режиме «только для чтения». Чтобы добавить или изменить запись, пользователю приходится открывать отдельное всплывающее окно записи регистра. Если вы хотите, чтобы работа с регистром выглядела точно так же, как работа с обычной табличной частью (то есть редактирование происходило прямо в ячейках таблицы на форме), вам необходимо использовать объект типа РегистрСведенийНаборЗаписей.
Рассмотрим по шагам, как настроить интерактивное редактирование:
ТаблицаДоступов.РегистрСведенийНаборЗаписей.[ИмяВашегоРегистра].Поскольку набор записей не умеет считываться автоматически, нам потребуется написать код для чтения данных при открытии формы и для их сохранения при записи справочника.
В модуле формы реализуем следующие обработчики событий:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если ЗначениеЗаполнено(Объект.Ссылка) Тогда
// Считываем записи регистра по текущему пользователю
ОбъектНабора = РегистрыСведений.ДоступыПользователей.СоздатьНаборЗаписей();
ОбъектНабора.Отбор.Пользователь.Установить(Объект.Ссылка);
ОбъектНабора.Прочитать();
// Заполняем реквизит формы данными из набора записей
ЗначениеВДанныеФормы(ОбъектНабора, ТаблицаДоступов);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
// Преобразуем данные таблицы формы обратно в объект набора записей
ОбъектНабора = ДанныеФормыВЗначение(ТаблицаДоступов, Тип("РегистрСведенийНаборЗаписей.ДоступыПользователей"));
// Перед записью обязательно фиксируем отбор по текущему объекту
ОбъектНабора.Отбор.Пользователь.Установить(ТекущийОбъект.Ссылка);
// Записываем набор в базу данных
ОбъектНабора.Записать();
КонецПроцедуры
Используя этот метод, вы получаете идеальный баланс: хранение данных в транзакционно-безопасном регистре сведений с одной стороны, и привычный, удобный для пользователя интерфейс ввода данных — с другой.
---
Выбор конкретного метода связывания зависит от бизнес-требований вашего приложения: