Как получить список заказов клиентов без отгрузок в 1С:ERP и оптимизировать запрос к регистрам

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

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

Проблема прямого обращения к физическим таблицам регистров

Рассмотрим ситуацию, когда нам нужно получить заказы без реализаций. Обращение напрямую к таблице РегистрНакопления.ЗаказыКлиентов заставляет систему сканировать все записи (движения) в базе данных. Если в компании тысячи заказов и миллионы строк движений, такой отчет будет «вешать» систему. Кроме того, условие ГДЕ ЗаказыКлиентов.ЗаказКлиента.Дата МЕЖДУ... крайне непроизводительно.

Проанализируем причину: поле ЗаказКлиента в ERP является составным. Оно может содержать ссылки на «Заказ клиента», «Заказ давальца», «Заявку на возврат» и другие документы. Когда мы обращаемся через точку к дате (ЗаказКлиента.Дата), СУБД делает неявное левое соединение со всеми возможными таблицами этих документов. Чтобы этого избежать, всегда следует использовать типизацию или обращаться к индексированным полям самого регистра.

Решение 1: Использование виртуальной таблицы ОстаткиИОбороты

Наиболее корректный способ получить информацию о том, была ли отгрузка по заказу — обратиться к виртуальной таблице ОстаткиИОбороты. В этой таблице данные уже предварительно агрегированы (просуммированы), что значительно ускоряет выборку. Мы можем определить факт отгрузки по наличию значения в поле ЗаказаноРасход.

Разберем алгоритм решения задачи с помощью временных таблиц:

  1. Сначала выберем все заказы, по которым в принципе были отгрузки (расход по регистру), и поместим их во временную таблицу.
  2. Затем выберем основные данные заказов, исключив те, что попали в первый список.

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


// 1. Собираем заказы, по которым была отгрузка (Расход > 0)
ВЫБРАТЬ РАЗЛИЧНЫЕ
    ЗаказыОбороты.ЗаказКлиента КАК ЗаказКлиента
ПОМЕСТИТЬ ВТ_ЗаказыСОтгрузками
ИЗ
    РегистрНакопления.ЗаказыКлиентов.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ЗаказыОбороты
ГДЕ
    ЗаказыОбороты.ЗаказаноРасход > 0;

////////////////////////////////////////////////////////////////////////////////
// 2. Основной запрос: выбираем заказы без отгрузок
ВЫБРАТЬ
    Заказы.ЗаказКлиента КАК Ссылка,
    Заказы.ЗаказКлиента.Дата КАК Дата,
    Заказы.ЗаказаноОстаток КАК ТекущийОстаток
ИЗ
    РегистрНакопления.ЗаказыКлиентов.Остатки(&ДатаОстатков, ) КАК Заказы
ГДЕ
    НЕ Заказы.ЗаказКлиента В (ВЫБРАТЬ ВТ.ЗаказКлиента ИЗ ВТ_ЗаказыСОтгрузками КАК ВТ)
    И Заказы.ЗаказКлиента ССЫЛКА Документ.ЗаказКлиента

Решение 2: Использование регистра Состояния заказов клиентов

В конфигурации 1С:ERP существует специализированный регистр сведений СостоянияЗаказовКлиентов. Этот регистр предназначен специально для быстрого получения текущего статуса обеспечения и отгрузки. В нем уже рассчитаны такие показатели, как «Сумма оплаты» и «Сумма отгрузки».

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

Однако стоит помнить, что этот регистр является расчетным. Данные в нем обновляются фоновым заданием. Если в системе не включено немедленное обновление состояний, отчет может показывать данные с задержкой в несколько минут.

Оптимизация работы с составными типами (ВЫРАЗИТЬ и ССЫЛКА)

Для ускорения работы любого запроса в ERP, где фигурирует измерение ЗаказКлиента, мы должны явно указывать тип ссылки. Выясним, как это сделать правильно:

Использование оператора ВЫРАЗИТЬ позволяет СУБД обращаться только к одной конкретной таблице документа вместо десятка возможных. Посмотрим на пример правильного обращения к реквизитам заказа:


ВЫБРАТЬ
    ВЫРАЗИТЬ(Заказы.ЗаказКлиента КАК Документ.ЗаказКлиента).Дата КАК ДатаЗаказа,
    ВЫРАЗИТЬ(Заказы.ЗаказКлиента КАК Документ.ЗаказКлиента).Менеджер КАК Менеджер
ИЗ
    РегистрНакопления.ЗаказыКлиентов.Остатки КАК Заказы
ГДЕ
    Заказы.ЗаказКлиента ССЫЛКА Документ.ЗаказКлиента

Важный момент: Условие ССЫЛКА Документ.ЗаказКлиента в блоке ГДЕ позволяет отсечь лишние типы данных еще на этапе формирования плана запроса, что крайне положительно сказывается на производительности.

Учет ордерной схемы склада

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

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

Выводы и рекомендации

Для построения качественного отчета по заказам в 1С:ERP придерживайтесь следующих правил:

  1. Избегайте физических таблиц: Всегда используйте виртуальные таблицы Остатки, Обороты или ОстаткиИОбороты.
  2. Фильтруйте по периоду в параметрах: Устанавливайте границы периода в параметрах виртуальной таблицы (в скобках), а не в блоке ГДЕ.
  3. Типизируйте составные поля: Используйте ВЫРАЗИТЬ при обращении к полям через точку от ЗаказКлиента или Регистратор.
  4. Используйте СКД: Если отчет сложный и требует объединения данных по заказам и реализациям, используйте несколько наборов данных в Системе компоновки данных, связывая их по заказу. Это позволит системе более гибко оптимизировать итоговый SQL-запрос.

Соблюдение этих принципов позволит вашему отчету работать быстро даже на крупных базах данных с большим объемом товарооборота.

← На главную