Как в СКД получить данные из регистра цен с отбором по видам цен и найти товары без цен?

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

При разработке отчетов в системе компоновки данных (СКД) программисты часто сталкиваются с необходимостью выборки данных из регистра сведений ЦеныНоменклатуры. Типичные сложности возникают при попытке настроить сложные отборы по видам цен или при поиске товаров, для которых цена вовсе не установлена. В этой статье мы подробно разберем, как правильно составить запрос, оптимизировать его работу и решить проблему "пустых" цен.

Настройка базового запроса к срезу последних цен

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

Для начала изучим структуру простого запроса к виртуальной таблице СрезПоследних:


ВЫБРАТЬ
    ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура,
    ЦеныНоменклатурыСрезПоследних.ВидЦены КАК ВидЦены,
    ЦеныНоменклатурыСрезПоследних.Цена КАК Цена,
    ЦеныНоменклатурыСрезПоследних.ВидЦены.БазовыйВидЦены КАК ВидЦеныБазовыйВидЦены
ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних

Часто новички пытаются наложить отбор в секции ГДЕ. Однако такой подход является неоптимальным. Разберем, почему это происходит: при использовании секции ГДЕ система сначала получает все последние записи из регистра для всех товаров и всех видов цен, и только потом "отсеивает" ненужное. Это существенно замедляет работу отчета на больших базах данных.

Оптимизация: использование параметров виртуальной таблицы

Правильный способ наложения отбора в СКД — использование параметров виртуальной таблицы. Посмотрим, как перенести условие непосредственно в параметры СрезПоследних. Это позволит платформе 1С выбрать из базы данных только те записи, которые соответствуют нашему условию, еще на этапе формирования выборки.

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


ВЫБРАТЬ
    ЦенНоменклатуры.Номенклатура,
    ЦенНоменклатуры.ВидЦены,
    ЦенНоменклатуры.Цена
ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ВидЦены В (&ВидыЦен)) КАК ЦенНоменклатуры

Если же нам необходимо сделать отбор по наименованию (хотя использование ссылок всегда предпочтительнее), запрос примет следующий вид:


ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ВидЦены.Наименование В ("Нормативная", "Базовая")) КАК ЦенНоменклатуры

Важный нюанс: если в вашей конфигурации (например, УТ 11 или ERP) вид цены является динамическим (рассчитывается по формуле), то в регистре сведений записей по нему просто не будет. Запрос к СрезПоследних вернет результат только для хранимых цен. Если "Нормативная" цена пуста, проверьте способ ее формирования в справочнике ВидыЦен.

Решение ошибки «Глобальные элементы отбора обязательно должны использовать поля...»

При работе в СКД вы можете столкнуться с ошибкой, когда система требует использовать ПараметрыДанных в отборах. Выясним причину: это происходит, когда вы объявили параметр в тексте запроса (например, &ВидыЦен), но в настройках СКД на закладке "Настройки" пытаетесь добавить отбор через стандартный механизм отборов, а не через параметры.

Чтобы исправить это, выполним следующие шаги:

  1. Перейдем на закладку Параметры в схеме компоновки данных.
  2. Убедимся, что параметр ВидыЦен имеет правильный тип (например, СправочникСсылка.ВидыЦен) и у него снята галочка "Ограничение доступности", если пользователь должен его заполнять.
  3. Если используется оператор В, убедимся, что параметр помечен как Доступен список значений.

Как найти товары, на которые не установлены цены

Проанализируем сложную задачу: вывод списка номенклатуры, у которой цена отсутствует. Если мы будем делать запрос только к регистру ЦеныНоменклатуры, мы никогда не увидим такие товары. В регистре хранятся только факты установки цен. Если цены нет — нет и записи в таблице.

Для решения этой задачи нам необходимо использовать Левое соединение. Рассмотрим алгоритм построения запроса:

  1. Основной таблицей выберем справочник Номенклатура (нам нужны все товары).
  2. К справочнику присоединим виртуальную таблицу СрезПоследних регистра цен.
  3. В условии связи укажем соответствие по Номенклатуре и ВидуЦены.

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


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

В данном примере условие Цены.Цена ЕСТЬ NULL как раз и отфильтрует те товары, по которым не было найдено записей в регистре цен. Если же цена установлена равной нулю физически, можно добавить условие ИЛИ Цены.Цена = 0.

Реализация через управляемый параметр (Булево)

Представим ситуацию, когда руководителю нужно в одном отчете видеть либо все цены, либо только пустые, переключая "галочку". Мы можем реализовать это с помощью хитрого условия в секции ГДЕ, используя параметр типа Булево.

Разберем пример реализации:


ГДЕ
    ВЫБОР 
        КОГДА &ТолькоПустыеЦены = ИСТИНА 
            ТОГДА Цены.Цена ЕСТЬ NULL 
        ИНАЧЕ ИСТИНА 
    КОНЕЦ

В этом случае, если пользователь установит флаг &ТолькоПустыеЦены в значение Истина, сработает фильтр по отсутствующим значениям. Если флаг снят — условие ИНАЧЕ ИСТИНА пропустит все строки без дополнительной фильтрации.

Вычисляемые поля для наглядности

Чтобы отчет выглядел профессионально, мы можем использовать вкладку Вычисляемые поля в СКД. Если цена не установлена, вместо пустого поля можно вывести текст "Цена не задана".

Для этого добавим новое поле с выражением:

ВЫБОР КОГДА Цена = 0 ИЛИ Цена ЕСТЬ NULL ТОГДА "Цена не установлена" ИНАЧЕ Цена КОНЕЦ

Подведем итог: при работе с ценами в СКД критически важно понимать разницу между отсутствием записи в регистре и нулевой ценой. Всегда используйте левое соединение от справочника Номенклатура, если ваша цель — инвентаризация полноты заполнения прайс-листа, и старайтесь выносить отборы в параметры виртуальных таблиц для обеспечения высокой скорости работы ваших отчетов.

← На главную