Динамический вывод таблицы значений на форму

Программирование - Работа с интерфейсом

таблица значений

31
Вывести на форму таблицу значений, а потом на её место другую, третью, четвёртую? Не вопрос.

Возможно, это уже где-то было, но мне не попалось.

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

В итоге получилась такая штука, в которую можно раз за разом пихать разные ТЗ, и она будет их показывать.

В реквизитах формы в конфигураторе заранее создаётся таблица значений ТабРеквизит и вытаскивается на форму на необходимое место под именем ТабЭлементФормы (если имя совпадает с ТабРеквизит, как обычно и бывает, в параметрах процедуры его можно не указывать).

Процедура удаляет (если они были) уже имеющиеся программно созданные (возможно, этой же процедурой) элементы формы из ТабЭлементФормы  с реквизитами, в которых хранились выводимые значения. На основании переданной ТаблицаЗначений формируются новые реквизиты, которые в последнем цикле привязываются к вновь создаваемым элементам формы. Осталось заполнить ТабРеквизит данными из ТаблицаЗначений ,что и происходит в предпоследней строчке. На этом всё. Готово. Конец процедуры.


&НаСервере
Процедура ВывестиТаблицуЗначенияВТаблицуНаФорме(ТаблицаЗначений, ТабРеквизит, ТабЭлементФормы = Неопределено)
	Если ТабЭлементФормы = Неопределено Тогда
		ТабЭлементФормы = ТабРеквизит;
	КонецЕсли; 
	
	// Собирается инофрмация по добавленным ранее элементам формы и реквизитам, на которые элементы формы ссылаются.
	УдаляемыеРеквизиты = Новый Массив;
	УдаляемыеЭлементы = Новый Массив;
	Для каждого Эл Из Элементы[ТабЭлементФормы].ПодчиненныеЭлементы Цикл
		УдаляемыеРеквизиты.Добавить(Эл.ПутьКДанным);
		УдаляемыеЭлементы.Добавить(Эл);
	КонецЦикла; 
	Для каждого Эл Из УдаляемыеЭлементы Цикл
		Элементы.Удалить(Эл);
	КонецЦикла; 
	
	// Добавляются колонки из ТаблицыЗначений в реквизит таблицы ТабРеквизит
	НовыеРеквизиты = Новый Массив;
	Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
		НовыйРеквизит = Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, ТабРеквизит, Колонка.Заголовок);
	   	НовыеРеквизиты.Добавить(НовыйРеквизит);
	КонецЦикла;

    //Удаляются старые и устанавливаются новые реквизиты
	ИзменитьРеквизиты(НовыеРеквизиты, УдаляемыеРеквизиты);
	
    // Добавляются колонки из ТаблицыЗначений в элементы ТабЭлементФормы со ссылкой на колонки в ТабРеквизит
    Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
        НовыйЭлемент = Элементы.Добавить( ТабРеквизит + "_" + Колонка.Имя, Тип("ПолеФормы"), Элементы[ТабЭлементФормы]);
        НовыйЭлемент.Вид = ВидПоляФормы.ПолеНадписи; //Или ПолеВвода, или что-то другое;
        НовыйЭлемент.ПутьКДанным = ТабРеквизит + "." + Колонка.Имя;
    КонецЦикла;
 
 	// В созданный реквизит загружается ТЗ
	ЭтаФорма[ТабРеквизит].Загрузить(ТаблицаЗначений);
КонецПроцедуры

 

