Как правильно объединить данные регистров «Товары на складах» и «Материалы в производстве» в одном отчете 1С:УПП?

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

При разработке сложных отчетов в конфигурации «Управление производственным предприятием 1.3» (УПП) программисты часто сталкиваются с необходимостью вывести в одной форме данные из разных учетных контуров. Типичный пример — совмещение данных по складским остаткам и остаткам материалов, переданных в производство. Однако при попытке просто «соединить» две таблицы в системе компоновки данных (СКД) часто возникает логическая ошибка: данные начинают дублироваться, а «Расход» внезапно превращается в «Приход».

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

Анализ проблемы: почему данные отображаются некорректно?

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

  1. Регистр «Товары на складах»: основным измерением является Склад.
  2. Регистр «Материалы в производстве»: основным измерением является Подразделение.

Попытка соединить эти таблицы по полю Регистратор или Номенклатура через «Левое соединение» в запросе приводит к так называемому «декартову произведению». Если в документе «Отчет производства за смену» (ОПзС) выпущено 5 видов продукции и списано 10 видов материалов, то при соединении по регистратору система создаст 50 строк. В результате агрегатные функции СКД (Сумма) выдадут неверные итоги, а из-за особенностей связи наборов данных в СКД, ресурсы одного регистра могут ошибочно подставляться в колонки другого.

Именно поэтому пользователь видит «Приход» там, где должен быть «Расход»: СКД просто не понимает, к какому движению относится конкретная строка при неправильно настроенной связи.

Решение №1: Использование объединения (UNION ALL) в одном запросе

Если нам необходимо видеть данные в одном списке, вместо соединения (JOIN) следует использовать объединение (UNION). Это позволит избежать дублирования записей.

Проанализируем структуру такого запроса:

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

Решение №2: Программный вывод двух разных макетов СКД

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

Шаг 1. Подготовка макетов. Создадим в отчете два макета схемы компоновки данных: СхемаТовары и СхемаМатериалы. В каждом макете настроим свой запрос к соответствующему регистру без каких-либо сложных соединений.

Шаг 2. Описание программного кода вывода. Нам потребуется написать процедуру, которая инициализирует каждый макет и выводит его в общий ТабличныйДокумент.

Рассмотрим пример кода для реализации этой задачи:


// Процедура для формирования отчета из двух схем
Процедура СформироватьОтчет(ТабличныйДокумент) Экспорт
    
    ТабличныйДокумент.Очистить();
    
    // 1. Выводим первую схему (Товары на складах)
    ВывестиСхемуВДокумент(ТабличныйДокумент, "СхемаТовары");
    
    // Добавим разделитель между таблицами
    ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
    
    // 2. Выводим вторую схему (Материалы в производстве)
    ВывестиСхемуВДокумент(ТабличныйДокумент, "СхемаМатериалы");
    
КонецПроцедуры

Процедура ВывестиСхемуВДокумент(ТабДок, ИмяМакета)
    
    СхемаКД = ЭтотОбъект.ПолучитьМакет(ИмяМакета);
    Настройки = СхемаКД.НастройкиПоУмолчанию;
    
    // Передаем параметры (например, период), если они определены на форме
    ПараметрПериод = Настройки.ПараметрыДанных.Элементы.Найти("Период");
    Если ПараметрПериод <> Неопределено Тогда
        ПараметрПериод.Значение = ЭтотОбъект.КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("Период").Значение;
        ПараметрПериод.Использование = Истина;
    КонецЕсли;

    ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    
    // Формируем макет компоновки
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКД, Настройки, ДанныеРасшифровки);
    
    // Инициализируем процессор компоновки
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
    
    // Выводим результат в табличный документ
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ТабДок);
    
    // Используем Истина во втором параметре, чтобы данные дописывались в конец документа
    ПроцессорВывода.Вывести(ПроцессорКомпоновки, Истина);
    
КонецПроцедуры

Важные моменты при работе с регистрами в УПП

Разберем, почему движения документа «Требование-накладная» (ТрН) могут отображаться только в одном из регистров. В типовой логике УПП 1.3:

Если в вашем совмещенном отчете ТрН отображается только как расход, выясним причину: скорее всего, вы смотрите на данные через призму складских остатков. Для корректного анализа «движения в производство» необходимо четко разделять приход в производство (ТрН) и расход из производства (ОПзС). Соединение этих данных в одну строку по регистратору архитектурно неверно, так как у них разные аналитические разрезы.

Рекомендации по настройке ресурсов СКД

Чтобы избежать путаницы между колонками разных регистров, проанализируем настройки на закладке «Ресурсы» в СКД:

  1. Уникальные имена полей: старайтесь называть ресурсы в разных наборах данных по-разному, например, КоличествоСклад и КоличествоПроизводство. Это предотвратит их автоматическое суммирование системой СКД при выводе.
  2. Роли полей: проверьте, чтобы у полей остатков были правильно проставлены роли (НачальныйОстаток, КонечныйОстаток) и указаны соответствующие поля периодов.
  3. Группировки: если вы используете два набора данных в одной схеме (без программного кода), убедитесь, что они связаны по Номенклатуре, но не связаны по Регистратору, если вы не хотите получить дублирование строк.

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

← На главную