При проектировании учетных систем в 1С часто возникает задача отображения аналитики по сложным многоуровневым связям. Типичный пример: есть перечень контрагентов с филиальной сетью, набор отделов и список оказываемых услуг. Если перемножить 100 контрагентов на 20 отделов, мы получим матрицу из 2000 строк. Заполнять такую матрицу вручную неэффективно, особенно если состав отделов и перечень услуг у филиалов одного заказчика одинаковы.
Проанализируем архитектурные подходы к решению этой задачи: выясним, как правильно смоделировать данные в конфигурации 1С, избежать избыточного ручного ввода и быстро вывести результат в отчет.
Связь между сущностями в нашей задаче носит характер «многие-ко-многим»: один отдел может оказывать множество услуг, а одна услуга может предоставляться в разных отделах нескольких контрагентов. В платформе 1С стандартное подчинение справочников (через механизм Владелец) строго ограничено отношением «один-ко-многим», поэтому оно здесь не обеспечивает требуемую гибкость.
Оптимальным решением для хранения таких связей является создание независимого непериодического регистра сведений. Разберем его структуру по шагам:
Контрагенты (или разделяем сущности на головные организации и филиалы).Отделы (общий список возможных подразделений).Услуги.МатрицаУслугОтделов со следующими измерениями:
Контрагент (тип: СправочникСсылка.Контрагенты);Отдел (тип: СправочникСсылка.Отделы);Услуга (тип: СправочникСсылка.Услуги).Регистр сведений дает возможность индексировать измерения для быстрого поиска, а также позволяет при необходимости добавить ресурсы (например, Цена или Активно). Чтобы не вводить 2000 строк вручную, реализуем механизм наследования через реквизит ГоловнойКонтрагент.
В справочнике Контрагенты добавляем реквизит ГоловнойКонтрагент ссылочного типа. Пользователь заполняет услуги и отделы только для головной компании (например, для 10 записей), а при формировании отчета система автоматически подтягивает эти данные для всех ее филиалов.
Посмотрим на пример запроса, который соединяет фактические филиалы с настройками головной организации:
ВЫБРАТЬ
Филиалы.Ссылка КАК Контрагент,
МатрицаГоловного.Отдел КАК Отдел,
МатрицаГоловного.Услуга КАК Услуга
ИЗ
Справочник.Контрагенты КАК Филиалы
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.МатрицаУслугОтделов КАК МатрицаГоловного
ПО Филиалы.ГоловнойКонтрагент = МатрицаГоловного.Контрагент
ГДЕ
НЕ Филиалы.ЭтоГруппа
Если структура жестко закреплена за конкретным контрагентом и не меняется динамически, можно объединить структуру филиалов и отделов в специализированный справочник. Рассмотрим эту модель:
Контрагенты для учета юридических лиц.СтруктураКонтрагентов, где верхний уровень иерархии — это филиал, а дочерний уровень — это отдел.СтруктураКонтрагентов добавляем табличную часть Услуги со ссылкой на общий справочник Номенклатура (или Услуги).Однако следует учитывать ограничения платформы: платформенные табличные части блокируют элемент справочника целиком при записи и не поддерживают вложенность. Кроме того, частое соединение табличных частей в аналитических отчетах уступает регистрам сведений по производительности на больших объемах данных.
Если перечень услуг и отделов фактически представляет собой спецификацию взаиморасчетов, более правильным решением будет использование типовой схемы: справочник ДоговорыКонтрагентов с табличной частью Спецификация. В таком случае филиал выступает стороной расчетов, а услуги определяются условиями соглашения.
Бывают ситуации, когда отделы и услуги у всех филиалов абсолютно типовые (например, любой филиал всегда имеет 20 фиксированных отделов и 10 фиксированных услуг), а в отчете требуется вывести полную сетку показателей, даже если по ним не было движений. В этом случае хранить 2000 записей в базе данных вообще не нужно.
Рассмотрим, как сгенерировать полную аналитическую матрицу средствами языка запросов 1С. Для этого используем декартово произведение таблиц:
ВЫБРАТЬ
Контрагенты.Ссылка КАК Контрагент,
Отделы.Ссылка КАК Отдел,
Услуги.Ссылка КАК Услуга
ИЗ
Справочник.Контрагенты КАК Контрагенты,
Справочник.Отделы КАК Отделы,
Справочник.Услуги КАК Услуги
ГДЕ
НЕ Контрагенты.ЭтоГруппа
Разберем логику работы этого запроса: перечисление трех таблиц через запятую без условий соединения формирует все возможные комбинации строк. Далее к полученной сетке можно привязать реальные финансовые показатели с помощью конструкции ЛЕВОЕ СОЕДИНЕНИЕ по полям Контрагент, Отдел и Услуга, заменив пустые числовые значения с помощью функции ЕСТЬNULL().
Если конечной целью является только наглядный вывод данных для пользователей, задачу можно решить в СКД без перегрузки структуры метаданных:
Контрагент и Отдел.Услуга.Такой подход формирует компактную кросс-таблицу, которая наглядно отражает все пересечения филиалов, отделов и услуг без необходимости вручную заполнять тысячи записей в интерфейсе пользователя.