31

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. AnderWonder 22 13.01.19 11:06 Сейчас в теме
А зачем ИзменитьРеквизиты вызывается два раза, если можно один?
ИзменитьРеквизиты(НовыеРеквизиты, УдаляемыеРеквизиты)
Vlad1917; +1 Ответить
6. Vlad1917 31 14.01.19 11:58 Сейчас в теме
(1) Думал, что будут проблемы при выводе новых реквизитов, аналогичных удаляемым. Проверил - действительно, так работает и с совпадающими реквизитами. Исправил. Спасибо за замечание.
2. Vlad1917 14.01.19 01:08 Сейчас в теме
Чтоб не получилось, что я одновременно и удаляю, и добавляю аналогичный реквизит. Например, при выводе ТЗ одинаковой структуры с предыдущей.
5. vitkhv 14.01.19 10:25 Сейчас в теме
(2) Вообще-то ИзменитьРеквизиты очень дорогая операция, поэтому вызывать ее два раза совсем не комильфо.
3. starik-2005 1586 14.01.19 08:43 Сейчас в теме
О, это было много раз! Давай ышо!
7. Vlad1917 31 14.01.19 12:19 Сейчас в теме
(3)Был бы признателен за ссылку на аналогичную статью на Инфостарте, где подробно написано про удаление старых и создание новых элементов и реквизитов ТЗ, сразу про оба этих момента. Ну так, чисто поржать над собой - мол, вот я чайник, велосипед-то уже давно изобрели. С такой ссылкой Ваш, без сомнения, поражающий своей информативностью комментарий был бы ещё информативнее.
А если получится дать МНОГО таких ссылок на Инфостарт (согласен считать что две - это много), то готов под Н-ным (по количеству приведённых ссылок) количеством Ваших постов написать - "да, этот человек знает, о чём говорит!". ;)
9. starik-2005 1586 14.01.19 14:16 Сейчас в теме
(7)
где подробно написано про удаление старых и создание новых элементов и реквизитов ТЗ
Фактически, искомая инфа есть во втором комментарии здесь: https://infostart.ru/public/574802/
logarifm; +1 Ответить
10. Vlad1917 31 14.01.19 17:04 Сейчас в теме
(9) Несомненно, Ваша фраза из второго комментария к Вашей статье "лучше полностью сносить таблицу и создавать новую, чем заморачиваться изменениями колонок - пользы чуть, а геморроя - масса." гораздо полнее и лучше раскрывает решение вопроса, который стоял передо мной (и, возможно, возникнет у кого-то ещё), чем способ, который я предложил. Вероятно, мне стоит согласиться с тем, что в статье, написанной мною, вместо кучи бессмысленного текста было бы достаточно привести ссылку на Вашу всеобъемлющую статью.
Но всё же я так не думаю.
Хотя спасибо Вам. Начинаю гордиться собой. Меньше, чем 30 строчек кода, оказывается, не только могут вывести разные ТЗ на форму, но и справиться с "массой геморроя"! :)
klinval; yufan; user609766_deltainform; +3 Ответить
11. starik-2005 1586 14.01.19 17:44 Сейчас в теме
(10)
Меньше, чем 30 строчек кода, оказывается, не только могут вывести разные ТЗ на форму, но и справиться с "массой геморроя"!
В девстве, помню, консоль запросов делал на УФ - ровно 30 строк занял вывод результата запроса в форму (с учетом изменившихся реквизитов). Но это по-молодости. Сейчас все в 10 строк умещается.
12. Vlad1917 31 14.01.19 18:36 Сейчас в теме
(11) Вот вырасту, и у меня вывод ТЗ будет занимать пару строчек. А пока ещё маленький, так что мне 30 простительно. :)
Дамир1; +1 Ответить
4. azhilichev 148 14.01.19 10:15 Сейчас в теме
Программное создание элементов формы после события ПриСозданииНаСервере() очень дорогая операция. Точно так же программное создание и удаление реквизитов управляемой формы. Пруфы: Синтаксис-помощник, Программное изменение формы.

Форма не рождается на клиенте. Форма рождается на сервере, она проходит несколько важных стадий предварительной обработки, прежде чем достичь глаз пользователя. Платформа содержит достаточно сложные механизмы многоуровневого кеширования различных частей формы как на сервере, так и на клиенте.

По этой причине возможность программного изменения формы является скорее опциональной, дополнительной. Она рассчитана на отдельные конкретные сценарии работы и не предполагает массового использования в большом количестве форм конфигурации или в часто используемых формах. Основным подходом при разработке прикладных решений должно являться визуальное конструирование форм в конфигураторе. А программное изменение форм рекомендуется использовать лишь в отдельных специфических сценариях работы.


Внимание! Действия добавления и удаления выполняются за один вызов. Следует учитывать, что операция изменения состава реквизитов является ресуркоемкой, поэтому операции изменения состава реквизитов формы выполняются пакетным образом.
8. Vlad1917 31 14.01.19 13:18 Сейчас в теме
(4) Из Вашего же пруфа: "Такими сценариями могут быть, например, отображение в форме имеющихся типовых операций или характеристик объектов. То есть той информации, которая содержится в базе данных и структура которой неизвестна на этапе конфигурирования. Ее можно узнать только уже в процессе функционирования прикладного решения, в режиме 1С:Предприятие. Поэтому для ее отображения в форме и требуется ее программное изменение."

Нужно было выводить и обрабатывать загружаемые xls файлы, в которых верхняя строка - название колонок, остальные строки - данные. Количество колонок, название и смысловая информация различные в различных файлах. Думаю, это тот самый случай. :)
13. azhilichev 148 15.01.19 04:34 Сейчас в теме
(8) Основной посыл: динамическое создание реквизитов и элементов формы - дорогая операция.
16. Vlad1917 31 16.01.19 15:39 Сейчас в теме
(13) Хорошо, не буду спорить.
Посоветуйте, пожалуйста, как задёшево решить эту часть задания заказчика, в котором надо выводить на форму ТЗ, с учётом того, что структура её и данных заранее неизвестна. Вариант "убедить заказчика, что ему это не надо" не предлагать. :)
19. azhilichev 148 18.01.19 04:12 Сейчас в теме
(16) Используйте табличный документ.
14. PerlAmutor 33 15.01.19 06:28 Сейчас в теме
(0)
НовыйРеквизит = Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, ТабРеквизит, Колонка.Заголовок);


