Как организовать хранение данных для нескольких элементов справочника в одной записи регистра сведений?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

В практике разработки на платформе 1С:Предприятие часто возникает ситуация, когда бизнес-логика требует назначить один и тот же параметр (например, процент бонуса, скидку или цену) сразу нескольким контрагентам или товарам. На первый взгляд кажется логичным «сгруппировать» эти элементы в одной строке регистра, чтобы не плодить тысячи записей. Однако такое решение вступает в противоречие с архитектурой реляционных баз данных и механизмом индексации 1С. В этой статье мы подробно разберем, почему попытка впихнуть список в одно измерение — это плохая идея, и какие архитектурно верные альтернативы существуют.

Проблема «раздутого» регистра и психология пользователя

Рассмотрим ситуацию: пользователю нужно установить бонус 5% для 10 контрагентов по 20 позициям номенклатуры. В классической структуре регистра сведений БонусыКонтрагентов (измерения: Контрагент, Номенклатура; ресурс: ПроцентБонуса) это потребует создания 200 записей. Пользователь видит огромный список и просит: «Сделайте так, чтобы я мог выбрать список контрагентов в одной строке».

Важно понимать: количество записей в базе данных не должно волновать конечного пользователя. Его волнует только удобство ввода данных. Программист же должен обеспечить производительность системы. Попытка удовлетворить просьбу «буквально» (через создание списка в измерении) приведет к невозможности быстрого поиска данных запросом.

Решение 1: Использование механизма сегментации (Архитектурный подход)

Проанализируем ситуацию: если у группы контрагентов всегда одинаковые условия, значит, они образуют некую логическую общность. В типовых конфигурациях (ERP, УТ 11) для этого используется справочник Сегменты партнеров или Ценовые группы.

Рассмотрим шаги реализации этого метода:

  1. Создадим справочник СегментыКонтрагентов.
  2. В регистре сведений Бонусы заменим измерение Контрагент на СегментКонтрагента.
  3. В карточке контрагента добавим реквизит (или создадим отдельный регистр), указывающий на его принадлежность к сегменту.

Теперь для 100 контрагентов одного сегмента в регистре будет храниться всего одна запись. Это идеальный способ «уменьшения количества записей» без потери производительности.

Решение 2: Группы справочника как измерения

Если сегментация кажется избыточной, можно воспользоваться иерархией справочников. Рассмотрим этот вариант подробнее. Мы можем разрешить в измерении регистра выбирать не только элементы, но и группы (папки).

В этом случае при получении бонуса в запросе нам нужно будет проверять вхождение контрагента в группу. Однако стоит помнить, что прямая проверка В ИЕРАРХИИ в динамических списках или больших отчетах может замедлить работу. Тем не менее, это стандартный функционал платформы, который позволяет минимизировать количество ручного ввода.

Решение 3: Паттерн «Виртуальный список» через документ установки

Выясним, как сделать интерфейс удобным, сохранив правильную структуру данных. Вместо того чтобы заставлять пользователя работать напрямую с регистром, создадим документ УстановкаУсловийБонусов.

Разберем по шагам логику работы документа:

  1. В документе создаются две табличные части: СписокКонтрагентов и СписокНоменклатуры.
  2. В шапке указывается ПроцентБонуса.
  3. При проведении документа система программно «разворачивает» эти списки и записывает в регистр классические одиночные записи.

Посмотрим на пример кода в обработке проведения такого документа:


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    
    НаборЗаписей = РегистрыСведений.БонусыКонтрагентов.СоздатьНаборЗаписей();
    // Устанавливаем фильтр по регистратору, если регистр подчинен документу
    НаборЗаписей.Отбор.Регистратор.Установить(Ссылка);
    
    Для Каждого СтрКонтрагент Из СписокКонтрагентов Цикл
        Для Каждого СтрНоменклатура Из СписокНоменклатуры Цикл
            
            НоваяЗапись = НаборЗаписей.Добавить();
            НоваяЗапись.Период = Дата;
            НоваяЗапись.Контрагент = СтрКонтрагент.Контрагент;
            НоваяЗапись.Номенклатура = СтрНоменклатура.Номенклатура;
            НоваяЗапись.ПроцентБонуса = ПроцентБонуса;
            
        КонецЦикла;
    КонецЦикла;
    
    НаборЗаписей.Записать();
    
КонецПроцедуры

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

Решение 4: Использование Планов видов характеристик (ПВХ)

Проанализируем более гибкий вариант. Если условия бонусов зависят от множества факторов (регион, категория, объем закупок), использование ПВХ позволяет назначать свойства группам объектов. В регистре тогда хранятся связи не ссылок на объекты, а Значений свойств. Это делает систему максимально масштабируемой: вы добавляете нового контрагента в «Бонусную категорию А», и он автоматически подхватывает все настройки без редактирования регистра.

Почему нельзя использовать «Хранилище значения» в измерениях?

Иногда новички предлагают использовать ХранилищеЗначения или строку с перечисленными через запятую ID, чтобы хранить массив элементов в одной записи. Рассмотрим, почему это путь к катастрофе:

Использование расширений для интерфейса (современный подход)

В современных версиях платформы 1С (8.3.15+) можно программно группировать записи в списке регистра. Мы можем программно «схлопывать» одинаковые строки для визуального отображения пользователю. Это решается созданием динамического списка с произвольным запросом (GROUP BY), где в поле «Контрагент» выводится текст «Группа из N элементов». При этом физически в базе данных записи остаются разделенными, что сохраняет правильную архитектуру.

Выводы и рекомендации

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

  1. Используйте Сегменты или Группы для архитектурного упрощения.
  2. Используйте Документы для удобного группового ввода данных.
  3. Используйте Запросы и настройки Динамических списков для красивого отображения данных пользователю.

Помните, что «много записей» в регистре сведений — это не проблема, а штатный режим работы 1С, на который рассчитаны все механизмы индексации и поиска.

← На главную