Как вывести поступления и списания одной строкой в отчете 1С

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

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

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

Способ 1. Использование агрегатных функций и конструкции ВЫБОР в запросе

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

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


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

В этом примере мы используем функцию СУММА в сочетании с ВЫБОР. Это позволяет системе при обходе записей проверять условие и прибавлять значение к нужному ресурсу (Поступление или Списание). В итоге для каждой номенклатуры сформируется ровно одна строка с заполненными показателями.

Способ 2. Настройка группировок в СКД

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

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

  1. Перейдем на закладку Настройки в схеме компоновки данных.
  2. Выберем группировку по полю Номенклатура.
  3. В составе выбранных полей этой группировки укажем все необходимые ресурсы: остатки, поступления и списания.
  4. Для детальных записей (если они нужны) создадим вложенную группировку.

Важный момент: чтобы поля не дублировались и отображались в одной строке, проверим свойство "Расположение полей". Установка значения "Вместе" или использование вертикальной группировки в выбранных полях позволяет визуально объединить данные.

Способ 3. Использование функции СтрокаСоединить в вычисляемых полях

Бывает так, что в одну строку нужно вывести не только цифры, но и перечень документов (регистраторов), которыми оформлялись движения. Начиная с версии платформы 8.3.15, мы можем использовать функцию СтрокаСоединить.

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

СтрокаСоединить(ВычислитьВыражениеСГруппировкойМассив("Регистратор"), ", ")

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

Способ 4. Связь наборов данных в СКД для исключения дублей

Одной из самых коварных проблем при объединении остатков и оборотов в одном запросе является эффект "умножения" (Cartesian Product). Если соединять таблицу остатков с таблицей оборотов через ЛЕВОЕ СОЕДИНЕНИЕ по номенклатуре в обычном запросе, то начальный остаток может продублироваться столько раз, сколько было движений по этой позиции.

Чтобы этого избежать, проанализируем архитектуру наборов данных в СКД. Вместо одного огромного запроса создадим два отдельных Набора данных - запрос:

  1. НаборОстатки: получает данные только из виртуальной таблицы Остатки.
  2. НаборДвижения: получает данные из таблицы Обороты или ОборотыДтКт.

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

Способ 5. Программная свертка таблицы значений

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


// Предположим, ТЗДвижения содержит колонки: Номенклатура, КоличествоПриход, КоличествоРасход
// Сначала подготавливаем данные, чтобы приход и расход были в разных колонках
ТЗДвижения.Свернуть("Номенклатура", "КоличествоПриход, КоличествоРасход, СуммаПриход, СуммаРасход");

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

Резюме

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

← На главную