При работе с протоколом OData в системе 1С:Предприятие разработчики часто сталкиваются с трудностями при попытке ограничить выборку из регистров накопления по временному интервалу. Основная проблема заключается в том, что стандартный механизм OData предоставляет доступ к разным типам таблиц для одного и того же объекта метаданных, и правила работы с ними существенно различаются. Разберем подробно, почему возникают ошибки типа «Сегмент пути не найден» и как получить данные с сохранением даты операции.
Для начала проанализируем архитектуру доступа к данным через standard.odata. Когда мы обращаемся к регистру накопления (например, AccumulationRegister_Продажи), платформа 1С может предоставить нам два принципиально разных набора данных:
Period._Turnovers. Она возвращает уже агрегированные (сгруппированные) данные. По умолчанию в этой таблице нет поля Period, так как она суммирует показатели за весь запрошенный интервал.Рассмотрим подробнее каждый вариант работы, чтобы понять, какой из них лучше подходит для ваших задач.
Если ваша цель — получить детальные записи регистра с сохранением даты каждой конкретной продажи, необходимо обращаться к основной таблице. Выясним причину типичной ошибки: использование параметров StartPeriod и EndPeriod внутри функции $filter для основной таблицы недопустимо, так как этих полей в структуре физической таблицы просто не существует.
Для фильтрации физической таблицы мы должны использовать стандартный синтаксис OData и системное поле Period. Рассмотрим пример правильного запроса:
/standard.odata/AccumulationRegister_Продажи?$filter=Period ge datetime'2023-01-01T00:00:00' and Period le datetime'2023-01-31T23:59:59'
В данном примере мы используем операторы ge (greater or equal — больше или равно) и le (less or equal — меньше или равно). Обратите внимание на формат даты: datetime'ГГГГ-ММ-ДДTHH:mm:ss'. Именно такой формат является стандартным для 1С при работе по протоколу OData версии 3 и 4. Для автоматического формирования корректных URL с нужными условиями фильтрации можно использовать генератор запросов OData.
Преимущества этого метода:
Period (дата движения) присутствует в каждой строке ответа.Recorder_Key.Если же нам нужны не детальные записи, а итоги (например, общая сумма продаж по контрагентам), мы используем таблицу _Turnovers. Здесь синтаксис меняется. Параметры периода передаются не через $filter, а в круглых скобках непосредственно после имени таблицы.
Посмотрим на пример запроса для получения оборотов:
/standard.odata/AccumulationRegister_Продажи_Turnovers(StartPeriod=datetime'2023-01-01T00:00:00', EndPeriod=datetime'2023-01-31T23:59:59')
Важно понимать: как только мы вызываем _Turnovers, платформа выполняет группировку. Если в параметрах виртуальной таблицы не указана периодичность (что в стандартном OData 1С ограничено), то в результате вы получите одну строку на каждую уникальную комбинацию измерений. Поля Period в этом наборе данных действительно не будет, так как данные «схлопнуты» за весь месяц.
Часто возникает ситуация: нужны именно обороты (чтобы не тянуть миллионы строк движений), но с разбивкой по дням. К сожалению, стандартный интерфейс OData в 1С не поддерживает параметр Periodicity (периодичность) в виртуальных таблицах так, как это делает язык запросов 1С (где можно указать «День», «Месяц» и т.д.).
Рассмотрим способы обхода этого ограничения:
AccumulationRegister_Продажи (как описано в первом способе) и выполняем агрегацию данных в Power BI, Excel или вашем приложении. Это самый надежный способ сохранить точность до секунды.ДатаДень (тип Дата). Тогда при обращении к _Turnovers это поле будет доступно как обычное измерение, и 1С автоматически сгруппирует данные по нему, фактически вернув вам обороты в разрезе дней.Проанализируем ситуацию, описанную в сообщениях форума. Пользователь пытался выполнить запрос:
.../AccumulationRegister_Продажи?$filter=StartPeriod ge datetime'2020-09-01T00:00:00'
Платформа закономерно ответила: «Сегмент пути StartPeriod не найден». Это произошло потому, что StartPeriod — это имя параметра функции для виртуальной таблицы, а не имя поля в базе данных. В основной таблице поле называется Period.
Также стоит помнить о версии OData. Если вы используете OData v4, убедитесь, что в настройках публикации информационной базы на веб-сервере разрешен доступ к нужным объектам. Иногда ошибка 400 (Bad Request) может быть вызвана отсутствием прав доступа у пользователя, под которым выполняется подключение, или тем, что регистр не включен в состав «Состава публикуемых объектов». Для интерактивной проверки и отладки веб-запросов к опубликованной базе подойдёт обработка для тестирования REST API на платформе 1С.
При получении данных из AccumulationRegister_Продажи рекомендуется всегда ограничивать набор получаемых полей с помощью параметра $select. Это существенно снизит нагрузку на сервер и ускорит передачу данных по сети.
Пример оптимизированного запроса:
/standard.odata/AccumulationRegister_Продажи?$filter=Period ge datetime'2023-09-01T00:00:00'&$select=Period, Summa, Customer_Key, Goods_Key
Подведем итог: если вам нужна дата каждой операции — используйте основную таблицу и фильтр по полю Period. Если нужны итоги за период без детализации по дням — используйте таблицу _Turnovers с параметрами в скобках. Помните, что StartPeriod и Period — это разные сущности, используемые в разных контекстах запроса.