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