Как выполнить отбор по родителю в запросе OData к 1С?

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

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

Анализ структуры метаданных через OData

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

Для начала рассмотрим, как получить описание структуры нашего объекта. Для этого воспользуемся запросом к метаданным сервиса. Добавим к базовому адресу публикации суффикс $metadata:

http://[адрес_сервера]/[база]/odata/standard.odata/$metadata

Проанализируем полученный XML-файл. Нам нужно найти раздел EntityType, соответствующий нашему объекту (например, ChartOfCharacteristicTypes_ВидыДокументов). Внутри этого раздела мы увидим список свойств (Property). Именно там скрывается ответ на вопрос, как называется поле родителя. В большинстве случаев для иерархических справочников и ПВХ это будет Parent_Key.

Разбор типичной ошибки: Регистрозависимость

Выясним причину, по которой стандартные запросы могут возвращать ошибку сегмента пути. Одной из ключевых особенностей протокола OData в реализации 1С является строгая зависимость от регистра символов.

Рассмотрим пример неудачного запроса:

.../ChartOfCharacteristicTypes_ВидыДокументов?$filter=parent_key eq guid'...'

Даже если поле называется именно так, использование нижнего регистра (parent_key вместо Parent_Key) приведет к тому, что система не распознает этот сегмент пути. В 1С стандартные поля идентификаторов и ссылок всегда пишутся в формате PascalCase.

Важно: Поле owner (владелец) в 1С относится к подчиненным справочникам, а для иерархии (группы и элементы внутри одного объекта) всегда используется «Родитель», что в терминах OData превращается в Parent_Key.

Правильный синтаксис фильтрации по родителю

Теперь сформируем корректный запрос, учитывая все требования платформы. Для того чтобы отобрать все элементы, входящие в определенную группу Плана видов характеристик, нам нужно использовать параметр $filter с оператором eq (equal) и указать уникальный идентификатор родительской группы в формате guid'...'.

Рассмотрим правильный пример запроса:


http://server/base/odata/standard.odata/ChartOfCharacteristicTypes_ВидыДокументов?$filter=Parent_Key eq guid'80d50050-56a6-e0b8-11e6-bf69f8d9b9d1'

В данном примере мы четко указываем:

  1. Имя сущности: ChartOfCharacteristicTypes_ВидыДокументов.
  2. Параметр фильтрации: $filter.
  3. Имя поля: Parent_Key (с большой буквы P и K).
  4. Тип значения: guid, за которым в одинарных кавычках следует сам UUID группы.

Как проверить доступные поля в ответе системы

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


<d:Ref_Key>f9d9b9dd-bf69-11e6-80d5-005056a6e0b8</d:Ref_Key>
<d:DataVersion>AAAAAAsVGWQ=</d:DataVersion>
<d:DeletionMark>false</d:DeletionMark>
<d:Parent_Key>f9d9b9dc-bf69-11e6-80d5-005056a6e0b8</d:Parent_Key>
<d:IsFolder>false</d:IsFolder>
<d:Description>Дополнительное соглашение</d:Description>

В этом XML-пакете мы видим тег <d:Parent_Key>. Это прямое указание на то, что в строке запроса $filter мы должны использовать именно Parent_Key. Если бы мы работали с подчиненным справочником, мы бы увидели там Owner_Key.

Особенности фильтрации элементов верхнего уровня

Иногда возникает задача получить только те элементы, которые находятся в корне справочника или ПВХ, то есть не имеют родителя. В обычном запросе 1С мы бы написали ГДЕ Родитель = ЗНАЧЕНИЕ(Справочник.ИмяСправочника.ПустаяСсылка).

В протоколе OData для этих целей используется сравнение с null. Проанализируем, как это выглядит на практике:

.../ChartOfCharacteristicTypes_ВидыДокументов?$filter=Parent_Key eq null

Этот запрос вернет все группы и элементы, расположенные на самом верхнем уровне иерархии.

Ограничения стандартного интерфейса: Отбор «В иерархии»

Важно понимать одно существенное ограничение: стандартный интерфейс OData в 1С (версия протокола 3.0) не поддерживает аналог команды «В ИЕРАРХИИ».

Если мы выполняем фильтр по Parent_Key, мы получим только прямых потомков указанной группы. Если внутри этой группы есть подгруппы, элементы которых вам тоже нужны, стандартный OData-запрос не сможет их выгрузить за один раз.

Для решения этой задачи у нас есть два пути:

  1. Рекурсивный обход: программно запрашивать список подгрупп, а затем для каждой выполнять отдельный запрос OData.
  2. Использование внешних источников данных: если данных много, лучше написать специализированную HTTP-службу (HTTP-сервис) внутри 1С, которая будет принимать GUID родителя и возвращать дерево данных, используя стандартный язык запросов 1С с оператором В ИЕРАРХИИ.

Итоговые рекомендации

Для успешного выполнения отбора по родителю придерживайтесь следующих правил:

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

← На главную