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