К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как добавить колонку в дерево значений в 1С

Как программно добавить колонку в дерево значений 1С: метод Колонки.Добавить, типы данных, реквизит формы, вложенные строки, типичные ошибки и примеры кода.

Дерево значений в 1С — это иерархическая структура данных, которая хранится в памяти и используется для группировок, итогов по уровням и отображения вложенных списков на форме. Прежде чем заполнять дерево строками, в него нужно добавить колонки — без них попытка обратиться к полю строки вызовет ошибку «Поле объекта не обнаружено».

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

Ниже разобраны оба сценария: работа с деревом значений только в коде (например, для промежуточных расчётов) и вывод дерева на форму с динамическим набором колонок. Также показано, как заполнить колонки данными, проверить результат и какие ошибки встречаются чаще всего.

Базовый способ: метод Колонки.Добавить()

У объекта «ДеревоЗначений» есть свойство Колонки — коллекция колонок. Метод Добавить() принимает до четырёх параметров: имя колонки, описание типов, заголовок и ширину. Минимально достаточно указать имя — тогда колонка сможет хранить значения произвольного типа.

Дерево = Новый ДеревоЗначений;

Дерево.Колонки.Добавить("Номенклатура");

Дерево.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));

Дерево.Колонки.Добавить("Склад", Новый ОписаниеТипов("СправочникСсылка.Склады"), "Склад отгрузки");

Имя колонки должно быть корректным идентификатором: начинаться с буквы, не содержать пробелов и спецсимволов. Заголовок — это произвольная строка, которая отображается пользователю, если дерево выводится на форму. Ширину указывают в символах; если её не задать, платформа подберёт значение автоматически.

Метод возвращает объект «КолонкаДереваЗначений», через который можно дополнительно настроить свойства — например, изменить тип или заголовок уже после добавления. Обращение к колонке позже выполняется по имени: СтрокаДерева.Номенклатура = ТекТовар;.

bsl
Дерево = Новый ДеревоЗначений;
Дерево.Колонки.Добавить("Группа", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(150)));
Дерево.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
Дерево.Колонки.Добавить("Пометка", Новый ОписаниеТипов("Булево"));

Как задать тип данных колонки через ОписаниеТипов

Второй параметр метода Добавить() — объект «ОписаниеТипов». Он ограничивает значения, которые можно записать в ячейку. Если тип не указан, колонка принимает любые значения, что удобно на этапе прототипирования, но опасно в рабочем коде: при сортировке или группировке смешанные типы могут дать неожиданный порядок.

Для примитивных типов конструктор выглядит так: Новый ОписаниеТипов("Строка"), Новый ОписаниеТипов("Число"), Новый ОписаниеТипов("Дата"), Новый ОписаниеТипов("Булево"). Составной тип задаётся перечислением через запятую: Новый ОписаниеТипов("СправочникСсылка.Номенклатура,СправочникСсылка.Контрагенты").

Для строк и чисел полезно уточнить квалификаторы. КвалификаторыСтроки ограничивает длину, КвалификаторыЧисла — разрядность и точность, КвалификаторыДаты — состав даты (только дата или дата со временем). Это влияет на хранение и на отображение в табличном поле.

Добавление колонки в дерево на управляемой форме

Когда дерево значений является реквизитом формы, недостаточно изменить сам объект — нужно изменить структуру реквизитов формы. Для этого используется метод ИзменитьРеквизиты(), который принимает два массива: добавляемые и удаляемые реквизиты. Каждый новый реквизит описывается объектом «РеквизитФормы».

&НаСервере

Процедура ДобавитьКолонкуДерева(ИмяКолонки, Заголовок)

Добавляемые = Новый Массив;

Добавляемые.Добавить(Новый РеквизитФормы(ИмяКолонки,

Новый ОписаниеТипов("Строка"), "ДеревоДанных", Заголовок));

ИзменитьРеквизиты(Добавляемые);

КонецПроцедуры

Третий параметр конструктора «РеквизитФормы» — путь к родительскому реквизиту, то есть имя реквизита формы типа «ДеревоЗначений». После изменения реквизитов нужно программно создать элемент формы (поле таблицы), привязанный к новой колонке, иначе колонка будет существовать в данных, но не отобразится пользователю.

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

Порядок действий для дерева на форме
  1. 1
    Создайте реквизит формы типа «ДеревоЗначений» (в конфигураторе или программно)
  2. 2
    Добавьте колонки через ИзменитьРеквизиты() с указанием пути к дереву
  3. 3
    Создайте элементы формы (поля таблицы) и свяжите их с новыми колонками через ПутьКДанным
  4. 4
    Заполните дерево строками через ДеревоДанных.ПолучитьЭлементы().Добавить()
  5. 5
    Проверьте отображение: откройте форму и разверните узлы дерева

Заполнение колонок данными и вложенные строки

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

СтрокаГруппы = Дерево.Строки.Добавить();

СтрокаГруппы.Группа = "Электроинструмент";

СтрокаТовара = СтрокаГруппы.Строки.Добавить();

СтрокаТовара.Группа = "Дрель ударная";

СтрокаТовара.Сумма = 4500;

Типичный источник данных — результат запроса. Метод Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией) возвращает готовое дерево значений, и его колонки формируются автоматически по полям запроса. В этом случае добавлять колонки вручную не нужно, но можно дополнить дерево вычисляемыми колонками после выгрузки.

Если колонку добавляют в уже заполненное дерево, существующие строки получат в этой колонке пустые значения. Их можно заполнить обходом дерева — рекурсивно по Строки или через НайтиСтроки() для плоских структур.

