Как объединить и суммировать данные из табличных частей нескольких документов в одном отчете 1С?

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

При работе в системе 1С:Предприятие 8 часто возникает задача по формированию отчетов, которые должны консолидировать информацию не по одному, а сразу по нескольким источникам данных, например, по нескольким документам или складам. Представьте ситуацию: у вас есть стандартный отчет, который формируется по одному проведенному документу. Вы хотите получить сводный результат, сложив данные из двух или более различных документов при выводе. Например, мы формируем отчет по первому складу и видим, что «Наушники» в количестве 2 шт. Затем мы выбираем другой документ, относящийся ко второму складу, и видим те же «Наушники», но уже в количестве 3 шт. Цель состоит в том, чтобы на форме отчета можно было выбрать оба документа, а система сформировала бы один отчет, где «Наушники» будут отображаться в количестве 5 шт. (2+3). При этом, если какого-то товара нет на одном из складов или в одном из документов, он должен быть учтен только из существующих источников, без возникновения ошибок или искажений.

Давайте подробно рассмотрим, как можно решить эту задачу, используя стандартные механизмы 1С:Предприятие, такие как Система Компоновки Данных (СКД) и язык запросов.

Основные подходы к решению задачи

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

  1. Использование Системы Компоновки Данных (СКД) с типом набора данных "Объединение". Это наиболее гибкий и рекомендуемый подход для большинства отчетов в 1С.
  2. Использование оператора ОБЪЕДИНИТЬ ВСЕ в запросе 1С. Прямой подход, если отчет строится на основе жестко заданного запроса.
  3. Использование временных таблиц. Более сложный, но мощный подход для сценариев, требующих промежуточной обработки данных.

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

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

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

  1. Создание нескольких наборов данных

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

    • Набор данных 1: Запрос к табличной части первого документа.
    • Набор данных 2: Запрос к табличной части второго документа.

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

  2. Набор данных типа "Объединение"

    После создания индивидуальных наборов данных, которые извлекают информацию из разных источников, мы создаем специальный набор данных типа "Объединение". Этот тип набора данных позволяет нам объединить результаты нескольких других наборов данных. В СКД это эквивалентно использованию оператора ОБЪЕДИНИТЬ ВСЕ в языке запросов.

    Мы просто добавляем наши предварительно созданные наборы данных (например, "ЗапросКДокументу1" и "ЗапросКДокументу2") в этот набор данных типа "Объединение".

  3. Согласование полей

    Для корректного объединения данных крайне важно, чтобы объединяемые наборы данных имели однотипные поля с одинаковыми наименованиями (или псевдонимами) для тех колонок, которые должны быть сведены вместе. Например, если в одном запросе поле называется Товар, а в другом Продукция, СКД будет рассматривать их как разные поля. Их необходимо привести к единому наименованию, например, Номенклатура.

    Пример полей, которые обычно согласуют:

    • Номенклатура (тип СправочникСсылка.Номенклатура)
    • Количество (тип Число)
    • Сумма (тип Число, если требуется суммирование по сумме)
  4. Группировка и ресурсы

    После того как данные из различных документов были объединены, мы переходим к настройкам отчета в СКД. Здесь мы задаем группировку по Номенклатуре. Затем, для поля Количество, мы устанавливаем тип агрегатной функции "Сумма". СКД автоматически просуммирует значения количества для каждой номенклатурной позиции, собранные из всех объединенных наборов данных. Для ознакомления с примером настройки ресурсов и группировок можно использовать пример создания внешнего табличного отчета с использованием ресурсов в СКД.

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

  5. Выбор нескольких документов на форме отчета

    Чтобы пользователь мог выбирать несколько документов (или складов) на форме отчета, необходимо правильно настроить параметры отчета в СКД. Создайте параметр, который будет принимать список значений (ссылок на документы, элементы справочника "Склады" и т.д.). В запросе или в отборах СКД для этого параметра следует использовать условие "В списке" (например, Документ.Ссылка В (&СписокДокументов)). Для удобной привязки элементов управления к отборам отчета подойдёт методика стыковки элементов управляемой формы и пользовательских настроек СКД.

2. Использование оператора ОБЪЕДИНИТЬ ВСЕ в запросе 1С