Эту строку нужно доработать. Уже столкнулся с этим на практике. Есть типы полей, которые приемлемы в ТЗ, но никак не в реквизите формы. Например Null или МоментВремени. В первом случае у вас будет платформа выдавать странную ошибку при попытке поиска чего-либо в такой таблице. Во втором - платформа сразу выдаст ошибку при добавлении. Ошибки такого рода коварны тем, что в какой-то момент начинаешь готовый код по отображению ТЗ на форме переносить в другие задачи, где таблицы значений могут быть самыми разнообразными и потом удивляться почему все перестало работать.
Vlad1917; +1 Ответить
18. Vlad1917 31 16.01.19 16:22 Сейчас в теме
(14)Спасибо. Надо будет подумать, как учесть это.
15. json 2029 15.01.19 07:51 Сейчас в теме
Почитал комментарии, многие написали, что ИзменитьРеквизиты() - это дорогая операция.
Понятно, что это взято из документации, и многие даже не задумывались, что это значит.

Мне бы хотелось узнать мнение практиков, а не теоретиков. В чем именно выражается эта дороговизна?

Я в нескольких проектах использовал этот метод. Всегда все работало быстро. Никаких задержек не ощущалось.

При каких условиях начинает проявляться эта дороговизна? Было бы интересно прочитать подробности из личного опыта
coollerinc; +1 Ответить
17. Vlad1917 31 16.01.19 16:19 Сейчас в теме
(15)
Экселевская таблица 5.200 строк 22 колонки. Её загрузка и первичная обработка занимает порядка минуты, включая и процесс засовывания в ТЗ и вывода этой ТЗ на экран (внизу скрина как раз оно).
Непосредственно процедура, которую я привёл, занимает, если верить замеру производительности... ммм... нисколько. :)
Т. е. на фоне всего остального - ни о чём.

20. azhilichev 148 18.01.19 04:15 Сейчас в теме
(15) Когда эта операция выполняется у бОльшего количества пользователей. В моей практике > 100.

В чем именно выражается эта дороговизна?


Отрисовка формы. Нагрузка на сервер.
21. json 2029 18.01.19 08:42 Сейчас в теме
(20) Ну если больше 100 пользователей, то там могут быть любые причины торможения. Как определили, что причина именно в методе ИзменитьРеквизиты()?
Ведь если такое количество пользователей, то там и функционала, наверное тоже довольно много, и должно быть полно и других методов, которые тормозят.

Изменение реквизитов делается менее чем за секунду. Это нужно, чтобы ваши 100 пользователей очень часто выполняли эту операцию. Причем замедление возможно было при динамическом изменении ЭЛЕМЕНТОВ формы, а не РЕКВИЗИТОВ.
22. azhilichev 148 18.01.19 08:45 Сейчас в теме
(21) Счетчики, замер производительности, технологический журнал. Все по-взрослому.
23. json 2029 18.01.19 08:52 Сейчас в теме
(22) ну по счетчикам вы это не определите, т.к. они только показывают серверные вызовы. Ведь и так понятно, что эта операция выполняется на сервере.

В замере тоже очень мало вероятно, чтобы эта операция вылезла в топ. Если только она не выполнялась в цикле по 50 раз.

По поводу тех. журнала - ответ расплывчатый.

Ну да ладно...
24. azhilichev 148 18.01.19 09:35 Сейчас в теме
(23)
ну по счетчикам вы это не определите, т.к. они только показывают серверные вызовы.

Программные счетчики.

По поводу тех. журнала - ответ расплывчатый.

Устанавливаете стек ELK и анализируете тех. журнал.

В замере тоже очень мало вероятно, чтобы эта операция вылезла в топ.

Почему маловероятно? Просто представьте, что документ не делает движений.
25. json 2029 18.01.19 09:40 Сейчас в теме
(24)
Вы пытаетесь меня уличить?

нет

Программные счетчики.

для себя интересно - можно поподробнее? Не в контексте нашего вопроса
26. json 2029 18.01.19 09:46 Сейчас в теме
(24) (25)
понял, наверное программные счетчики типа этого:
НачВремя = ТекущаяДата();
ДолгаяПроцедура();
КонВремя = ТекущаяДата();
ЗафиксироватьЗамерКудаНадо(НачВремя, КонВремя, "ДолгаяПроцедура");


и вопрос:
в БСП же ИзменитьРеквизиты() на каждом шагу, вроде. Они там доп. реквизиты добавляют.
Удалось с этим что-нибудь сделать?
Оставьте свое сообщение