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

Программист 1С v8.3 (Обычные формы) Налоговый учет Промышленность, строительство и АПК
← На главную

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

Проблема: Почему суммы в отчете «размножаются»?

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

Когда мы пытаемся соединить таблицу документа с таблицей оборотов регистра по полям Регистратор и Номенклатура, система выполняет так называемое картезианское произведение. Каждая строка из документа находит соответствие в каждой строке из проводок. В итоге вместо двух строк мы получаем четыре, а итоговая сумма по документу может удвоиться или даже утроиться. Если же мы используем функцию МАКСИМУМ или СУММА с группировкой только по документу, мы теряем детализацию по строкам или получаем неверные итоги.

Вариант 1: Изменение архитектуры запроса (Идем от регистра)

Как справедливо замечено в обсуждении, наиболее надежный способ получить корректные суммы — это строить отчет, где основной таблицей является Регистр Бухгалтерии, а не табличная часть документа. Проводка — это первичный источник данных о стоимости. Если в проводке не хватает каких-то данных (например, «Площади поля»), то их нужно либо добавлять в регистр как дополнительные субконто/реквизиты, либо подтягивать из документа по тем полям, которые гарантированно уникальны.

Проанализируем пример запроса, который выбирает данные напрямую из оборотов, используя документ только как фильтр:


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

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

Вариант 2: Предварительная агрегация табличной части

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

Рассмотрим, как это выглядит в коде запроса:


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

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

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

Вариант 3: Метод математического распределения

Если отчет должен показывать строки именно в том виде, в котором они внесены в документ (например, с разными комментариями или привязкой к разным объектам), а ключа связи между ТЧ и проводками нет, остается метод пропорционального распределения.

Алгоритм действий следующий:

  1. Вычисляем общую сумму по номенклатуре в проводках для конкретного документа.
  2. Вычисляем общее количество этой номенклатуры в табличной части документа.
  3. Для каждой строки документа рассчитываем сумму по формуле: (Сумма из проводки / Общее количество в ТЧ) * Количество в строке.

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

Вариант 4: Использование ключа связи (КлючСтроки)

В современных конфигурациях 1С (ERP, Комплексная автоматизация 2, УТ 11) эта проблема решена на уровне платформы. В табличных частях документов и в регистрах присутствует реквизит КлючСвязи.

Проанализируем преимущества этого метода:

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

Резюме

Выяснив причину задвоения данных, мы можем сделать вывод: попытка прямого соединения Документ.ТабличнаяЧасть и РегистрБухгалтерии без дополнительных условий — это заведомо ошибочный путь для систем, где возможны повторы номенклатуры.

Для решения задачи мы рекомендуем:

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