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