Как вывести нулевые строки и отобразить период в отчете СКД 1С

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

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

Причины исчезновения пустых строк при применении отборов

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

Однако при добавлении отбора (например, по периоду или подразделению) пустые строки с нулевыми показателями часто исчезают. Происходит это потому, что отбор СКД по умолчанию накладывается на итоговую выборку в секции ГДЕ. Когда для элементов без движений значения полей регистра равны NULL, любое условие сравнения вида Регистр.Период = &Период возвращает Ложь, и строки с NULL отсекаются из результата.

Способ 1. Использование условия с проверкой на ЕСТЬ NULL в запросе

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

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


ВЫБРАТЬ
	СправочникНоменклатура.Ссылка КАК Номенклатура,
	ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) КАК Количество
ИЗ
	Справочник.Номенклатура КАК СправочникНоменклатура
	ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
	ПО СправочникНоменклатура.Ссылка = ПродажиОбороты.Номенклатура
ГДЕ
	(ПродажиОбороты.Период = &Период ИЛИ ПродажиОбороты.Период ЕСТЬ NULL)

Такой подход позволяет сохранить строки, не имеющие движений в регистре. Однако стоит учитывать важный нюанс: использование условий с логическим оператором ИЛИ и проверкой ЕСТЬ NULL в секции ГДЕ может негативно сказаться на производительности СУБД, так как оптимизатор запросов не всегда может эффективно использовать индексы.

Способ 2. Перенос условий в параметры виртуальной таблицы (Best Practice)

Более эффективным и архитектурно правильным решением в 1С является передача условий фильтрации непосредственно в параметры виртуальной таблицы регистра. В этом случае фильтрация происходит до выполнения соединения с ведущим справочником.

Разберем структуру такого запроса на примере:


ВЫБРАТЬ
	СправочникНоменклатура.Ссылка КАК Номенклатура,
	ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) КАК Количество
ИЗ
	Справочник.Номенклатура КАК СправочникНоменклатура
	ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(
		&НачалоПериода,
		&КонецПериода,
		Авто,
		Организация = &Организация
	) КАК ПродажиОбороты
	ПО СправочникНоменклатура.Ссылка = ПродажиОбороты.Номенклатура

При таком подходе из регистра выбираются только данные, соответствующие заданным параметрам. Последующее ЛЕВОЕ СОЕДИНЕНИЕ гарантирует сохранение всех элементов справочника Номенклатура, а функция ЕСТЬNULL() заменяет отсутствующие значения на «0».

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

Способ 3. Механизм «Дополнение периодов» в СКД

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

Рассмотрим по шагам настройку дополнения периодов:

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

СКД автоматически сгенерирует все недостающие даты в указанном диапазоне и выведет строки с нулевыми значениями ресурсов.

Вывод периода отчета в шапку произвольного макета

При оформлении отчетов с использованием собственных макетов часто требуется вывести фразу вида: «За период с 01.01.2024 по 31.01.2024». Рассмотрим способы реализации этой задачи.

Вариант А. Вычисляемые поля и функция ПредставлениеПериода()

Платформа 1С содержит встроенную функцию для получения корректной строковой формулировки периода:

  1. Перейдем на вкладку «Вычисляемые поля».
  2. Добавим новое поле с именем ПредставлениеПериодаОтчета.
  3. В колонку «Выражение» введем следующую функцию:

ПредставлениеПериода(&НачалоПериода, &КонецПериода, "Л=ru")

Данная функция автоматически сформирует готовый текст (например, «Январь 2024 г.» или «с 01.01.2024 по 31.01.2024» в зависимости от введенных границ).

Вариант Б. Настройка ячейки в макете оформления

Если в отчете используется индивидуальный макет заголовка, оформить вывод периода можно напрямую через свойства ячейки макета:

  1. На вкладке «Макеты» создадим макет области для заголовка.
  2. Выделим ячейку и установим заполнение в значение Шаблон.
  3. В тексте ячейки впишем: За период с [ДатаНачала] по [ДатаОкончания].
  4. В таблице параметров макета зададим выражения для параметров:

    Для ДатаНачала: Формат(&НачалоПериода, "ДФ=dd.MM.yyyy")

    Для ДатаОкончания: Формат(&КонецПериода, "ДФ=dd.MM.yyyy")

Вариант В. Обработка незаполненных дат и СтандартногоПериода

Если пользователь задает интервал через один параметр типа СтандартныйПериод, дата окончания периода может принимать системное значение 31.12.3999 23:59:59, когда верхняя граница не ограничена.

Чтобы избежать вывода неограниченной даты в шапке, проанализируем выражение проверки:


ВЫБОР
	КОГДА ЗначениеЗаполнено(&КонецПериода) И &КонецПериода < ДАТАВРЕМЯ(3999, 12, 31)
		ТОГДА Формат(&КонецПериода, "ДФ=dd.MM.yyyy")
	ИНАЧЕ "по н.в."
КОНЕЦ

Использование этого выражения в параметрах макета позволит сформировать корректный и понятный заголовок отчета при любых вводных данных пользователя.

← На главную