При разработке внешних отчетов и обработок в 1С (особенно на обычных формах) часто возникает задача предоставить пользователю удобный интерфейс отборов по различным справочникам — например, одновременно по организациям и контрагентам. Схема компоновки данных (СКД) отлично подходит для выполнения роли гибкого конструктора условий. Однако при попытке выгрузить выбранные пользователем данные в ТаблицаЗначений разработчики сталкиваются с нюансами формирования запросов и работы с генератором макета.
Рассмотрим подробнее, как правильно организовать набор данных в СКД для нескольких справочников и корректно выгрузить результаты фильтрации в коллекцию значений.
Когда требуется вывести на форму отборы по нескольким несвязанным справочникам (например, Справочник.Организации и Справочник.Контрагенты), создавать отдельные наборы данных не требуется. Наиболее эффективным подходом является объединение запросов внутри одного набора данных НаборДанных1.
Разберем пример запроса, в котором поля обоих справочников выравниваются с помощью пустых ссылок:
ВЫБРАТЬ
Организации.Ссылка КАК Организация,
ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка) КАК Контрагент
ИЗ
Справочник.Организации КАК Организации
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка),
Контрагенты.Ссылка КАК Контрагент
ИЗ
Справочник.Контрагенты КАК Контрагенты
Посмотрим на особенности этого подхода:
Организация и Контрагент.Отбор.ГДЕ ЛОЖЬ или оптимизации выбора полей.После того как пользователь заполнил условия на форме (через реквизит формы, связанный с КомпоновщикНастроек.Настройки.Отбор), необходимо программно выполнить компоновку и получить выбранные значения.
Проанализируем программный код для выгрузки результата компоновки в коллекцию значений:
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
СхемаКомпоновкиДанных = ПолучитьМакет("МакетДляОтборов");
// Для учета изменений, внесенных пользователем на форме,
// рекомендуется получать настройки через КомпоновщикНастроек.ПолучитьНастройки()
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
Макет = КомпоновщикМакета.Выполнить(
СхемаКомпоновкиДанных,
Настройки,
,,
Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений")
);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ТЗ = Новый ТаблицаЗначений;
ПроцессорВывода.УстановитьОбъект(ТЗ);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Выясним основные причины, по которым созданные колонки (например, Контрагент) могут отсутствовать в итоговой ТаблицаЗначений:
ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений создает колонки в ТаблицаЗначений только для тех полей, которые присутствуют в коллекции Выбранные поля соответствующей группировки или корня настроек СКД. Если поле есть в запросе и в отборах, но не добавлено в выбранные поля макета, колонка выгружена не будет. Убедитесь, что в макете СКД сформированы группировки (например, группировка «Детальные записи») и в список выбранных полей внесены и Организация, и Контрагент.КомпоновщикНастроек.Настройки в КомпоновщикМакета.Выполнить может не учесть пользовательские изменения. Вызов метода ПолучитьНастройки() гарантирует объединение основных и пользовательских настроек.Если задача заключается исключительно в получении выбранных пользователем ссылок (без выполнения запроса к базе данных), выполнение компоновки может быть избыточным. Разберем вариант обхода элементов отбора напрямую через коллекцию настроек:
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
Для Каждого Элемент Из Настройки.Отбор.Элементы Цикл
Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") И Элемент.Использование Тогда
Если Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент") Тогда
ЗначениеФильтра = Элемент.ПравоеЗначение;
// Обработка выбранного контрагента или СпискаЗначений
ИначеЕсли Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация") Тогда
ЗначениеФильтра = Элемент.ПравоеЗначение;
// Обработка выбранной организации
КонецЕсли;
КонецЕсли;
КонецЦикл;
Такой подход позволяет моментально считывать значения отборов из формы без формирования макета СКД и исполнения запросов к базе данных.