Если дерево строится из запроса с итогами по группировкам, проще добавить вычисляемое поле прямо в текст запроса (например, 0 КАК Резерв), чем добавлять колонку и обходить все строки после выгрузки.
ПЗ
Практическое замечание

Типичные ошибки при добавлении колонок

Самая частая проблема — обращение к колонке, которой нет. Ошибка «Поле объекта не обнаружено» возникает, когда имя в коде заполнения не совпадает с именем при добавлении: лишний пробел, другой регистр букв не мешает (платформа регистронезависима), но опечатка в символах — да. Перед обращением можно проверить наличие: Если Дерево.Колонки.Найти("Сумма") <> Неопределено Тогда ....

Вторая группа ошибок связана с управляемыми формами. Разработчик добавляет колонку в объект дерева через РеквизитФормыВЗначение(), но забывает, что после обратного преобразования ЗначениеВРеквизитФормы() структура реквизита не изменится — новая колонка просто потеряется. Для динамических колонок нужен именно ИзменитьРеквизиты().

Третья ситуация — дублирование колонок при повторном вызове процедуры инициализации. Если обработчик «ПриСозданииНаСервере» или кнопка обновления вызывает добавление колонок повторно, платформа выдаст ошибку о том, что колонка с таким именем уже существует. Перед добавлением стоит очищать коллекцию Дерево.Колонки.Очистить() или проверять наличие.

Типичные ошибки
01
Обращение к колонке до её добавления — ошибка «Поле объекта не обнаружено»
02
Повторное добавление колонки без проверки — ошибка дублирования имени
03
Изменение объекта дерева вместо реквизита формы — колонка не отображается на форме
04
Добавление колонки через ИзменитьРеквизиты() без создания элемента формы — данные есть, но пользователь их не видит
05
Колонка без типа, по которой выполняется сортировка, — непредсказуемый порядок строк

Проверка результата и отладка

Быстрый способ убедиться, что колонки созданы, — вывести их список в отладчике или через Сообщить(): перебрать Дерево.Колонки и посмотреть свойства Имя, ТипЗначения, Заголовок. Для проверки данных удобно временно выгрузить дерево в таблицу значений одноуровневой структуры или использовать вычисление выражения в конфигураторе.

На форме признаком корректной настройки служит появление колонки в табличном поле с заданным заголовком и возможность разворачивать узлы. Если колонка видна, но пуста — проверьте совпадение имён при заполнении. Если колонки нет вообще — проверьте ПутьКДанным у элемента формы и то, что элемент создан после вызова ИзменитьРеквизиты().

Контрольные точки

Как проверить результат

Состав колонок дерева
Норма

Колонка присутствует в Дерево.Колонки с нужным типом

Тревожный признак

Колонки нет или тип «Произвольный» вместо ожидаемого

Отображение на форме
Норма

Поле таблицы показывает заголовок и значения

Тревожный признак

Колонка невидима или пуста при заполненных данных

Заполнение строк
Норма

Значения читаются по имени колонки без ошибок

Тревожный признак

Ошибка «Поле объекта не обнаружено» при обращении

FAQ

Можно ли добавить колонку в дерево значений, полученное из запроса?

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

Как удалить колонку из дерева значений?

Используйте метод Дерево.Колонки.Удалить(Колонка), где параметр — объект колонки, найденный через Дерево.Колонки.Найти("Имя"), либо её индекс. Для полной очистки структуры подходит Дерево.Колонки.Очистить() — при этом удаляются и все строки, поскольку без колонок дерево не может хранить данные.

Почему колонка добавлена, но не видна на управляемой форме?

На управляемой форме колонка данных и элемент отображения — разные сущности. Нужно не только добавить реквизит через ИзменитьРеквизиты(), но и создать элемент формы: Элементы.Добавить(ИмяЭлемента, Тип("ПолеФормы"), РодительТаблица), установить ПутьКДанным вида «ДеревоДанных.ИмяКолонки» и при необходимости Вид = ВидПоляФормы.ПолеВвода.

Как добавить колонку с флажком (булево) в дерево?

Укажите тип Новый ОписаниеТипов("Булево") при добавлении колонки. На форме платформа автоматически отобразит такую колонку как флажок, если вид поля не переопределён. Для трёхсостоящих флажков в иерархии логику согласования значений родителя и подчинённых строк нужно программировать вручную в обработчике «ПриИзменении».

Чем добавление колонки в дерево отличается от добавления в таблицу значений?

Синтаксис идентичен: у обоих объектов есть коллекция Колонки с методом Добавить(Имя, Тип, Заголовок, Ширина). Различие только в структуре строк: у дерева строки образуют иерархию через вложенные коллекции Строки, а у таблицы — плоский список. Методы работы с колонками переносятся между объектами без изменений.

Можно ли изменить тип уже существующей колонки?

Да, через свойство ТипЗначения объекта колонки: Дерево.Колонки.Найти("Сумма").ТипЗначения = Новый ОписаниеТипов("Число"). Учтите, что значения, уже записанные в строки, при несовместимости с новым типом будут приведены к значению по умолчанию, поэтому менять тип безопаснее до заполнения дерева данными.

Итог

Что важно запомнить

Колонка добавляется методом Дерево.Колонки.Добавить() с именем, типом и заголовком. Для управляемой формы дополнительно нужны ИзменитьРеквизиты() и создание элемента формы. Перед повторным добавлением проверяйте наличие колонки, а типы задавайте явно — это избавит от ошибок обращения и проблем с сортировкой.