Как реализовать полное соединение наборов данных в СКД и вывести остатки и потребности за каждый день?

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

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

Анализируем причину проблемы: почему «пропадают» данные?

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

Для решения этой задачи нам нужно имитировать полное соединение (Full Join). В СКД это реализуется двумя основными способами: через использование набора данных типа «Объединение» или через механизм «Дополнения периодов».

Решение 1: Использование набора данных «Объединение»

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

  1. Добавим в схему компоновки новый Набор данных - объединение.
  2. Переместим внутрь него оба наших набора: и Запрос, и Объект (таблицу значений).
  3. Проверим именование полей. Чтобы СКД «схлопнула» данные по номенклатуре и дате в одну строку, поля в обоих наборах должны называться абсолютно одинаково, например, Номенклатура и Период.
  4. В настройках отчета (вкладка «Настройки») выберем группировку по полю Период (день) и Номенклатура.

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

Также важно правильно передать таблицу значений в процессор компоновки. Посмотрим на пример кода:


ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("ТЗ_Потребность", ТаблицаПотребности);

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных);

Убедитесь, что имя ТЗ_Потребность в коде совпадает с именем объекта в схеме СКД.

Решение 2: Механизм «Дополнения периодов» в СКД

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

Рассмотрим по шагам, как это настроить:

  1. Перейдем в настройки отчета на вкладку «Настройки».
  2. Выберем группировку по полю Период.
  3. В нижней части окна перейдем на закладку «Иерархия группировки» или «Тип дополнения».
  4. Установим флаг «Дополнение периодов».
  5. Укажем начало и конец периода (обычно это параметры &НачалоПериода и &КонецПериода).
  6. Тип дополнения установим как День.

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

Решение 3: Использование виртуальной таблицы «Остатки и обороты»

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

При обращении к ней мы можем указать периодичность День. Это позволит нам получить готовый набор данных, где уже есть начальный остаток на каждый день и обороты за этот же день. Посмотрим на пример запроса:


ВЫБРАТЬ
    Регистр.Номенклатура,
    Регистр.Период КАК Период,
    Регистр.КоличествоНачальныйОстаток,
    Регистр.КоличествоПриход
ИЗ
    РегистрНакопления.Материалы.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, , ) КАК Регистр

Если мы объединим этот запрос через Набор данных - объединение с нашей таблицей значений потребностей, мы получим максимально стабильный результат без необходимости сложной настройки связей.

Как скрыть лишние колонки после поля «Остаток»?

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

Чтобы скрыть эти колонки или сделать отчет компактнее, рекомендуем следующее:

Таким образом, комбинируя механизм Набора-объединения для связи Запроса и ТЗ и Дополнение периодов для отображения пустых дат, вы получите полноценный и корректный отчет по движению материалов за каждый день.

← На главную