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