Если отчет формируется не через СКД, а с помощью программно формируемого запроса, или если вы хотите иметь более прямой контроль над SQL-запросом, можно использовать оператор ОБЪЕДИНИТЬ ВСЕ. Этот оператор позволяет объединить результаты нескольких независимых запросов в один результирующий набор данных.

  1. Структура запроса

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

    
    ВЫБРАТЬ
        Документ1.Товары.Номенклатура КАК Номенклатура,
        Документ1.Товары.Количество КАК Количество,
        Документ1.Ссылка КАК ДокументСсылка
    ИЗ
        Документ.ПоступлениеТоваровУслуг КАК Документ1
    ГДЕ
        Документ1.Ссылка В (&СписокДокументов1) // Параметр для первого документа/списка документов
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
        Документ2.Товары.Номенклатура,
        Документ2.Товары.Количество,
        Документ2.Ссылка
    ИЗ
        Документ.ПоступлениеТоваровУслуг КАК Документ2
    ГДЕ
        Документ2.Ссылка В (&СписокДокументов2) // Параметр для второго документа/списка документов
    
    // Затем агрегируем объединенные данные
    ИТОГИ СУММА(Количество) ПО Номенклатура
    
  2. Идентичные поля

    Критически важно, чтобы список полей, выбираемых в каждой секции ВЫБРАТЬ, был абсолютно одинаковым по количеству, порядку и типам. Если поля будут различаться, запрос завершится ошибкой или выдаст непредсказуемые результаты.

  3. Группировка и суммирование

    После объединения всех данных, мы используем предложение ИТОГИ СУММА(Количество) ПО Номенклатура для того, чтобы сгруппировать все записи по номенклатуре и просуммировать их количество. Таким образом, мы получаем консолидированный результат по каждой номенклатурной позиции из всех выбранных документов.

    Обработка отсутствующих позиций: Оператор ОБЪЕДИНИТЬ ВСЕ естественным образом включает все записи из каждого запроса. Если товар отсутствует в одном из документов, соответствующая строка просто не будет добавлена из этой части запроса. При последующем суммировании по номенклатуре это приведет к корректному итогу, так как будут просуммированы только существующие количества.

3. Использование временных таблиц

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

  1. Создание временных таблиц

    Мы выполняем отдельные запросы для каждого документа, но вместо того чтобы сразу выводить результат, мы помещаем его во временные таблицы с помощью предложения ПОМЕСТИТЬ.

    
    ЗАПРОС1 = Новый Запрос;
    ЗАПРОС1.Текст =
    "ВЫБРАТЬ
        Документ1.Товары.Номенклатура КАК Номенклатура,
        Документ1.Товары.Количество КАК Количество
    ИЗ
        Документ.ПоступлениеТоваровУслуг.Товары КАК Документ1
    ГДЕ
        Документ1.Ссылка = &ДокументСсылка1
    ПОМЕСТИТЬ ВТ_Документ1";
    
    ЗАПРОС2 = Новый Запрос;
    ЗАПРОС2.Текст =
    "ВЫБРАТЬ
        Документ2.Товары.Номенклатура КАК Номенклатура,
        Документ2.Товары.Количество КАК Количество
    ИЗ
        Документ.ПоступлениеТоваровУслуг.Товары КАК Документ2
    ГДЕ
        Документ2.Ссылка = &ДокументСсылка2
    ПОМЕСТИТЬ ВТ_Документ2";
    

    Каждый из этих запросов будет выполнен, и их результаты будут храниться в памяти сервера 1С как временные таблицы: ВТ_Документ1 и ВТ_Документ2.

  2. Объединение временных таблиц

    После того как все необходимые данные помещены во временные таблицы, мы можем выполнить третий запрос, который объединит данные из этих временных таблиц, используя тот же оператор ОБЪЕДИНИТЬ ВСЕ, и выполнит агрегацию.

    
    ОСНОВНОЙ_ЗАПРОС = Новый Запрос;
    ОСНОВНОЙ_ЗАПРОС.Текст =
    "ВЫБРАТЬ
        ВТ_Документ1.Номенклатура,
        ВТ_Документ1.Количество
    ИЗ
        ВТ_Документ1 КАК ВТ_Документ1
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
        ВТ_Документ2.Номенклатура,
        ВТ_Документ2.Количество
    ИЗ
        ВТ_Документ2 КАК ВТ_Документ2
    
    ИТОГИ СУММА(Количество) ПО Номенклатура
    ";
    
  3. Менеджер временных таблиц

    При программном формировании отчета или при использовании СКД для работы с временными таблицами используется объект МенеджерВременныхТаблиц. Этот объект позволяет управлять жизненным циклом временных таблиц (создание, очистка) и связывать их с различными запросами.

Выбор нескольких документов или складов в отчете

Чтобы предоставить пользователю возможность выбирать несколько документов или складов на форме отчета, необходимо правильно настроить механизм передачи параметров в запрос или СКД.

  1. Параметры отчета

    В настройках отчета (если это СКД) или в коде формирования запроса необходимо создать параметр, который способен принимать не одиночное значение, а список значений. Например, если нам нужно выбрать несколько документов, создаем параметр СписокДокументов типа СписокЗначений или Массив.

  2. Условие "В списке"

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

    
    ГДЕ
        Документ.Ссылка В (&СписокВыбранныхДокументов)
    

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

Что касается "стандартного отчета" из темы форума

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

В целом, использование СКД с наборами данных типа "Объединение" или прямое применение оператора ОБЪЕДИНИТЬ ВСЕ в запросе являются наиболее подходящими и эффективными способами для решения описанной задачи. Выбор конкретного метода зависит от уровня существующей доработки отчета и предпочтений разработчика.

← На главную