При разработке отчетов в 1С программисты часто сталкиваются с задачей: необходимо вывести данные из табличной части документа (например, количество, площадь, спецификации) и дополнить их суммами из проводок (регистра бухгалтерии). Однако стандартный подход через соединение по Номенклатуре часто приводит к ошибкам, особенно если одна и та же позиция встречается в документе несколько раз. Рассмотрим, почему это происходит и как правильно решить эту проблему.
Разберем ситуацию на примере. Допустим, у нас есть документ «Акт об использовании удобрений», в табличной части которого указано две строки с одной и той же номенклатурой «Суперфосфат» (например, для разных полей или разных партий). В проводках при этом также сформировались две записи по дебету счета затрат.
Когда мы пытаемся соединить таблицу документа с таблицей оборотов регистра по полям Регистратор и Номенклатура, система выполняет так называемое картезианское произведение. Каждая строка из документа находит соответствие в каждой строке из проводок. В итоге вместо двух строк мы получаем четыре, а итоговая сумма по документу может удвоиться или даже утроиться. Если же мы используем функцию МАКСИМУМ или СУММА с группировкой только по документу, мы теряем детализацию по строкам или получаем неверные итоги.
Как справедливо замечено в обсуждении, наиболее надежный способ получить корректные суммы — это строить отчет, где основной таблицей является Регистр Бухгалтерии, а не табличная часть документа. Проводка — это первичный источник данных о стоимости. Если в проводке не хватает каких-то данных (например, «Площади поля»), то их нужно либо добавлять в регистр как дополнительные субконто/реквизиты, либо подтягивать из документа по тем полям, которые гарантированно уникальны.
Проанализируем пример запроса, который выбирает данные напрямую из оборотов, используя документ только как фильтр:
ВЫБРАТЬ
ХозрасчетныйОбороты.Регистратор КАК Документ,
ХозрасчетныйОбороты.Субконто1 КАК Номенклатура,
ХозрасчетныйОбороты.СуммаНУОборотДт КАК СуммаНУ,
ХозрасчетныйОбороты.КоличествоОборотДт КАК Количество
ИЗ
РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, Регистратор, , , , , ) КАК ХозрасчетныйОбороты
ГДЕ
ТИПЗНАЧЕНИЯ(ХозрасчетныйОбороты.Регистратор) = ТИП(Документ.схАктОбИспользованииУдобрений)
В этом случае мы получаем ровно те суммы, которые зафиксированы в учете, без риска их дублирования из-за особенностей заполнения табличной части.
Если специфика отчета требует обязательного использования данных из табличной части, но при этом строки с одинаковой номенклатурой можно объединить, мы применим сгруппированную таблицу. Перед соединением с регистром бухгалтерии таблицу документа необходимо свернуть по номенклатуре.
Рассмотрим, как это выглядит в коде запроса:
ВЫБРАТЬ
ТЧ_Документа.Ссылка КАК Документ,
ТЧ_Документа.Номенклатура КАК Номенклатура,
СУММА(ТЧ_Документа.Количество) КАК КоличествоДок
ПОМЕСТИТЬ ВТ_СгруппированныеМатериалы
ИЗ
Документ.схАктОбИспользованииУдобрений.Материалы КАК ТЧ_Документа
ГДЕ
ТЧ_Документа.Ссылка.Проведен
СГРУППИРОВАТЬ ПО
ТЧ_Документа.Ссылка,
ТЧ_Документа.Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ.Документ,
ВТ.Номенклатура,
ВТ.КоличествоДок,
ЕСТЬNULL(Обороты.СуммаНУОборотДт, 0) КАК СуммаНУ
ИЗ
ВТ_СгруппированныеМатериалы КАК ВТ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(&Начало, &Конец, Авто, , , , , ) КАК Обороты
ПО ВТ.Документ = Обороты.Регистратор
И ВТ.Номенклатура = Обороты.СубконтоКт1
Этот метод исключает появление лишних строк, так как в обеих частях соединения номенклатура внутри одного документа встречается только один раз.
Если отчет должен показывать строки именно в том виде, в котором они внесены в документ (например, с разными комментариями или привязкой к разным объектам), а ключа связи между ТЧ и проводками нет, остается метод пропорционального распределения.
Алгоритм действий следующий:
(Сумма из проводки / Общее количество в ТЧ) * Количество в строке.Важный нюанс: при таком подходе могут возникнуть копейки из-за округления. В профессиональных решениях разница (остаток) обычно списывается на последнюю строку набора данных.
В современных конфигурациях 1С (ERP, Комплексная автоматизация 2, УТ 11) эта проблема решена на уровне платформы. В табличных частях документов и в регистрах присутствует реквизит КлючСвязи.
Проанализируем преимущества этого метода:
Номенклатура.Если вы работаете в кастомизированной системе и часто сталкиваетесь с такой задачей, рекомендуется внедрить КлючСвязи в структуру метаданных документа и регистра бухгалтерии.
Выяснив причину задвоения данных, мы можем сделать вывод: попытка прямого соединения Документ.ТабличнаяЧасть и РегистрБухгалтерии без дополнительных условий — это заведомо ошибочный путь для систем, где возможны повторы номенклатуры.
Для решения задачи мы рекомендуем:
КлючаСвязи в вашей конфигурации.