Как в 1С:УТ 11.4 программно узнать количество заказов по номенклатуре за разные периоды и вывести остатки

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

В типовых конфигурациях, таких как Управление торговлей 11.4, часто возникает задача анализа оборачиваемости или спроса на товары. Одной из классических задач является создание отчета, который показывает не только текущие остатки, но и активность покупателей за определенные промежутки времени: например, сколько раз товар заказывали за последние 30, 60 и 90 дней. Разберем подробно, как реализовать такой функционал правильно, используя современные инструменты 1С.

Выбор архитектурного решения: почему СКД лучше кода

Начинающие программисты часто пытаются решить задачу "в лоб": создать массив или таблицу значений, в цикле обходить номенклатуру и для каждой позиции выполнять запрос. Как справедливо отмечено в обсуждении, за такие планы "отправляли на галеры". И вот почему: выполнение запроса в цикле — это критическая ошибка производительности. При наличии в справочнике 10 000 позиций программа выполнит 10 000 отдельных обращений к базе данных, что приведет к зависанию системы.

Правильный путь — использование Системы компоновки данных (СКД). Мы напишем один комплексный запрос, который за один проход соберет все необходимые данные. СКД сама позаботится о выводе, группировках по иерархии номенклатуры и оформлении отчета.

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

Для реализации задачи в УТ 11.4 нам понадобятся два основных источника данных:

  1. Регистр накопления ТоварыНаСкладах — из него мы возьмем остатки. Используем виртуальную таблицу Остатки.
  2. Регистр накопления ЗаказыКлиентов — из него мы получим данные о количестве заказов. Нам понадобится виртуальная таблица Обороты.

Важный нюанс: если мы просто выберем данные из регистра заказов, то в отчет попадут только те товары, которые заказывали. Чтобы увидеть "мертвые" позиции (у которых есть остаток, но нет заказов), основным источником в запросе должен выступать справочник Номенклатура.

Реализация логики периодов (30, 60, 90 дней)

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

Рассмотрим пример запроса, который собирает статистику заказов:


ВЫБРАТЬ
    ЗаказыОбороты.Номенклатура КАК Номенклатура,
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВЫБОР
            КОГДА ЗаказыОбороты.Период >= &ДатаНачала30
                ТОГДА ЗаказыОбороты.Регистратор
            ИНАЧЕ NULL
        КОНЕЦ) КАК ЗаказовЗа30Дней,
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВЫБОР
            КОГДА ЗаказыОбороты.Период >= &ДатаНачала60
                ТОГДА ЗаказыОбороты.Регистратор
            ИНАЧЕ NULL
        КОНЕЦ) КАК ЗаказовЗа60Дней,
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ЗаказыОбороты.Регистратор) КАК ЗаказовЗа90Дней
ИЗ
    РегистрНакопления.ЗаказыКлиентов.Обороты(&ДатаНачала90, &КонецПериода, День, ) КАК ЗаказыОбороты
СГРУППИРОВАТЬ ПО
    ЗаказыОбороты.Номенклатура

В данном фрагменте мы используем функцию КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ...). Это критически важно, так как одна позиция номенклатуры может присутствовать в нескольких строках одного заказа или по ней могут быть корректировки. Нам же нужно посчитать именно число уникальных сделок.

Сборка полного запроса с остатками

Теперь объединим справочник номенклатуры, текущие остатки и нашу статистику заказов с помощью левого соединения. Это позволит нам не потерять ни одну позицию товара. Проанализируем итоговую структуру запроса:


ВЫБРАТЬ
    СпрНоменклатура.Ссылка КАК Номенклатура,
    СпрНоменклатура.Артикул КАК Артикул,
    ЕСТЬNULL(ТоварыОстатки.ВНаличииОстаток, 0) КАК ОстатокНаСегодня,
    ЕСТЬNULL(СтатистикаЗаказов.ЗаказовЗа30Дней, 0) КАК Заказов30,
    ЕСТЬNULL(СтатистикаЗаказов.ЗаказовЗа60Дней, 0) КАК Заказов60,
    ЕСТЬNULL(СтатистикаЗаказов.ЗаказовЗа90Дней, 0) КАК Заказов90
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&ПериодОстатков, ) КАК ТоварыОстатки
        ПО СпрНоменклатура.Ссылка = ТоварыОстатки.Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ (
            ВЫБРАТЬ
                Заказы.Номенклатура КАК Номенклатура,
                КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВЫБОР
                        КОГДА Заказы.Период >= &Дата30
                            ТОГДА Заказы.Регистратор
                    КОНЕЦ) КАК ЗаказовЗа30Дней,
                КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВЫБОР
                        КОГДА Заказы.Период >= &Дата60
                            ТОГДА Заказы.Регистратор
                    КОНЕЦ) КАК ЗаказовЗа60Дней,
                КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Заказы.Регистратор) КАК ЗаказовЗа90Дней
            ИЗ
                РегистрНакопления.ЗаказыКлиентов.Обороты(&Дата90, &ТекущаяДата, День, ) КАК Заказы
            СГРУППИРОВАТЬ ПО
                Заказы.Номенклатура
        ) КАК СтатистикаЗаказов
        ПО СпрНоменклатура.Ссылка = СтатистикаЗаказов.Номенклатура
ГДЕ
    НЕ СпрНоменклатура.ЭтоГруппа

Разберем важные моменты этого запроса:

Тонкости учета в УТ 11.4: статусы и отмены

При работе с регистром ЗаказыКлиентов в УТ 11.4 нужно учитывать специфику бизнес-процессов. Заказ может быть создан, но позже отменен. В регистре накопления отмена строки заказа обычно отражается сторнирующим движением. Если мы просто считаем обороты, мы можем учесть отмененные заказы.

Чтобы отчет был максимально точным, рекомендуется добавить в виртуальную таблицу оборотов условие на статус заказа или анализировать только те заказы, которые перешли в статус "К выполнению" или "Закрыт". Также стоит обращать внимание на реквизит Отменено в строках заказа, если вы решите делать запрос к физической таблице (чего лучше избегать ради производительности).

Настройка параметров в СКД

Для того чтобы запрос заработал, необходимо правильно настроить параметры в схеме компоновки данных. На вкладке "Параметры" мы создаем:

  1. &Дата90, &Дата60, &Дата30 — даты начала соответствующих периодов.
  2. &ПериодОстатков — текущий момент времени.

Чтобы пользователю не приходилось вводить эти даты вручную, в выражениях параметров СКД можно прописать функции языка запросов. Например, для &Дата90 выражение будет: ДобавитьКДате(ТекущаяДата(), "День", -90). Это автоматизирует отчет, и он всегда будет показывать актуальную статистику относительно "сегодня".

Заключение

Мы проанализировали задачу создания аналитического отчета в УТ 11.4. Использование СКД в сочетании с механизмом виртуальных таблиц оборотов и грамотным применением левых соединений позволяет создать быстрый и надежный инструмент для бизнеса. Такой подход не только экономит ресурсы сервера, но и предоставляет гибкие возможности для дальнейшей настройки отчета пользователем: добавления отборов по складам, артикулам или характеристикам товаров без изменения программного кода.

← На главную