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

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

При разработке отчетов на встроенном языке 1С мы часто сталкиваемся с ситуацией, когда данные «пропадают» из выборки. Если вы пишете запрос, объединяющий несколько источников, и обнаруживаете, что строки с нулевыми показателями попросту отсутствуют в результате, значит, вы столкнулись с особенностью работы внутреннего соединения.

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

Анализ проблемы: невидимые нули

В первом варианте запроса автора использовалась конструкция вида ИЗ Источник1, Источник2, Источник3. В языке запросов 1С перечисление таблиц через запятую автоматически интерпретируется как ВНУТРЕННЕЕ СОЕДИНЕНИЕ (INNER JOIN). Логика работы такой конструкции такова: система оставляет в итоговой таблице только те записи, которые имеют соответствие во всех перечисленных источниках.

Если в одной из таблиц (например, с количеством WhatsApp) для конкретного сотрудника данных нет, то результат соединения по этой строке будет равен нулю или отсутствовать. В результате движок запроса отсекает всю строку целиком, даже если по СМС или Звонкам данные у сотрудника были.

Решение: переход к левым соединениям

Чтобы вывести сотрудника в отчете, даже если у него нет активности по некоторым типам, нам необходимо использовать ЛЕВОЕ СОЕДИНЕНИЕ (LEFT JOIN). При использовании этого метода система сохраняет все записи из основной (левой) таблицы, а для отсутствующих данных в присоединенных таблицах подставляет значение NULL.

Чтобы вместо NULL отображался «0», мы используем функцию ЕСТЬNULL().

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

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

Рассмотрим пошаговое построение корректного запроса:

  1. Подготовка данных: Помещаем активность сотрудника во временные таблицы, сгруппированные по типу активности.
  2. Основная выборка: Используем в качестве базы список сотрудников (или константу, если отчет по одному человеку).
  3. Левое соединение: Присоединяем временные таблицы к основному списку.

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


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

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

ВЫБРАТЬ
    &Сотрудник КАК Автор,
    ЕСТЬNULL(ТабСМС.Количество, 0) КАК КоличествоСМС,
    ЕСТЬNULL(ТабЗв.Количество, 0) КАК КоличествоЗвонков,
    ЕСТЬNULL(ТабАпп.Количество, 0) КАК КоличествоWhatsApp,
    ЕСТЬNULL(ТабПочта.Количество, 0) КАК КоличествоEmail
ИЗ
    (ВЫБРАТЬ &Сотрудник КАК Автор) КАК Пром
    ЛЕВОЕ СОЕДИНЕНИЕ поТипу КАК ТабСМС ПО ТабСМС.ТипАктивности = ЗНАЧЕНИЕ(Справочник.ТипыАктивности.СМС)
    ЛЕВОЕ СОЕДИНЕНИЕ поТипу КАК ТабЗв ПО ТабЗв.ТипАктивности = ЗНАЧЕНИЕ(Справочник.ТипыАктивности.Звонок)
    ЛЕВОЕ СОЕДИНЕНИЕ поРеквизиту КАК ТабАпп ПО ТабАпп.Реквизит = "WhatsApp"
    ЛЕВОЕ СОЕДИНЕНИЕ поРеквизиту КАК ТабПочта ПО ТабПочта.Реквизит = "E-mail"

Как вывести данные по всем сотрудникам?

Если перед нами стоит задача вывести отчет сразу по всей компании, нам нужно изменить источник данных для формирования строки Автор. Вместо передачи параметра &Сотрудник мы используем справочник Сотрудники как ведущую таблицу.

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

Совет: Всегда анализируйте план запроса при работе с большими объемами данных. Использование временных таблиц — это стандарт индустрии при разработке профессиональных отчетов в 1С, так как это минимизирует количество чтений с диска и предотвращает потерю данных при соединении.

← На главную