Как изменить значение даты по условию и подменить поле в запросе 1С?

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

При составлении запросов в 1С разработчики часто сталкиваются с задачей модификации значений полей «на лету» — например, когда для определенных строк или складов требуется скорректировать дату документа или движения, округлив ее до начала недели или месяца. При этом нередко возникают ошибки, связанные с попыткой использовать оператор присваивания внутри запроса или неверным построением условий в секциях ВЫБРАТЬ и ГДЕ. Разберем по шагам типичные ошибки и составим правильный запрос.

Анализ типичных ошибок при работе с условиями в запросах

Рассмотрим, с какими сложностями сталкиваются разработчики при попытке подменить поле даты:

  1. Попытка присваивания через знак равенства: В языке запросов 1С отсутствует оператор присваивания =. Знак равенства всегда интерпретируется СУБД как операция сравнения. Конструкция вида ТОГДА ТоварыНаСкладах.Период = НАЧАЛОПЕРИОДА(...) вернет логическое значение (ИСТИНА или ЛОЖЬ), а не вычисленную дату.
  2. Несовместимость типов данных в выражении: Внутри одной конструкции ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ все возвращаемые ветками значения должны иметь совместимые типы данных. Если в одной ветке возвращается значение типа Булево, а в другой — Дата, запрос либо вернет поле составного типа, либо завершится ошибкой.
  3. Избыточное использование ВЫБОР в секции ГДЕ: Написание конструкции ГДЕ ВЫБОР КОГДА ... ТОГДА ИСТИНА КОНЕЦ является неоптимальным и ухудшает план выполнения запроса. Для условий отбора следует применять стандартные логические связки И, ИЛИ, НЕ.

Шаг 1. Формирование условного выражения даты в секции ВЫБРАТЬ

Проанализируем, как правильно вычислить новую дату для определенных строк. Чтобы функция вернула саму дату, необходимо указать вычисляемое выражение в секции ТОГДА без знака равенства, а также обязательно предусмотреть ветку ИНАЧЕ, чтобы для остальных строк сохранилось исходное значение:


ВЫБОР
    КОГДА ТоварыНаСкладах.Склад = &Склад2
        ТОГДА НАЧАЛОПЕРИОДА(ТоварыНаСкладах.Период, НЕДЕЛЯ)
    ИНАЧЕ ТоварыНаСкладах.Период
КОНЕЦ КАК Период

Обратите внимание: чтобы не выводить отдельную колонку, мы исключаем исходное поле ТоварыНаСкладах.Период из списка выборки и присваиваем псевдоним Период самому условному выражению с помощью ключевого слова КАК.

Шаг 2. Оптимизация условия фильтрации в секции ГДЕ

Теперь разберем фильтрацию строк. Вместо громоздких условных конструкций используем логические операторы И и ИЛИ с явным выделением скобками приоритета условий:


ГДЕ
    (ТоварыНаСкладах.Склад = &Склад И ТоварыНаСкладах.Количество > 15)
    ИЛИ (ТоварыНаСкладах.Склад = &Склад2)

Итоговый текст запроса

Соберем все элементы вместе и посмотрим на готовый рабочий запрос:


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

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

  1. Проверка активности записей: При прямом обращении к таблице движений регистра накопления (например, РегистрНакопления.ТоварыНаСкладах) запрос считывает все записи, включая сторнированные и неактивные. Всегда добавляйте условие ТоварыНаСкладах.Активность = ИСТИНА, если требуются только действующие движения.
  2. Использование виртуальных таблиц: Если целью запроса является получение агрегированных итогов по периодам (неделям, месяцам), эффективнее обращаться к виртуальной таблице ТоварыНаСкладах.Обороты или ТоварыНаСкладах.ОстаткиИОбороты, передавая в параметры периодичность (например, Периодичность = Неделя). Это позволяет СУБД использовать предварительно рассчитанные итоги регистра и существенно ускоряет выборку.
  3. Настройки в СКД: Если запрос разрабатывается для отчета на Системе компоновки данных, расчет начала периода или агрегацию дат зачастую удобнее выносить в настройки вычисляемых полей или выражений представления СКД, оставляя запрос простым и производительным.
← На главную