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

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

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

Исходная структура данных может выглядеть следующим образом:

  1. Партнер (Верхний уровень)
  2. - Контрагент1 (связан с Верхним Партнером)
  3. - ДочернийПартнер (подчинен Верхнему Партнеру)
  4. - (нет собственного связанного контрагента)
  5. - ВторойДочернийПартнер (подчинен ДочернемуПартнеру)
  6. - Контрагент2 (связан с ВторымДочернимПартнером)

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

  1. Партнер (Верхний уровень) - Контрагент1
  2. ДочернийПартнер - Контрагент1
  3. ВторойДочернийПартнер - Контрагент1
  4. ВторойДочернийПартнер - Контрагент2

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

Использование регистра сведений "ИерархияПартнеров" для получения всех контрагентов по иерархии

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

Преимущества использования "ИерархияПартнеров":

  1. Производительность: Регистр предоставляет предварительно рассчитанную иерархию, что позволяет избежать сложных рекурсивных запросов к справочнику, которые могут быть ресурсоемкими на больших объемах данных.
  2. Простота запросов: Мы можем получить всю необходимую информацию с помощью простого объединения таблиц, а не сложных итераций.
  3. Гибкость: Регистр обычно содержит измерения Партнер и Родитель, а также может иметь ресурс Уровень, который указывает на глубину вложенности партнера относительно его непосредственного родителя или корневого элемента иерархии.

Давайте посмотрим на пример запроса, который позволяет нам получить желаемую выборку:


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

Разберем этот запрос по шагам:

  1. Мы обращаемся к регистру сведений РегистрСведений.ИерархияПартнеров, который хранит информацию о том, какой партнер (измерение Партнер) является потомком какого родителя (измерение Родитель). Важно понимать, что в данном регистре для каждого партнера есть запись, где Партнер равен Родитель (т.е. сам партнер является своим собственным "родителем" на уровне 0), а также записи со всеми его вышестоящими родителями.
  2. Затем мы выполняем ВНУТРЕННЕЕ СОЕДИНЕНИЕ с таблицей Справочник.Контрагенты.
  3. Ключевым моментом является условие соединения: ПО ИерархияПартнеров.Родитель = Контрагенты.Партнер. Это означает, что для каждого партнера из регистра иерархии мы ищем всех контрагентов, которые связаны с его родительскими элементами (включая самого партнера, если он является своим "родителем" в регистре). Таким образом, мы получаем список всех контрагентов, привязанных ко всей цепочке родителей, включая текущего партнера.

Этот подход позволяет нам эффективно получить все необходимые данные для дальнейшего использования в отчетах СКД или в программном коде.

Альтернативный подход с использованием оператора "В ИЕРАРХИИ" и временных таблиц

В некоторых случаях, особенно если необходимо получить потомков определенного "головного" партнера или если мы работаем в контексте динамического списка, где основной таблицей является Справочник.Партнеры, мы можем использовать оператор В ИЕРАРХИИ. Этот оператор полезен для получения всех подчиненных элементов иерархического справочника, включая сам заданный элемент. Однако, для решения нашей текущей задачи (получение контрагентов родителей) его прямое применение может быть менее очевидным, чем использование ИерархияПартнеров.

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

Рассмотрим пример, когда нам нужно получить всех партнеров, которые находятся в иерархии определенного головного партнера, а затем их контрагентов:

  1. Получаем всех партнеров по иерархии головного:

ВЫБРАТЬ
    Партнеры.Ссылка КАК Партнер
ПОМЕСТИТЬ ВТ_ВсеПартнеры
ИЗ
    Справочник.Партнеры КАК Партнеры
ГДЕ
    Партнеры.Ссылка В ИЕРАРХИИ
        (ВЫБРАТЬ
            Иерархия.Родитель
        ИЗ
            РегистрСведений.ИерархияПартнеров КАК Иерархия
        ГДЕ
            Иерархия.Партнер = &ГоловнойПартнер
            И Иерархия.Уровень = 0)

Разберем этот первый запрос:

  1. Мы создаем временную таблицу ВТ_ВсеПартнеры, в которую помещаем ссылки на партнеров.
  2. В условии ГДЕ Партнеры.Ссылка В ИЕРАРХИИ (...) мы используем оператор В ИЕРАРХИИ.
  3. Вложенный запрос определяет, какой партнер является "корневым" для иерархии, которую мы хотим выбрать. Мы ищем в РегистрСведений.ИерархияПартнеров запись, где Партнер = &ГоловнойПартнер и Уровень = 0 (это означает сам головной партнер как корневой элемент). Поле Родитель в этом случае будет ссылаться на самого себя, т.е. на &ГоловнойПартнер.
  4. Таким образом, мы получаем всех потомков (включая самого головного) для заданного &ГоловнойПартнер.

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

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


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

Этот запрос покажет всех контрагентов, которые напрямую привязаны к каждому партнеру из выбранной иерархии. Однако, это не решает полностью исходную задачу, которая требует включения контрагентов родителей для дочерних партнеров. Для полной реализации исходной задачи все же лучше вернуться к первому запросу с прямым соединением ИерархияПартнеров.Родитель = Контрагенты.Партнер.

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

Флаг "Включая контрагентов-родителей"

В конфигурациях 1С, таких как 1С:ERP или 1С:Управление торговлей, существует функциональность, которая позволяет дочерним партнерам использовать контрагентов, привязанных к их головным (родительским) партнерам. Это реализуется через специальный флаг "Включая контрагентов-родителей".

