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