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

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

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

Анализ структуры связей и типичных ошибок в запросах

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

  1. Завышение суммы: если в один документ доп. расходов включены позиции по разным приходным ордерам или накладным, сумма из шапки покажет общие затраты по всем документам сразу, а не только по текущему.
  2. Дублирование сумм при соединении: если документ-основание встречается в нескольких строках табличной части подчиненного документа, при левом соединении табличной части с шапкой сумма шапки будет задвоена или затроена.
  3. Учет непроведенных или удаленных документов: если не наложить условие на признак проведения, в расчет попадут черновые или помеченные на удаление документы.

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

Построение правильного запроса к табличной части

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

Посмотрим на пример запроса для получения итоговой суммы дополнительных расходов по конкретному документу-партии:


ВЫБРАТЬ
    ПоступлениеДопРасходовТовары.ДокументПартии КАК ДокументПартии,
    СУММА(ПоступлениеДопРасходовТовары.Сумма) КАК СуммаДопРасходов,
    СУММА(ПоступлениеДопРасходовТовары.СуммаНДС) КАК СуммаНДСДопРасходов
ИЗ
    Документ.ПоступлениеДопРасходов.Товары КАК ПоступлениеДопРасходовТовары
ГДЕ
    ПоступлениеДопРасходовТовары.ДокументПартии = &ДокументОснование
    И ПоступлениеДопРасходовТовары.Ссылка.Проведен = ИСТИНА
    И ПоступлениеДопРасходовТовары.Ссылка.ПометкаУдаления = ЛОЖЬ
СГРУППИРОВАТЬ ПО
    ПоступлениеДопРасходовТовары.ДокументПартии

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


ВЫБРАТЬ
    ПоступлениеДопРасходовТовары.Ссылка КАК ДокументДопРасходов,
    СУММА(ПоступлениеДопРасходовТовары.Сумма) КАК Сумма,
    СУММА(ПоступлениеДопРасходовТовары.СуммаНДС) КАК СуммаНДС
ИЗ
    Документ.ПоступлениеДопРасходов.Товары КАК ПоступлениеДопРасходовТовары
ГДЕ
    ПоступлениеДопРасходовТовары.ДокументПартии = &ДокументОснование
    И ПоступлениеДопРасходовТовары.Ссылка.Проведен = ИСТИНА
СГРУППИРОВАТЬ ПО
    ПоступлениеДопРасходовТовары.Ссылка

Способы отображения и оптимизация производительности

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

  1. Вывод только в форме документа: если сумма нужна исключительно как информационный показатель при просмотре или редактировании документа-основания, расчет запросом можно выполнять на сервере в событии ПриСозданииНаСервере или ПриЧтенииНаСервере. Это не создает критической нагрузки на систему.
  2. Вывод в динамическом списке (форме списка документов): добавление соединения с табличными частями в основной запрос динамического списка категорически не рекомендуется. Это приводит к сканированию больших объемов данных в СУБД, блокировкам таблиц и существенному замедлению открытия списка.
  3. Хранение в реквизите документа: если сумму необходимо быстро фильтровать или отображать в списке, правильным решением будет добавить в документ-основание отдельный реквизит СуммаДопРасходов. Заполнение и пересчет этого реквизита следует выполнять программно при проведении и отмене проведения подчиненного документа (ПоступлениеДопРасходов).

Альтернативные платформенные механизмы

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

  1. Использование критериев отбора: в типовых конфигурациях для получения подчиненных объектов используется критерий отбора СвязанныеДокументы или СтруктураПодчиненности. Метод КритерииОтбора.[ИмяКритерия].Найти(&Ссылка) задействует штатные индексы платформы и быстро возвращает список всех документов, ссылающихся на исходный через шапку или табличные части.
  2. Обращение к регистрам накопления: если в конфигурации включен партионный учет или учет затрат, дополнительные расходы при проведении формируют движения по регистрам (например, ПартииТоваровНаСкладах или СебестоимостьТоваров). Запрос к виртуальной таблице остатков или оборотов соответствующего регистра с отбором по регистратору или партии часто выполняется быстрее, чем прямое чтение табличных частей документов.
← На главную