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

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

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

Анализ проблемы и поиск причины

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


ВЫБРАТЬ
    РасходыНаНоменклатуру.Номенклатура КАК Номенклатура,
    РасходыНаНоменклатуру.Аналитика КАК Операция,
    СУММА(РасходыНаНоменклатуру.СуммаОборот) КАК Сумма,
    СУММА(РасходыНаНоменклатуру.КоличествоОборот) КАК Количество,
    СУММА(РасходыНаНоменклатуру.КоличествоАналитикаОборот) КАК КоличествоОпераций
ПОМЕСТИТЬ ТаблицаОперации
ИЗ
    РегистрНакопления.РасходыНаНоменклатуру.Обороты(ДОБАВИТЬКДАТЕ(&НачалоПериода, МЕСЯЦ, -3), &КонецПериода, Авто, ) КАК РасходыНаНоменклатуру
ГДЕ
    РасходыНаНоменклатуру.Аналитика ССЫЛКА Справочник.Номенклатура
СГРУППИРОВАТЬ ПО
    РасходыНаНоменклатуру.Номенклатура,
    РасходыНаНоменклатуру.Аналитика

При выполнении этого запроса в консоли выражение ДОБАВИТЬКДАТЕ(&НачалоПериода, МЕСЯЦ, -3) успешно вычисляется СУБД, и временная таблица заполняется данными за 3 предыдущих месяца.

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

Решение: правильная передача расчетных параметров в СКД

Для исправления этой проблемы выделим вычисление даты из текста запроса и перенесем его в настройки схемы компоновки данных.

  1. Выясним, какие параметры требуются, и заменим выражение в тексте запроса на отдельный параметр, например &НачалоПериодаЗатрат:
    
    РегистрНакопления.РасходыНаНоменклатуру.Обороты(&НачалоПериодаЗатрат, &КонецПериода, Авто, ) КАК РасходыНаНоменклатуру
    
  2. Перейдем на вкладку Параметры в схеме компоновки данных.
  3. Найдем параметр НачалоПериодаЗатрат и в колонке Выражение укажем формулу вычисления: ДобавитьКДате(&НачалоПериода, "Месяц", -3)
  4. Включим флаг Ограничение доступности для параметра НачалоПериодаЗатрат, чтобы пользователь не видел его в настройках отчета и не мог переопределить вручную.

Дополнительные рекомендации по защите от потери данных

Помимо корректной работы с параметрами виртуальных таблиц, проанализируем еще несколько факторов, из-за которых СКД может терять строки при работе с временными таблицами:

1. Защита от деления на ноль и значений NULL
Если во временной таблице рассчитываются удельные показатели путем деления, обязательно используем конструкции проверки на равенство нулю или ЕСТЬNULL. В противном случае результатом деления станет NULL, что при последующих соединениях приведет к выпадению позиций номенклатуры:


ВЫБОР 
    КОГДА ЕСТЬNULL(ТаблицаОперации.Количество, 0) = 0 
        ТОГДА 0 
    ИНАЧЕ ТаблицаОперации.КоличествоОпераций / ТаблицаОперации.Количество 
КОНЕЦ

2. Использование связей наборов данных
Если запрос в СКД становится слишком громоздким из-за множества временных таблиц и соединений, эффективнее разделить его на два независимых набора данных (например, НаборДанных_Продажи и НаборДанных_Затраты) и настроить их связывание на вкладке Связи наборов данных. В этом случае СКД автоматически организует левое соединение и применит пользовательские отборы без искажения исходной выборки.

← На главную