В процессе разработки на платформе 1С:Предприятие часто возникает задача выноса части данных из справочника в отдельный регистр сведений (РС). Это может быть продиктовано необходимостью хранения истории изменений (периодический регистр), экономией ресурсов базы данных или требованиями типовых конфигураций (например, хранение паспортных данных в БП 3.0). Рассмотрим подробно, как реализовать этот механизм, начиная от простых способов записи и заканчивая правильной архитектурой при большом количестве полей.
Если для одного элемента справочника в регистре сведений должна соответствовать строго одна запись, удобнее всего использовать объект РегистрСведенийМенеджерЗаписи. Когда вы добавляете такой реквизит на форму, платформа позволяет напрямую обращаться к полям регистра. Однако важно помнить, что автоматической магии сохранения не произойдет — нам нужно программно связать объект справочника и запись регистра.
Разберем алгоритм действий по шагам:
ДанныеРегистра и типом РегистрСведенийМенеджерЗаписи.ВашРегистр.Проанализируем программный код в модуле формы. В обработчике ПриЧтенииНаСервере нам нужно инициализировать менеджер записи, чтобы пользователь увидел текущие данные из базы:
&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
// Устанавливаем отбор по ключевому измерению - ссылке на текущий элемент справочника
ДанныеРегистра.Объект = ТекущийОбъект.Ссылка;
ДанныеРегистра.Прочитать();
КонецПроцедуры
Для записи данных необходимо использовать событие ПередЗаписьюНаСервере или ПриЗаписиНаСервере. Выясним причину выбора: лучше использовать ПриЗаписиНаСервере, так как в этот момент у нового объекта уже точно есть сформированная ссылка в базе данных.
&НаСервере
Процедура ПриЗаписиНаСервере(ТекущийОбъект, Отказ, ПараметрыЗаписи)
// Заполняем измерение, если это новый элемент
ДанныеРегистра.Объект = ТекущийОбъект.Ссылка;
// Записываем данные регистра в той же транзакции, что и справочник
Попытка
ДанныеРегистра.Записать();
Исключение
ТекстОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Не удалось сохранить данные регистра: " + ТекстОшибки);
Отказ = Истина;
КонецПопытки;
КонецПроцедуры
В ситуациях, когда для одного справочника в регистре может быть несколько записей (например, история адресов или контактная информация), объект РегистрСведенийМенеджерЗаписи не подойдет. В этом случае мы используем РегистрСведенийНаборЗаписей.
Принцип работы схож, но вместо метода Прочитать() мы работаем с коллекцией строк. Посмотрим на пример инициализации набора:
&НаСервере
Процедура ПрочитатьНаборЗаписейНаСервере()
Набор = РегистрыСведений.ДанныеФизЛиц.СоздатьНаборЗаписей();
Набор.Отбор.ФизЛицо.Установить(Объект.Ссылка);
Набор.Прочитать();
// Значения из набора можно выгрузить в таблицу значений на форме
ЗначениеВРеквизитФормы(Набор.Выгрузить(), "ТЗ_ДанныеНаФорме");
КонецПроцедуры
Если в вашей задаче количество полей превышает сотню, создание 100 колонок в таблице справочника или регистре сведений — не лучшее решение. Это переусложняет структуру БД и замедляет работу формы при отрисовке. В профессиональной разработке (как в типовых решениях 1С) применяется паттерн EAV (Entity-Attribute-Value) или механизм Дополнительных реквизитов и сведений из БСП (Библиотеки стандартных подсистем).
Вместо 100 ресурсов в регистре, мы создаем регистр со следующей структурой:
Объект (Ссылка на справочник)Свойство (ПланВидовХарактеристик или Справочник с названиями полей)Значение (Любой тип данных)Рассмотрим преимущества этого подхода: вы можете добавлять новые параметры без изменения конфигурации (в режиме "1С:Предприятие"), а форма остается легкой. Для отображения таких данных на форме обычно используют динамическое создание элементов или одну таблицу со списком "Параметр — Значение".
Если вы проанализируете запись паспортных данных в регистр ДокументыФизическихЛиц, вы заметите, что 1С редко использует прямую привязку менеджера записи к форме. Вместо этого применяется модульный подход:
ПередЗаписьюНаСервере данные собираются в структуру.УчетПерсональныхДанных), который уже внутри себя открывает набор записей регистра, устанавливает отборы и выполняет запись.Такой подход позволяет разделять интерфейсную логику и логику работы с данными. Если вы хотите найти конкретное место записи, рекомендуется установить точку останова в модуле набора записей регистра (событие ПриЗаписи) и посмотреть стек вызовов. Это лучший способ научиться писать код по стандартам "1С".
Важный момент: если вы записываете данные в независимый регистр сведений из формы справочника, делайте это внутри транзакции записи основного объекта. Это гарантирует целостность: либо сохранятся и справочник, и данные в регистре, либо ничего не сохранится в случае ошибки.
Также помните о скорости отрисовки формы. Если у вас действительно много полей, распределите их по вкладкам (группам страниц). Установите свойство Содержимое при просмотре в значение Ленивое. В этом случае данные, находящиеся на невидимых в данный момент вкладках, не будут нагружать сервер и клиент до тех пор, пока пользователь не переключится на них.
Таким образом, мы разобрали основные способы интеграции регистров в формы справочников. Для простых задач используйте МенеджерЗаписи, для сложных и объемных — НаборЗаписей или механизмы дополнительных свойств.