При разработке интерфейсов и отчетов в 1С:Предприятие часто возникает задача отображения нескольких полей данных в одной визуальной колонке, например, для экономии места или для более логичного представления информации. Стандартный механизм "Дерево значений" позволяет гибко работать с иерархическими данными, но объединение колонок требует определенных подходов. Давайте вместе разберем, как эффективно решить эту задачу, рассмотрим различные методы и их особенности.
Один из самых простых и прямолинейных способов создания совмещенной колонки – это объединение текстовых представлений нескольких полей непосредственно в запросе. Мы можем сформировать новую колонку, конкатенируя значения из других полей. Этот подход позволяет получить готовую объединенную строку, которую затем можно вывести в любую колонку дерева значений.
Посмотрим на пример такого запроса:
ВЫБРАТЬ
Строка(таб.Номенклатура) + "/" + Строка(таб.Заказ) КАК Колонка1,
таб.КоличествоОстаток КАК Остаток
ИЗ
РегистрНакопления КАК таб
УПОРЯДОЧИТЬ ПО
таб.Номенклатура
ИТОГИ СУММА(Остаток) ПО таб.Номенклатура
В этом примере мы объединяем наименование номенклатуры и номер заказа, разделяя их символом "/". Результатом будет одна текстовая колонка под названием Колонка1.
Несмотря на простоту, такой метод имеет существенные ограничения, о которых нам следует помнить:
Если вам необходимо сохранить интерактивность, но при этом визуально отображать объединенную колонку, мы можем использовать следующий подход:
Номенклатура и Заказ) в отдельных колонках. Эти колонки могут быть скрыты от пользователя, если они не нужны для прямого отображения.ПриПолученииДанных или ОбработкаРасшифровки. В этих событиях вы можете формировать текстовое представление из нескольких колонок и присваивать его отображаемой колонке. Это позволит вам иметь доступ к базовым данным для выполнения таких действий, как открытие ссылок или вызов контекстных команд.Более гибкий и часто используемый метод — это выгрузка результата запроса непосредственно в объект ДеревоЗначений с последующей передачей его на форму. Этот подход позволяет нам строить иерархические структуры и более детально управлять данными.
Если ваш запрос содержит группировки (с помощью оператора ИТОГИ ПО), вы можете выгрузить его результат в дерево значений, которое автоматически сформирует иерархию на основе этих группировок. Рассмотрим пример:
ДеревоИзЗапроса = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
ЗначениеВРеквизитФормы(ДеревоИзЗапроса, "Дерево");
Здесь мы используем метод Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам), который строит иерархию дерева на основе уровней группировки в запросе. Затем с помощью функции ЗначениеВРеквизитФормы() мы передаем полученное дерево значений в реквизит формы с именем "Дерево".
Важный момент: Для корректного отображения иерархии в запросе должны быть четко определены операторы ИТОГИ ПО, которые задают уровни группировки. Также убедитесь, что структура колонок реквизита формы типа ДеревоЗначений соответствует структуре объекта дерева, полученного из запроса, чтобы избежать ошибок.
В случаях, когда прямой выгрузки запроса недостаточно или требуется более сложная логика заполнения, мы можем программно формировать дерево значений. Это дает нам полный контроль над структурой и содержимым.
Разберем по шагам процесс программного заполнения:
Начнем с создания нового экземпляра ДеревоЗначений:
МоеДерево = Новый ДеревоЗначений;
Прежде чем добавлять строки, нам необходимо определить структуру колонок. Каждая колонка имеет имя, тип и может иметь заголовок. Тип колонки определяется с помощью объекта ОписаниеТипов. Важно: после создания колонки ее тип изменить нельзя.
МоеДерево.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
МоеДерево.Колонки.Добавить("Заказ", Новый ОписаниеТипов("ДокументСсылка.Заказ"));
МоеДерево.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
МоеДерево.Колонки.Добавить("СовмещеннаяКолонка", Новый ОписаниеТипов("Строка"));
Мы видим, что мы можем добавить как колонки для исходных данных (Номенклатура, Заказ, Количество), так и отдельную колонку для совмещенного текстового представления (СовмещеннаяКолонка).
Если у нас есть выборка из запроса с иерархией (полученная, например, с помощью Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам)), мы можем перебирать ее и заполнять дерево. Для вложенных уровней удобно использовать рекурсивную процедуру.
Функция ЗаполнитьДеревоИзВыборки(ВыборкаЗапроса, РодительскаяСтрокаДерева)
Пока ВыборкаЗапроса.Следующий() Цикл
Если ВыборкаЗапроса.Уровень() = 0 Тогда // Верхний уровень
НоваяСтрока = МоеДерево.Строки.Добавить();
Иначе // Подчиненный уровень
НоваяСтрока = РодительскаяСтрокаДерева.Строки.Добавить();
КонецЕсли;
НоваяСтрока.Номенклатура = ВыборкаЗапроса.Номенклатура;
НоваяСтрока.Заказ = ВыборкаЗапроса.Заказ;
НоваяСтрока.Количество = ВыборкаЗапроса.КоличествоОстаток;
// Формируем совмещенную колонку
НоваяСтрока.СовмещеннаяКолонка = Строка(ВыборкаЗапроса.Номенклатура) + "/" + Строка(ВыборкаЗапроса.Заказ);
// Если есть вложенные выборки, рекурсивно вызываем функцию
Если ВыборкаЗапроса.ЕстьВложенныеВыборки() Тогда
ЗаполнитьДеревоИзВыборки(ВыборкаЗапроса.Выбрать(), НоваяСтрока);
КонецЕсли;
КонецЦикла;
КонецФункции
// Пример использования
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
// ... поля и группировки
|ИТОГИ ПО Номенклатура"; // Пример группировки
ВыборкаДанных = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
ЗаполнитьДеревоИзВыборки(ВыборкаДанных, МоеДерево);
После заполнения дерева его необходимо присвоить реквизиту управляемой формы соответствующего типа для отображения. Для этого мы снова используем функцию ЗначениеВРеквизитФормы().
ЗначениеВРеквизитФормы(МоеДерево, "ДеревоНаФорме");
При работе с очень большими объемами данных или глубокой иерархией прямой обход результата запроса и пошаговое заполнение дерева может быть не самым производительным решением. В таких случаях мы можем рассмотреть "оптимизированные" методы, например, предварительное получение всех данных в плоскую таблицу значений, а затем ее обход для более эффективного построения дерева.
Система Компоновки Данных (СКД) — это мощный инструмент 1С, который обычно ассоциируется с формированием отчетов в табличном документе. Однако СКД также предоставляет механизм для вывода данных напрямую в коллекции значений, такие как ТаблицаЗначений или ДеревоЗначений. Это может быть особенно полезно, когда требуется динамически формировать сложную иерархию или использовать гибкие настройки отчета.
Для вывода результата компоновки данных в ДеревоЗначений мы используем объект ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений. Рассмотрим общий алгоритм:
КомпоновщикМакетаКомпоновкиДанных.КомпоновщикМакета.Выполнить().ПроцессорКомпоновкиДанных.ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений и указываем целевое дерево значений с помощью метода УстановитьОбъект().ПроцессорВывода.Вывести().Пример кода (упрощенный):
// 1. Получаем схему компоновки данных (например, из макета)
СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
// 2. Создаем настройки компоновки (если необходимо)
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
// Можно программно изменить выбранные поля, группировки и т.д.
// 3. Создаем КомпоновщикМакетаКомпоновкиДанных
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки);
// 4. Создаем ПроцессорКомпоновкиДанных
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки); // ДанныеРасшифровки опционально
// 5. Создаем целевое ДеревоЗначений
РезультатДерево = Новый ДеревоЗначений;
// 6. Создаем ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(РезультатДерево);
// 7. Выводим результат
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// Теперь РезультатДерево содержит данные из СКД
ЗначениеВРеквизитФормы(РезультатДерево, "ДеревоНаФорме");
Применение СКД для формирования дерева значений дает нам следующие преимущества:
Важно учитывать, что при выводе результата СКД непосредственно в коллекцию значений (в отличие от вывода в табличный документ) существуют определенные ограничения:
Иногда возникает обратная задача: использовать уже сформированное ДеревоЗначений в качестве источника данных для СКД. Для сохранения иерархических связей между родительскими и дочерними строками в таком сценарии нам потребуется добавить служебные поля в дерево значений для хранения идентификатора строки и идентификатора родителя, заполняя их в процессе формирования дерева. Эти поля затем будут использоваться в схеме СКД для построения связей.
Давайте проанализируем некоторые общие моменты, которые помогут нам эффективнее работать с ДеревомЗначений:
ДеревоЗначений, как и ТаблицаЗначений, является серверным объектом. Это означает, что работать с ним напрямую можно только в серверном контексте или на толстом клиенте. На тонком клиенте с ДеревомЗначений можно работать только в том случае, если оно создано в виде реквизита управляемой формы. В этом случае платформа сама обеспечивает передачу данных между клиентом и сервером.ДеревоЗначений не имеет встроенного механизма стандартной фильтрации, аналогичного, например, методу Отбор у ТаблицыЗначений. Если вам нужна фильтрация, ее придется реализовывать программно, обходя строки дерева и скрывая или удаляя те, которые не соответствуют условиям. Это может быть сложным нюансом, особенно когда нужно учитывать иерархию (например, если родитель не удовлетворяет условию, а подчиненный элемент удовлетворяет).ДеревеЗначений используется метод Сортировать(). Он позволяет выполнять сортировку как по одному уровню иерархии, так и с учетом подчиненных строк.
// Сортировка по колонке "Номенклатура" по возрастанию
МоеДерево.Сортировать("Номенклатура Возр");
// Сортировка по нескольким колонкам
МоеДерево.Сортировать("Номенклатура Возр, Количество Убыв");
Мы можем указать несколько колонок для сортировки, а также направление сортировки (Возр - возрастание, Убыв - убывание).
Мы рассмотрели различные подходы к созданию и работе с совмещенными колонками в ДеревеЗначений. Выбор конкретного метода зависит от ваших требований к интерактивности, сложности иерархии и производительности. Надеемся, что этот подробный разбор поможет вам найти оптимальное решение для вашей задачи!