Как правильно составить запрос для получения оборотов по регистру накопления с условием ГДЕ?

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

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

Проанализируем исходный вариант кода, который был предложен в качестве решения:


Выбрать
    ТоварыОрганизаций.Номенклатура,
    ТоварыОрганизаций.Количество
ИЗ
    РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрганизации
ГДЕ
    ТоварыОрганизации.КоличествоПриход
И   ТоварыОрганизации.КоличествоРасход

Выясним причину, почему данный запрос является синтаксически и логически неверным:

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

Способ 1. Получение оборотов через физическую таблицу регистра

Рассмотрим вариант, когда по условиям задачи требуется обращаться напрямую к физической таблице движений регистра и обязательно использовать конструкцию ГДЕ. Этот подход часто дают в качестве теста на понимание внутреннего устройства регистров накопления с видом «Остатки».

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

Посмотрим на рабочий пример реализации:


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

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

  1. Проверка активности: Условие И ТоварыОрганизации.Активность отсекает сторнированные или неактивные записи, которые не должны влиять на итоги.
  2. Границы периода: Конструкция МЕЖДУ &ДатаНач И &ДатаКон включает обе граничные даты. При передаче параметров убедитесь, что дата окончания включает время конца дня (например, 23:59:59), иначе движения за последний день не попадут в результат.
  3. Ограничение по виду регистра: Данный метод применим только к регистрам с видом «Остатки». У оборотных регистров поле ВидДвижения отсутствует, так как в них накапливается только оборот.

Способ 2. Оптимальное решение с использованием виртуальной таблицы оборотов

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

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


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

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

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