При выполнении учебных или практических задач в консоли запросов часто возникает необходимость получить таблицу оборотов по регистру накопления за определенный период и с отбором по конкретной организации. Разберем типичные ошибки начинающих разработчиков и выясним, как правильно составить такой запрос двумя способами: через физическую таблицу движений (если этого строго требуют условия задачи) и через виртуальную таблицу оборотов платформы 1С.
Проанализируем исходный вариант кода, который был предложен в качестве решения:
Выбрать
ТоварыОрганизаций.Номенклатура,
ТоварыОрганизаций.Количество
ИЗ
РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрганизации
ГДЕ
ТоварыОрганизации.КоличествоПриход
И ТоварыОрганизации.КоличествоРасход
Выясним причину, почему данный запрос является синтаксически и логически неверным:
ГДЕ используются поля КоличествоПриход и КоличествоРасход как булевы выражения (через логическое И). В физической таблице регистра накопления таких полей просто не существует: там есть ресурс Количество и системный реквизит ВидДвижения.Приход и Расход автоматически генерируются только виртуальными таблицами регистра (Обороты или ОстаткиИОбороты).СГРУППИРОВАТЬ ПО и агрегатные функции СУММА(), без которых получить итоговые обороты невозможно.Рассмотрим вариант, когда по условиям задачи требуется обращаться напрямую к физической таблице движений регистра и обязательно использовать конструкцию ГДЕ. Этот подход часто дают в качестве теста на понимание внутреннего устройства регистров накопления с видом «Остатки».
В физической таблице каждая запись имеет направление движения, определяемое системным перечислением ВидДвиженияНакопления (значения Приход и Расход). Чтобы разделить одно поле ресурса на два отдельных столбца оборотов, используем конструкцию ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ вместе с агрегатной функцией СУММА.
Посмотрим на рабочий пример реализации:
ВЫБРАТЬ
ТоварыОрганизации.Номенклатура КАК Номенклатура,
СУММА(ВЫБОР
КОГДА ТоварыОрганизации.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
ТОГДА ТоварыОрганизации.Количество
ИНАЧЕ 0
КОНЕЦ) КАК КоличествоПриход,
СУММА(ВЫБОР
КОГДА ТоварыОрганизации.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Расход)
ТОГДА ТоварыОрганизации.Количество
ИНАЧЕ 0
КОНЕЦ) КАК КоличествоРасход
ИЗ
РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрганизации
ГДЕ
ТоварыОрганизации.Период МЕЖДУ &ДатаНач И &ДатаКон
И ТоварыОрганизации.Организация = &Организация
И ТоварыОрганизации.Активность
СГРУППИРОВАТЬ ПО
ТоварыОрганизации.Номенклатура
Разберем подробнее важные детали этого запроса:
И ТоварыОрганизации.Активность отсекает сторнированные или неактивные записи, которые не должны влиять на итоги.МЕЖДУ &ДатаНач И &ДатаКон включает обе граничные даты. При передаче параметров убедитесь, что дата окончания включает время конца дня (например, 23:59:59), иначе движения за последний день не попадут в результат.ВидДвижения отсутствует, так как в них накапливается только оборот.В реальной разработке чтение физической таблицы для получения итогов считается грубой ошибкой производительности. Платформа 1С хранит рассчитанные итоги в отдельных служебных таблицах СУБД. Обращаясь к виртуальной таблице Обороты, мы получаем готовые данные с максимальной скоростью.
Рассмотрим, как правильно построить запрос с использованием виртуальной таблицы:
ВЫБРАТЬ
ТоварыОрганизацийОбороты.Номенклатура КАК Номенклатура,
ТоварыОрганизацийОбороты.КоличествоПриход КАК КоличествоПриход,
ТоварыОрганизацийОбороты.КоличествоРасход КАК КоличествоРасход,
ТоварыОрганизацийОбороты.КоличествоОборот КАК КоличествоОборот
ИЗ
РегистрНакопления.ТоварыОрганизаций.Обороты(
&ДатаНач,
&ДатаКон,
,
Организация = &Организация) КАК ТоварыОрганизацийОбороты
Проанализируем преимущества и правила работы с виртуальной таблицей:
ГДЕ. Если перенести отбор по организации в секцию ГДЕ, СУБД сначала прочитает и рассчитает обороты по всем организациям базы данных, и лишь затем отфильтрует результат, что приведет к катастрофическому падению производительности на больших объемах данных.КоличествоПриход, КоличествоРасход и общий КоличествоОборот без необходимости вручную писать ветвления ВЫБОР КОГДА и группировки.ГДЕ в связке с виртуальной таблицей оборотов применяется только для наложения условий на вычисленные ресурсы (например, ГДЕ ТоварыОрганизацийОбороты.КоличествоОборот > 0), так как в круглых скобках параметров таблицы обращаться к ресурсам запрещено.