Где находится флаг и для чего он нужен:

Этот флаг обычно расположен в карточке партнера, в разделе прикрепленных контрагентов (часто доступно по гиперссылке "Контрагенты"). Установка этого флага для дочернего партнера позволяет ему при оформлении документов (например, реализаций) выбирать в качестве контрагента любое юридическое или физическое лицо, которое привязано не только к самому дочернему партнеру, но и ко всем его родительским партнерам по иерархии. Это удобно, когда, например, филиалы или дочерние предприятия ведут деятельность от имени материнской компании, используя ее юридические реквизиты.

Программное создание и установка флага:

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

Подробности использования Регистра сведений "ИерархияПартнеров"

Регистр сведений ИерархияПартнеров – это ключевой элемент для работы с иерархиями в 1С без необходимости написания сложных рекурсивных запросов. Давайте рассмотрим его структуру подробнее:

  1. Измерения:
    • Партнер: Ссылка на элемент справочника "Партнеры", который является потомком.
    • Родитель: Ссылка на элемент справочника "Партнеры", который является предком (родителем) для данного Партнера. Важно, что для каждого партнера будет запись, где Партнер равен Родитель (т.е. сам партнер является своим собственным элементом в иерархии на уровне 0).
  2. Ресурсы:
    • Уровень: Числовое значение, указывающее на глубину вложенности. Уровень = 0 обычно означает, что Партнер равен Родителю (сам себе). Уровень = 1 означает непосредственного родителя, Уровень = 2 – родителя родителя и так далее.

Предположим, у нас есть следующая иерархия:

А -> Б -> В

Тогда в регистре ИерархияПартнеров мы увидим следующие записи (упрощенно):

  1. Партнер: А, Родитель: А, Уровень: 0
  2. Партнер: Б, Родитель: Б, Уровень: 0
  3. Партнер: Б, Родитель: А, Уровень: 1
  4. Партнер: В, Родитель: В, Уровень: 0
  5. Партнер: В, Родитель: Б, Уровень: 1
  6. Партнер: В, Родитель: А, Уровень: 2

Именно эта плоская структура позволяет нам легко выполнять запросы, подобные рассмотренному выше, соединяя ИерархияПартнеров.Родитель с Контрагенты.Партнер, чтобы получить контрагентов всех предков.

Разделение справочников "Партнеры" и "Контрагенты" и их иерархия

В современных конфигурациях 1С (таких как 1С:ERP, 1С:Управление торговлей, 1С:Комплексная автоматизация) реализована концепция раздельного ведения справочников "Партнеры" и "Контрагенты". Разберем, зачем это сделано и как это влияет на работу с данными.

  1. Справочник "Партнеры":
    • Предназначен для управленческого учета.
    • Может иметь иерархическую структуру (группы, элементы). Это позволяет объединять дочерние компании, филиалы, подразделения или даже отдельные магазины в единую структуру под материнской компанией или холдингом.
    • Иерархия партнеров дает возможность проводить анализ продаж, дебиторской и кредиторской задолженности, а также других управленческих показателей как в разрезе конкретного подразделения/магазина, так и для всей сети или холдинга в целом.
  2. Справочник "Контрагенты":
    • Предназначен для регламентированного учета (бухгалтерский, налоговый).
    • Содержит официальную юридическую и физическую информацию о лицах, с которыми компания ведет деятельность (ИНН, КПП, юридический адрес, банковские реквизиты и т.д.).
    • Как правило, не имеет иерархической структуры в том же понимании, что "Партнеры", хотя может быть сгруппирован по папкам для удобства.

Связь между "Партнерами" и "Контрагентами":

Связь между этими двумя справочниками очень гибкая:

  1. Один партнер может соответствовать одному или нескольким контрагентам (например, если у одной компании несколько юридических лиц).
  2. Несколько партнеров могут соответствовать одному контрагенту (например, если несколько филиалов или магазинов одной сети работают от имени одного юридического лица).

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

Производительность и альтернативы

При работе с иерархическими данными в 1С вопрос производительности всегда стоит остро, особенно на больших базах данных.

  1. Специализированные регистры сведений: Мы уже убедились, что использование таких регистров, как ИерархияПартнеров, является наиболее оптимальным решением для обеспечения высокой производительности. Они предварительно рассчитывают и хранят иерархию в плоском виде, что позволяет избежать сложных рекурсивных запросов и существенно ускоряет получение информации в отчетах СКД и других обработках.
  2. Рекурсивные запросы: Хотя язык запросов 1С поддерживает рекурсивные конструкции (через вложенные запросы или общие табличные выражения), их использование на больших объемах данных может привести к значительным задержкам. Поэтому, если есть возможность использовать предварительно рассчитанные данные из регистра, всегда отдавайте предпочтение этому способу.
  3. Альтернативы при отсутствии явной иерархии: Если в вашей конфигурации справочник "Контрагенты" не имеет явной иерархии (или вы не используете "Партнеров"), но вам все равно нужна группировка, можно рассмотреть следующие варианты:
    • Дополнительные реквизиты: Создайте дополнительные реквизиты в справочнике "Контрагенты", например, "ГоловнойКонтрагент", "БизнесРегион", "ОтветственныйМенеджер", и используйте их для создания пользовательских группировок в динамических списках и отчетах.
    • Группы (папки) справочника: Используйте стандартные группы справочника "Контрагенты" для организации данных, хотя это не обеспечивает "наследование" контрагентов родителей, как в случае с партнерами.

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

← На главную