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