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

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

При проектировании учетных систем в 1С часто возникает задача отображения аналитики по сложным многоуровневым связям. Типичный пример: есть перечень контрагентов с филиальной сетью, набор отделов и список оказываемых услуг. Если перемножить 100 контрагентов на 20 отделов, мы получим матрицу из 2000 строк. Заполнять такую матрицу вручную неэффективно, особенно если состав отделов и перечень услуг у филиалов одного заказчика одинаковы.

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

Вариант 1. Использование независимого регистра сведений «Матрица услуг»

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

Оптимальным решением для хранения таких связей является создание независимого непериодического регистра сведений. Разберем его структуру по шагам:

  1. Создаем справочник Контрагенты (или разделяем сущности на головные организации и филиалы).
  2. Создаем справочник Отделы (общий список возможных подразделений).
  3. Создаем справочник Услуги.
  4. Создаем непериодический регистр сведений МатрицаУслугОтделов со следующими измерениями:
    1. Контрагент (тип: СправочникСсылка.Контрагенты);
    2. Отдел (тип: СправочникСсылка.Отделы);
    3. Услуга (тип: СправочникСсылка.Услуги).

Регистр сведений дает возможность индексировать измерения для быстрого поиска, а также позволяет при необходимости добавить ресурсы (например, Цена или Активно). Чтобы не вводить 2000 строк вручную, реализуем механизм наследования через реквизит ГоловнойКонтрагент.

В справочнике Контрагенты добавляем реквизит ГоловнойКонтрагент ссылочного типа. Пользователь заполняет услуги и отделы только для головной компании (например, для 10 записей), а при формировании отчета система автоматически подтягивает эти данные для всех ее филиалов.

Посмотрим на пример запроса, который соединяет фактические филиалы с настройками головной организации:


ВЫБРАТЬ
	Филиалы.Ссылка КАК Контрагент,
	МатрицаГоловного.Отдел КАК Отдел,
	МатрицаГоловного.Услуга КАК Услуга
ИЗ
	Справочник.Контрагенты КАК Филиалы
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.МатрицаУслугОтделов КАК МатрицаГоловного
		ПО Филиалы.ГоловнойКонтрагент = МатрицаГоловного.Контрагент
ГДЕ
	НЕ Филиалы.ЭтоГруппа

Вариант 2. Иерархия справочников и табличные части

Если структура жестко закреплена за конкретным контрагентом и не меняется динамически, можно объединить структуру филиалов и отделов в специализированный справочник. Рассмотрим эту модель:

  1. Создаем справочник Контрагенты для учета юридических лиц.
  2. Создаем подчиненный или иерархический справочник СтруктураКонтрагентов, где верхний уровень иерархии — это филиал, а дочерний уровень — это отдел.
  3. В справочнике СтруктураКонтрагентов добавляем табличную часть Услуги со ссылкой на общий справочник Номенклатура (или Услуги).

Однако следует учитывать ограничения платформы: платформенные табличные части блокируют элемент справочника целиком при записи и не поддерживают вложенность. Кроме того, частое соединение табличных частей в аналитических отчетах уступает регистрам сведений по производительности на больших объемах данных.

Если перечень услуг и отделов фактически представляет собой спецификацию взаиморасчетов, более правильным решением будет использование типовой схемы: справочник ДоговорыКонтрагентов с табличной частью Спецификация. В таком случае филиал выступает стороной расчетов, а услуги определяются условиями соглашения.

Вариант 3. Формирование матрицы через декартово произведение (Cross Join)

Бывают ситуации, когда отделы и услуги у всех филиалов абсолютно типовые (например, любой филиал всегда имеет 20 фиксированных отделов и 10 фиксированных услуг), а в отчете требуется вывести полную сетку показателей, даже если по ним не было движений. В этом случае хранить 2000 записей в базе данных вообще не нужно.

Рассмотрим, как сгенерировать полную аналитическую матрицу средствами языка запросов 1С. Для этого используем декартово произведение таблиц:


ВЫБРАТЬ
	Контрагенты.Ссылка КАК Контрагент,
	Отделы.Ссылка КАК Отдел,
	Услуги.Ссылка КАК Услуга
ИЗ
	Справочник.Контрагенты КАК Контрагенты,
	Справочник.Отделы КАК Отделы,
	Справочник.Услуги КАК Услуги
ГДЕ
	НЕ Контрагенты.ЭтоГруппа

Разберем логику работы этого запроса: перечисление трех таблиц через запятую без условий соединения формирует все возможные комбинации строк. Далее к полученной сетке можно привязать реальные финансовые показатели с помощью конструкции ЛЕВОЕ СОЕДИНЕНИЕ по полям Контрагент, Отдел и Услуга, заменив пустые числовые значения с помощью функции ЕСТЬNULL().

Вариант 4. Настройка отчета с помощью Системы компоновки данных (СКД)

Если конечной целью является только наглядный вывод данных для пользователей, задачу можно решить в СКД без перегрузки структуры метаданных:

  1. Создаем схему компоновки данных с источником данных на основе регистра или декартова запроса.
  2. В настройках отчета выбираем структуру вывода в виде таблицы.
  3. В строки таблицы добавляем группировки Контрагент и Отдел.
  4. В колонки таблицы выносим группировку Услуга.
  5. В область выбранных полей помещаем суммовые ресурсы.

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

← На главную