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