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

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

При формировании отчетов в 1С часто возникает задача — получить данные по проводкам или движениям, в которых не указано структурное подразделение. В стандартных отчетах такие записи могут отображаться с пометкой "Головное подразделение", но при создании собственного отчета в Системе Компоновки Данных (СКД) необходимо правильно составить запрос, чтобы отобрать именно такие "пустые" значения.

Разберем по шагам, как это сделать, и какие ошибки часто допускают разработчики.

Типичная ошибка: проверка на "Неопределено"

Первое, что может прийти в голову — это проверить, равно ли поле СтруктурноеПодразделение значению НЕОПРЕДЕЛЕНО. Однако такой подход не сработает.

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


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

Почему это неправильно? В таблицах базы данных, в частности в регистрах, реквизит ссылочного типа (как, например, ссылка на справочник "Подразделения организаций"), который не заполнен, хранит не значение Неопределено, а пустую ссылку соответствующего типа. Значение Неопределено используется в языке 1С для других целей, например, для неинициализированных переменных или для реквизитов составного типа, когда тип не выбран.

Правильный способ: отбор по пустой ссылке

Чтобы корректно отобрать записи с незаполненным подразделением, нужно сравнивать поле с пустой ссылкой на справочник подразделений. Для этого в языке запросов 1С используется функция ЗНАЧЕНИЕ().

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


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

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

Для наглядности в отчете можно подменить пустое значение на понятный текст с помощью конструкции ВЫБОР:


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

Сложный сценарий: как совместить данные по выбранным и пустым подразделениям?

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

В чем проблема? Если вы добавите в настройках отчета СКД на вкладке "Отбор" условие по полю "СтруктурноеПодразделение", этот отбор будет применен ко всему результату запроса. То есть, если пользователь выберет "Цех №1", то все записи, где подразделение пустое, будут отфильтрованы и не попадут в отчет, даже если ваш запрос их получил.

Решение — использовать несколько наборов данных в СКД.

Разберем по шагам:

  1. Создаем первый набор данных для выбранных подразделений.

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

    
    // Набор данных 1: ДанныеПоВыбраннымПодразделениям
    ВЫБРАТЬ
        ХозрасчетныйОбороты.ПериодМесяц,
        ХозрасчетныйОбороты.Организация,
        ХозрасчетныйОбороты.СтруктурноеПодразделение,
        ХозрасчетныйОбороты.СуммаОборотДт
    ПОМЕСТИТЬ ВТ_ВыбранныеПодразделения
    ИЗ
        РегистрБухгалтерии.Типовой.Обороты(
            ,
            ,
            Авто,
            Счет В ИЕРАРХИИ (&МассивСчетов),
            ,
            СтруктурноеПодразделение В (&Подразделения) // Используем параметр
            ,
            ,
        ) КАК ХозрасчетныйОбороты;
    

    Здесь &Подразделения — это параметр отчета, который пользователь заполнит в форме.

  2. Создаем второй набор данных для пустого подразделения.

    Этот запрос жестко отбирает данные только по пустой ссылке и не зависит от пользовательских отборов.

    
    // Набор данных 2: ДанныеПоПустомуПодразделению
    ВЫБРАТЬ
        ХозрасчетныйОбороты.ПериодМесяц,
        ХозрасчетныйОбороты.Организация,
        СУММА(ХозрасчетныйОбороты.СуммаОборотДт) КАК СуммаПустых
    ПОМЕСТИТЬ ВТ_ПустыеПодразделения
    ИЗ
        РегистрБухгалтерии.Типовой.Обороты(
            ,
            ,
            Авто,
            Счет В ИЕРАРХИИ (&МассивСчетов),
            ,
            СтруктурноеПодразделение = ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка) // Жесткое условие
            ,
            ,
        ) КАК ХозрасчетныйОбороты
    СГРУППИРОВАТЬ ПО
        ХозрасчетныйОбороты.ПериодМесяц,
        ХозрасчетныйОбороты.Организация;
    
  3. Объединяем результаты в третьем наборе данных.

    Теперь создаем третий, основной набор данных, который будет выводиться в отчет. В нем мы соединяем две временные таблицы.

    
    // Набор данных 3: Итог
    ВЫБРАТЬ
        Выбранные.ПериодМесяц,
        Выбранные.Организация,
        Выбранные.СтруктурноеПодразделение,
        Выбранные.СуммаОборотДт КАК СуммаВыбранных,
        ЕСТЬNULL(Пустые.СуммаПустых, 0) КАК СуммаПустых
    ИЗ
        ВТ_ВыбранныеПодразделения КАК Выбранные
            ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ПустыеПодразделения КАК Пустые
            ПО Выбранные.ПериодМесяц = Пустые.ПериодМесяц
            И Выбранные.Организация = Пустые.Организация
    
  4. Настраиваем связи и вычисляемые поля.

    В конструкторе СКД на вкладке "Связи наборов данных" убедитесь, что наборы правильно связаны (например, по полям ПериодМесяц и Организация). Затем на вкладке "Вычисляемые поля" вы можете создать новое поле, например, "Отношение", с формулой для расчета нужного показателя:

    ВЫБОР КОГДА СуммаВыбранных > 0 ТОГДА СуммаПустых / СуммаВыбранных ИНАЧЕ 0 КОНЕЦ

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

Замечание про "кеширование" в СКД

Иногда, после многочисленных изменений запроса и настроек, СКД может вести себя непредсказуемо, как будто "помнит" старые параметры. Если вы уверены в правильности запроса, но результат некорректен, попробуйте простое действие: создайте схему компоновки данных с нуля в новом, чистом отчете. Часто это помогает избавиться от "закешированных" настроек и получить ожидаемый результат.

← На главную