Как настроить несколько отборов в СКД и выгрузить отобранные значения в Таблицу Значений?

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

При разработке внешних отчетов и обработок в 1С (особенно на обычных формах) часто возникает задача предоставить пользователю удобный интерфейс отборов по различным справочникам — например, одновременно по организациям и контрагентам. Схема компоновки данных (СКД) отлично подходит для выполнения роли гибкого конструктора условий. Однако при попытке выгрузить выбранные пользователем данные в ТаблицаЗначений разработчики сталкиваются с нюансами формирования запросов и работы с генератором макета.

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

Организация набора данных запроса для нескольких отборов

Когда требуется вывести на форму отборы по нескольким несвязанным справочникам (например, Справочник.Организации и Справочник.Контрагенты), создавать отдельные наборы данных не требуется. Наиболее эффективным подходом является объединение запросов внутри одного набора данных НаборДанных1.

Разберем пример запроса, в котором поля обоих справочников выравниваются с помощью пустых ссылок:


ВЫБРАТЬ
	Организации.Ссылка КАК Организация,
	ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка) КАК Контрагент
ИЗ
	Справочник.Организации КАК Организации

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка),
	Контрагенты.Ссылка КАК Контрагент
ИЗ
	Справочник.Контрагенты КАК Контрагенты

Посмотрим на особенности этого подхода:

  1. Каждая ветка объединения возвращает заменяющую пустую ссылку для полей, отсутствующих в текущей таблице. Это позволяет СКД однозначно определить типы полей Организация и Контрагент.
  2. В настройках отчета (вкладка «Настройки» СКД) обе колонки становятся доступны для отбора в коллекции Отбор.
  3. Если отчет используется только как форма отборов и вычислять реальные данные из базы не требуется, запрос можно ускорить с помощью условия ГДЕ ЛОЖЬ или оптимизации выбора полей.

Выгрузка результатов компоновки в Таблицу Значений

После того как пользователь заполнил условия на форме (через реквизит формы, связанный с КомпоновщикНастроек.Настройки.Отбор), необходимо программно выполнить компоновку и получить выбранные значения.

Проанализируем программный код для выгрузки результата компоновки в коллекцию значений:


КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
СхемаКомпоновкиДанных = ПолучитьМакет("МакетДляОтборов");

// Для учета изменений, внесенных пользователем на форме,
// рекомендуется получать настройки через КомпоновщикНастроек.ПолучитьНастройки()
Настройки = КомпоновщикНастроек.ПолучитьНастройки();

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

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

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ТЗ = Новый ТаблицаЗначений;
ПроцессорВывода.УстановитьОбъект(ТЗ);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

Почему новые поля могут не выгружаться в Таблицу Значений?

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

  1. Поле не добавлено в выбранные поля структуры: ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений создает колонки в ТаблицаЗначений только для тех полей, которые присутствуют в коллекции Выбранные поля соответствующей группировки или корня настроек СКД. Если поле есть в запросе и в отборах, но не добавлено в выбранные поля макета, колонка выгружена не будет. Убедитесь, что в макете СКД сформированы группировки (например, группировка «Детальные записи») и в список выбранных полей внесены и Организация, и Контрагент.
  2. Использование `КомпоновщикНастроек.Настройки` вместо `ПолучитьНастройки()`: Если пользователь редактировал настройки на форме, прямая передача КомпоновщикНастроек.Настройки в КомпоновщикМакета.Выполнить может не учесть пользовательские изменения. Вызов метода ПолучитьНастройки() гарантирует объединение основных и пользовательских настроек.

Альтернативный вариант: Прямой разбор элементов отбора

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


Настройки = КомпоновщикНастроек.ПолучитьНастройки();

Для Каждого Элемент Из Настройки.Отбор.Элементы Цикл
	Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") И Элемент.Использование Тогда
		Если Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент") Тогда
			ЗначениеФильтра = Элемент.ПравоеЗначение;
			// Обработка выбранного контрагента или СпискаЗначений
		ИначеЕсли Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация") Тогда
			ЗначениеФильтра = Элемент.ПравоеЗначение;
			// Обработка выбранной организации
		КонецЕсли;
	КонецЕсли;
КонецЦикл;

Такой подход позволяет моментально считывать значения отборов из формы без формирования макета СКД и исполнения запросов к базе данных.

← На главную