Можно ли соединять таблицы через OData в 1С и как реализовать аналог SQL JOIN?

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

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

Давайте подробно разберемся в возможностях и ограничениях OData в контексте соединения данных и рассмотрим наиболее эффективные подходы для решения этой задачи.

Прямые аналоги SQL JOIN в OData

Начнем с главного: в OData нет прямого аналога оператора JOIN, как в SQL. Нельзя написать запрос, который бы произвольно соединил, например, регистр сведений и регистр накопления по общим измерениям, если между ними нет прямой ссылочной связи в метаданных.

Это связано с самой сутью протокола OData. Он предназначен для работы с сущностями (объектами метаданных, такими как справочники, документы, регистры) в рамках REST-архитектуры, а не для выполнения произвольных SQL-запросов к базе данных. Его цель — предоставить стандартизированный CRUD-интерфейс к объектам, а не служить полноценным сервером баз данных.

Механизм $expand — «соединение» для связанных данных

Наиболее близким к JOIN функционалом в OData является системный параметр $expand. Он позволяет «развернуть» или «расширить» связанные данные, подтянув их в один ответ с основным запросом. Фактически, это аналог LEFT JOIN.

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

Рассмотрим на примере. Допустим, у нас есть документ «РеализацияТоваровУслуг», в котором есть реквизит «Контрагент» (ссылка на справочник «Контрагенты»). Мы можем одним запросом получить и сам документ, и данные связанного с ним контрагента.

Пример запроса:

/odata/standard.odata/Document_РеализацияТоваровУслуг?$filter=Ref_Key eq guid'...'&$expand=Контрагент

В ответе мы получим поля документа реализации, а внутри будет вложенный объект с полями контрагента. Это очень удобно и позволяет избежать проблемы «N+1 запросов», когда на каждый объект из списка приходится делать отдельный запрос за связанными данными.

Ограничения $expand:

Реализация пагинации (постраничной загрузки)

При работе с большими объемами данных важно загружать их порциями. В OData для этого есть стандартные параметры:

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

/odata/standard.odata/Catalog_Номенклатура?$top=50&$skip=100

Этот запрос пропустит первые 100 записей (2 страницы по 50) и вернет следующие 50. Для быстрого формирования и отладки таких URL можно использовать генератор запросов OData для платформы 1С.

Что делать, если $expand не подходит? Альтернативные решения

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

Решение 1: Кастомный HTTP-сервис (рекомендуемый способ)

Это наиболее гибкий и правильный архитектурный подход для сложных интеграций. Вы создаете в конфигурации 1С собственный HTTP-сервис, который будет выполнять роль кастомного API. Для ускорения этой задачи можно использовать конструктор API для интеграции 1С в формате JSON.

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

  1. Создание HTTP-сервиса. В дереве конфигурации добавьте новый HTTP-сервис, укажите корневой URL и создайте шаблон URL с методом для вашего запроса (например, /products/list с методом GET).
  2. Написание кода в модуле. В модуле сервиса, в процедуре, обрабатывающей ваш метод, вы пишете код на встроенном языке 1С.
  3. Формирование запроса. С помощью объекта Запрос вы можете составить абсолютно любой по сложности запрос:
    • Соединять несколько таблиц (справочники, регистры) с помощью ЛЕВОЕ СОЕДИНЕНИЕ, ВНУТРЕННЕЕ СОЕДИНЕНИЕ.
    • Использовать виртуальные таблицы регистров (Остатки, Обороты, СрезПоследних).
    • Применять группировки, агрегатные функции (СУММА, КОЛИЧЕСТВО) и вложенные запросы.
  4. Обработка результата и возврат. Результат запроса вы обрабатываете и преобразуете в удобный для клиента формат, чаще всего JSON. Затем формируете объект HTTPОтвет, помещаете в его тело строку JSON и отправляете клиенту.

Преимущества этого подхода:

Решение 2: Соединение данных на стороне клиента

Этот подход заключается в том, чтобы сделать несколько последовательных OData-запросов и «склеить» данные уже на стороне принимающей системы (например, на сайте).

Например, для получения списка товаров с ценами и остатками, клиенту придется:

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

Недостатки этого подхода:

Этот метод может быть оправдан только для очень простых случаев с небольшим объемом данных.

Резюме

Подведем итоги. Стандартный интерфейс OData в 1С — мощный инструмент, но его сфера применения ограничена.

← На главную