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

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

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

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

В чем суть технической проблемы?

Представим стандартную задачу: нам необходимо построить ведомость по взаиморасчетам с контрагентами в разрезе договоров, документов расчетов и регистраторов. Нам нужно вывести ресурсы: Начальный остаток, Увеличение долга (Приход), Уменьшение долга (Расход) и Конечный остаток.

В базе данных присутствует множество контрагентов, по которым все расчеты давно закрыты в ноль. Мы хотим исключить их из отчета, чтобы не загромождать форму пустыми строками. На первый взгляд, решение очевидно — наложить отбор КонечныйОстаток <> 0. Однако здесь мы сталкиваемся с неприятным поведением СКД:

  1. Если наложить общий отбор на весь отчет: СКД применит условие на самом нижнем уровне выборки — то есть к каждой строке детальных записей (к каждому регистратору). Те документы-регистраторы, после проведения которых остаток стал равен нулю, просто исчезнут из выборки. Хронологическая цепочка расчетов разорвется. В результате СКД потеряет данные для расчета начальных и конечных остатков по родительским группировкам, и итоговые суммы станут некорректными либо вовсе обнулятся.
  2. Если наложить отбор только на родительские группировки: В отчет все равно будут выводиться пустые родительские строки (контрагенты и договоры), у которых внутри когда-то были обороты, но конечный итог равен нулю. Отчет окажется переполнен лишней информацией.

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

Решение 1. Разделение данных на два набора (Связи наборов данных)

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

Шаг 1. Создание Мастер-набора (НаборДанных1)

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

Пример запроса для НабораДанных1:


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

На этот набор данных мы можем смело наложить глобальный отбор в настройках СКД: КонечныйОстаток <> 0 (или более сложное условие, например: КонечныйОстаток <> 0 ИЛИ НачальныйОстаток <> 0 ИЛИ УвеличениеДолга <> 0). СКД корректно отфильтрует строки аналитики, так как здесь нет детальных записей.

Шаг 2. Создание Ведомого набора (НаборДанных2)

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

Пример запроса для НабораДанных2:


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

Шаг 3. Настройка связей наборов данных

Перейдем на вкладку «Связи наборов данных» в СКД и добавим связи по всем ключевым полям аналитики:

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

Решение 2. Использование ресурсов Минимум и Максимум (Один набор данных)

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

Если у контрагента все закрылось в ноль, то на любом уровне вложенности его документов максимальный и минимальный остатки будут равны нулю. Если же у него по одному договору висит долг 1000 рублей, а по другому переплата -1000 рублей (в сумме по контрагенту выходит 0), то максимальный остаток будет равен 1000, а минимальный — -1000. Это позволит нам не потерять записи с внутренними взаиморасчетами.

Разберем реализацию этого метода по шагам:

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

    Добавим условие: (МаксОстаток <> 0) ИЛИ (МинОстаток <> 0)

  5. Важный нюанс: В свойствах созданного элемента отбора для группировки установим свойство «Применение» в значение «После группировки». Это заставит СКД сначала вычислить агрегатные функции по группировке, а затем скрыть те ветки дерева, которые не удовлетворяют условию.

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

Важные технические нюансы работы с Регистратором в СКД

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

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

← На главную