Как правильно связать регистр остатков с регистром оборотов в запросе 1С?

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

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

Почему прямое соединение по регистратору приводит к ошибкам

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


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

Проанализируем ситуацию и выделим две фундаментальные проблемы такого подхода:

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

Способ 1. Использование Системы компоновки данных (СКД) с двумя наборами данных

Наиболее надежный и правильный способ в платформе 1С — настроить схему компоновки данных с разделением источников на два отдельных набора данных-запроса.

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

Способ 2. Объединение запросов («ОБЪЕДИНИТЬ ВСЕ»)

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

Разберем пример построения такого запроса:


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

СГРУППИРОВАТЬ ПО
    ТаблицаДанных.БанковскийСчетКасса,
    ТаблицаДанных.ВидДенежныхСредств,
    ТаблицаДанных.СтатьяДвиженияДенежныхСредств

Посмотрим на особенности этого решения:

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

Архитектурные рекомендации

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

← На главную