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