Как составить запрос для поиска цен, изменившихся более чем на заданный процент?

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

Разберем задачу поиска номенклатуры, цена на которую изменилась на определенный процент за заданный период. Это классическая аналитическая задача в 1С, для решения которой нам потребуется грамотно использовать механизмы виртуальных таблиц и конструкцию ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ. Давайте пройдем этот путь шаг за шагом.

Основные принципы анализа цен

Для начала уясним, что цены в 1С обычно хранятся в РегистрСведений. Чтобы получить актуальную цену на конкретную дату, мы будем использовать виртуальную таблицу СрезПоследних. Она позволяет сэкономить ресурсы системы, так как сама делает выборку последних значений на заданный момент времени.

Поскольку нам нужно сравнить цены между двумя датами (начальной и конечной), нам потребуется два «среза» данных. Простым вычитанием здесь не обойтись — нужно сформировать полноценную таблицу соответствий.

Алгоритм решения через временные таблицы

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

  1. Создание выборки на начальную дату: Получаем срез цен на &ДатаНачала и помещаем результат во временную таблицу, например, ЦеныНаНачало.
  2. Создание выборки на конечную дату: Получаем срез цен на &ДатаКонца и помещаем результат во временную таблицу ЦеныНаКонец.
  3. Соединение данных: Объединяем две временные таблицы с помощью ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ по полю Номенклатура. Это важно, так как товар мог появиться в ассортименте или исчезнуть из него в рассматриваемый период.
  4. Расчет изменения: Вычисляем процент разницы, используя функцию ЕСТЬNULL, чтобы избежать ошибок при отсутствии данных на одну из дат.

Пример реализации запроса

Посмотрим, как это выглядит в коде 1С. Мы используем параметры виртуальной таблицы для отбора, так как это значительно эффективнее, чем фильтрация через ГДЕ.


ВЫБРАТЬ
    ЦеныНаНачало.Номенклатура КАК Номенклатура,
    ЕСТЬNULL(ЦеныНаНачало.Цена, 0) КАК ЦенаНачальная,
    ЕСТЬNULL(ЦеныНаКонец.Цена, 0) КАК ЦенаКонечная
ПОМЕСТИТЬ ВТ_СравнениеЦен
ИЗ
    РегистрСведений.Цены.СрезПоследних(&ДатаНачала, ) КАК ЦеныНаНачало
        ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ РегистрСведений.Цены.СрезПоследних(&ДатаКонца, ) КАК ЦеныНаКонец
        ПО ЦеныНаНачало.Номенклатура = ЦеныНаКонец.Номенклатура
;

ВЫБРАТЬ
    ВТ.Номенклатура,
    ВТ.ЦенаНачальная,
    ВТ.ЦенаКонечная,
    (ВТ.ЦенаКонечная - ВТ.ЦенаНачальная) / ВЫБОР КОГДА ВТ.ЦенаНачальная = 0 ТОГДА 1 ИНАЧЕ ВТ.ЦенаНачальная КОНЕЦ * 100 КАК ПроцентИзменения
ИЗ
    ВТ_СравнениеЦен КАК ВТ
ГДЕ
    (ВТ.ЦенаКонечная - ВТ.ЦенаНачальная) / ВЫБОР КОГДА ВТ.ЦенаНачальная = 0 ТОГДА 1 ИНАЧЕ ВТ.ЦенаНачальная КОНЕЦ * 100 > &ПроцентОтбора

Важные замечания

Обратите внимание на конструкцию ВЫБОР КОГДА при расчете процента. Мы обязаны защитить систему от деления на ноль, если ЦенаНачальная равна нулю (например, товар не продавался ранее или был бесплатно заведен в базу). Использование ЕСТЬNULL гарантирует, что даже если товар отсутствовал на какую-то из дат, мы не получим «пустое» значение NULL, которое ломает математические операции.

Полезные советы:

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

← На главную