При разработке отчетов по учету агрегатов, узлов или шин на автотранспорте разработчики часто сталкиваются с ситуацией: в отчете выводятся установленные на технику шины, но как только добавляется группировка по регистратору, шины, находящиеся в запасе (или агрегаты с нулевым пробегом), полностью пропадают из результата. Разберем причины такого поведения платформы 1С:Предприятие и рассмотрим по шагам надежные способы решения этой задачи.
Рассмотрим, почему запрос к виртуальным таблицам регистра накопления не возвращает строки по агрегатам, у которых пробег равен нулю:
Остатки, Обороты, ОстаткиИОбороты) платформы 1С на уровне СУБД формируют запросы с агрегатными функциями и автоматической фильтрацией пустых итогов. Если по агрегату есть только движение с ресурсом, равным 0, либо движений за указанный период не было вовсе, виртуальная таблица не возвращает эту строку. Физическая таблица движений строку с нулем содержит, а виртуальная таблица итогов — отсекает.ЛЕВОГО СОЕДИНЕНИЯ в СКД: При соединении среза последних регистра сведений (список установленных шин) с виртуальной таблицей оборотов для запасных шин формируются значения NULL по всем полям правой таблицы, включая поле Регистратор.NULL, и при стандартных настройках компоновщик может исключить пустые ветки из дерева группировок.Если требуется сохранить единый запрос, разберем, как правильно составить текст запроса с заменой пустых значений регистратора и числовых ресурсов с помощью функции ЕСТЬNULL.
Посмотрим на пример запроса:
ВЫБРАТЬ
АгрегатыСрез.ТС КАК ТС,
АгрегатыСрез.ТС.ГосударственныйНомер КАК ГосНомер,
АгрегатыСрез.СерияНоменклатуры КАК СерияНоменклатуры,
АгрегатыСрез.СерияНоменклатуры.Модель КАК Модель,
АгрегатыСрез.СерияНоменклатуры.Модель.НормаПробега КАК НормаПробега,
ЕСТЬNULL(ИзносПробегОбороты.ПробегОборот, 0) КАК ПробегЗаПериод,
ЕСТЬNULL(ИзносПробегОбороты.ИзносОборот, 0) КАК ИзносЗаПериод,
ЕСТЬNULL(ИзносПробегОстатки.ПробегОстаток, 0) КАК ПробегВсего,
ЕСТЬNULL(ИзносПробегОстатки.ИзносОстаток, 0) КАК ИзносВсего,
ВЫБОР
КОГДА АгрегатыСрез.ТС.ДатаВыбытия <> ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ КАК ТСВыбыло,
ВЫБОР
КОГДА АгрегатыСрез.СерияНоменклатуры.Модель.НормаПробега > 0
ТОГДА ВЫРАЗИТЬ(ЕСТЬNULL(ИзносПробегОстатки.ПробегОстаток, 0) / АгрегатыСрез.СерияНоменклатуры.Модель.НормаПробега * 100 КАК ЧИСЛО(15, 2))
ИНАЧЕ 0
КОНЕЦ КАК ПроцентИспользования,
АгрегатыСрез.СостояниеАгрегата КАК СостояниеАгрегата,
ЕСТЬNULL(ИзносПробегОбороты.Регистратор, "Без пробега") КАК Регистратор
ИЗ
РегистрСведений.ДПАТ_АгрегатыТС.СрезПоследних(&Период, ) КАК АгрегатыСрез
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ИзносПробегШин.Обороты(&НачалоПериода, &КонецПериода, Регистратор, ) КАК ИзносПробегОбороты
ПО АгрегатыСрез.СерияНоменклатуры = ИзносПробегОбороты.СерияНоменклатуры
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ИзносПробегШин.Остатки(&Период, ) КАК ИзносПробегОстатки
ПО АгрегатыСрез.СерияНоменклатуры = ИзносПробегОстатки.СерияНоменклатуры
ГДЕ
АгрегатыСрез.СерияНоменклатуры.Модель.ТипАгрегата.ТипАгрегата = ЗНАЧЕНИЕ(Перечисление.ДПАТ_ТипыАгрегатов.Шина)
Обратим внимание на ключевую конструкцию ЕСТЬNULL(ИзносПробегОбороты.Регистратор, "Без пробега"): теперь для запасных агрегатов поле регистратора не является пустым значением NULL, а содержит конкретную строку. Это позволяет СКД успешно сформировать ветку группировки для шин без движений.
Наиболее архитектурно правильный подход в системе компоновки данных — разделение источников на два независимых набора данных. Разберем по шагам, как это реализовать:
Регистратор), получая поля Регистратор, ПробегОборот, ИзносОборот и остатки.НаборДанных1НаборДанных2СерияНоменклатуры = СерияНоменклатурыПри такой схеме СКД выведет все строки из первого набора данных независимо от того, есть ли соответствующие документы движения во втором наборе. Для шин без движений поле регистратора останется незаполненным, но сама строка агрегата из отчета не пропадет.
Если используется виртуальная таблица ОстаткиИОбороты, важно правильно сконфигурировать роли полей на вкладке Наборы данных:
Регистратор в колонке Роль необходимо указать флаг Период и задать соответствующий порядковый номер (счетчик).ПробегКонечныйОстаток) указать роли НачальныйОстаток и КонечныйОстаток, связав их с полем регистратора/периода.Правильная расстановка ролей сообщает компоновщику данных, как именно следует рассчитывать итоги и агрегировать остатки при сворачивании и разворачивании группировок отчета.
Проанализируем стандарты разработки 1С относительно нулевых движений: