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