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

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

При разработке отчетов по движению денежных средств в конфигурациях уровня 1С:Управление торговлей 11, ERP или Комплексная автоматизация программисты часто сталкиваются с проблемой «пустых полей». Суть ситуации заключается в том, что в одних документах (например, поступление на счет) СтатьяДДС находится непосредственно в шапке, а в других (например, списание безналичных ДС) она вынесена в табличную часть РасшифровкаПлатежа. Это сделано для того, чтобы один платеж можно было разбить по нескольким статьям или разным договорам.

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

Причина проблемы: разница в хранении данных

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

Рассмотрим по шагам основные способы решения этой задачи.

Способ 1. Левое соединение с табличной частью документа

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

Проанализируем пример запроса, в котором мы соединяем данные регистра с расшифровкой платежа документа СписаниеБезналичныхДенежныхСредств:


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

Важные моменты этого подхода:

  1. Фильтр по номеру строки: Условие ТЧ_Расшифровка.НомерСтроки = 1 критически важно. Если его не указать, и в документе будет 5 строк расшифровки, сумма оборота по этому документу в вашем отчете увеличится в 5 раз (произойдет «размножение» строк из-за особенностей работы JOIN в SQL).
  2. Типы документов: Поскольку документов-регистраторов может быть много (Поступление, Списание, Лимиты и т.д.), вам придется делать левое соединение с каждой табличной частью каждого возможного типа документа. Это сильно усложняет запрос.

Способ 2. Использование измерений регистра (Оптимальный)

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

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


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

В этом случае, если в одном документе было две разные статьи ДДС, виртуальная таблица ОстаткиИОбороты при детализации до регистратора выдаст вам две строки. Это наиболее корректный вариант для финансового отчета, так как суммы будут распределены по статьям правильно.

Способ 3. Универсальный регистр «Движения Денежных Средств»

В УТ 11 и ERP существует специализированный оборотный регистр РегистрНакопления.ДвиженияДенежныхСредств. Он предназначен специально для управленческой отчетности по статьям. Проанализируем его преимущества:

Если ваша задача — построить отчет по оборотам (Приход/Расход) в разрезе статей, лучше всего использовать именно его.

Разберем нюансы работы с типами пустых значений

При написании условий ВЫБОР КОГДА... начинающие разработчики часто путают NULL, Неопределено и ПустаяСсылка. Посмотрим на различия:

Правильная проверка на заполненность статьи в запросе должна выглядеть так:

СтатьяДДС <> ЗНАЧЕНИЕ(Справочник.СтатьиДвиженияДенежныхСредств.ПустаяСсылка)

Итоги и рекомендации

Подведем итоги нашего анализа. Для того чтобы статьи ДДС отображались корректно:

  1. Первым делом проверьте, нет ли статьи в измерениях самого регистра, к которому вы обращаетесь. В 90% случаев в УТ 11/ERP она там есть.
  2. Если вы строите сложный отчет, рассмотрите возможность использования регистра ДвиженияДенежныхСредств вместо прямых регистров остатков.
  3. Если же вам абсолютно необходимо соединение с табличной частью (например, для получения специфических реквизитов из строки), всегда используйте фильтр по НомерСтроки или группировку, чтобы избежать дублирования денежных сумм.

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

← На главную