Как программно добавить колонку в динамический список и почему она может оставаться пустой

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Анализ исходной проблемы

Представим ситуацию: в конфигурацию (или через расширение) добавлены новые реквизиты объекта, например, ЧисловойПриоритет и КрайнийСрок. Нам необходимо вывести их в форму списка документа. Разработчик использует стандартный подход — в процедуре ПриСозданииНаСервере модифицирует текст запроса динамического списка и программно создает элементы формы.

Типичный код добавления колонок выглядит следующим образом:


// Модификация текста запроса
Список.ТекстЗапроса = СтрЗаменить(Список.ТекстЗапроса, 
    "itilprofИнциденты.КодЗавершения,", 
    "itilprofИнциденты.КодЗавершения, itilprofИнциденты.ЧисловойПриоритет, itilprofИнциденты.КрайнийСрок, ");

// Программное создание элементов формы (колонок)
НоваяКолонка = Элементы.Вставить("ЧисловойПриоритет", Тип("ПолеФормы"), Элементы.Список, Элементы.ТекущийИсполнитель);
НоваяКолонка.ПутьКДанным = "Список.ЧисловойПриоритет";
НоваяКолонка.Заголовок = "Приоритет (Ч)";
НоваяКолонка.Вид = ВидПоляФормы.ПолеНадписи;

НоваяКолонка = Элементы.Вставить("КрайнийСрок", Тип("ПолеФормы"), Элементы.Список, Элементы.ТекущийИсполнитель);
НоваяКолонка.ПутьКДанным = "Список.КрайнийСрок";
НоваяКолонка.Заголовок = "Крайний срок";
НоваяКолонка.Вид = ВидПоляФормы.ПолеНадписи;

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

Причина 1: Переопределение запроса в типовом коде

Это самая распространенная причина. В типовых конфигурациях 1С (особенно в сложных решениях на базе БСП) текст запроса динамического списка может формироваться динамически не только в ПриСозданииНаСервере, но и в процедуре ПриОткрытии на стороне клиента или в сопутствующих серверных вызовах.

Суть проблемы: Вы успешно изменили Список.ТекстЗапроса в обработчике ПриСозданииНаСервереПосле, но затем выполняется типовой код процедуры ПриОткрытии, который полностью перезаписывает свойство ТекстЗапроса, не учитывая ваши правки. В итоге структура колонок на форме есть, а данных в источнике (динамическом списке) для этих колонок уже нет.

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

Причина 2: Использование строковых замен (СтрЗаменить)

Использование функции СтрЗаменить для модификации запросов — метод быстрый, но крайне ненадежный. Если в запросе изменятся пробелы, регистр букв или добавятся новые поля, ваша замена может просто не сработать.

Рассмотрим более профессиональный подход с использованием объекта СхемаЗапроса. Этот метод позволяет гарантированно добавить поля в выборку, не ломая синтаксис запроса.


Схема = Новый СхемаЗапроса;
Схема.УстановитьТекстЗапроса(Список.ТекстЗапроса);

ЗапросВыбора = Схема.ПакетЗапросов[0]; // Обычно ДС содержит один запрос
ВыбираемыеПоля = ЗапросВыбора.ВыбираемыеПоля;

// Добавляем поле, если его еще нет в списке
Если ВыбираемыеПоля.Найти("ЧисловойПриоритет") = Неопределено Тогда
    ВыбираемыеПоля.Добавить("itilprofИнциденты.ЧисловойПриоритет");
КонецЕсли;

Список.ТекстЗапроса = Схема.ПолучитьТекстЗапроса();

Причина 3: Оптимизация платформы и "Используемые поля"

Платформа 1С оптимизирует работу с данными. Если поле добавлено в запрос, но система считает, что оно не отображается или не нужно для работы, она может исключить его из выборки. Чтобы этого избежать, особенно при программном выводе данных, рекомендуется принудительно указывать поле как используемое.

Проанализируем коллекцию КомпоновщикНастроек.Настройки.Выбор. Поля, добавленные туда, платформа будет обязана получить из базы данных.


ВыбранноеПоле = Список.КомпоновщикНастроек.Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных("ЧисловойПриоритет");
ВыбранноеПоле.Использование = Истина;

Причина 4: Пользовательские настройки формы

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

Решение: При отладке и первом внедрении кода обязательно выполните команду "Установить стандартные настройки" (через меню "Еще" в форме списка). Это сбросит кэш настроек и позволит форме отобразить элементы так, как прописано в вашем коде.

Пошаговый алгоритм правильного добавления колонки

  1. Определяем точку входа: Если типовая конфигурация не меняет запрос динамически, используем ПриСозданииНаСервере. Если меняет — ищем финальную точку инициализации (часто это ПриОткрытии или специализированные процедуры инициализации списка).
  2. Модифицируем текст запроса: Используем СхемаЗапроса для безопасного добавления полей или (в простых случаях) СтрЗаменить, убедившись в точном совпадении подстроки.
  3. Создаем элемент формы: Используем Элементы.Вставить() или Элементы.Добавить(). Метод Вставить предпочтительнее, так как позволяет указать позицию новой колонки относительно существующих.
  4. Связываем данные: Обязательно указываем ПутьКДанным в формате ИмяДинамическогоСписка.ИмяПоляЗапроса.
  5. Устанавливаем вид поля: Для списков просмотра рекомендуется ВидПоляФормы.ПолеНадписи. Это повышает производительность интерфейса.
  6. Проверяем права доступа: Убедитесь, что у пользователя есть право "Просмотр" на добавляемые реквизиты, иначе данные в колонке будут пустыми по соображениям безопасности.

Рассмотрим пример правильной реализации в расширении для процедуры ПриОткрытии:


&НаКлиенте
Процедура Имя_ПриОткрытииПосле(Отказ)
    
    // Вызываем серверный метод для модификации списка
    ПодключитьКолонкиНаСервере();
    
КонецПроцедуры

&НаСервере
Процедура ПодключитьКолонкиНаСервере()
    
    // Проверяем, не добавлены ли уже колонки (чтобы избежать дублей при повторном открытии)
    Если Элементы.Найти("ЧисловойПриоритет") <> Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // 1. Правим текст запроса
    Текст = Список.ТекстЗапроса;
    Если Найти(Текст, "ЧисловойПриоритет") = 0 Тогда
        Список.ТекстЗапроса = СтрЗаменить(Текст, "ВЫБРАТЬ", "ВЫБРАТЬ Инциденты.ЧисловойПриоритет КАК ЧисловойПриоритет, ");
    КонецЕсли;
    
    // 2. Создаем колонку
    НоваяКолонка = Элементы.Вставить("ЧисловойПриоритет", Тип("ПолеФормы"), Элементы.Список);
    НоваяКолонка.ПутьКДанным = "Список.ЧисловойПриоритет";
    НоваяКолонка.Заголовок = "Приоритет";
    НоваяКолонка.Вид = ВидПоляФормы.ПолеНадписи;
    
КонецПроцедуры

Выясним еще один важный момент: Основная таблица. Если в динамическом списке свойство ОсновнаяТаблица заполнено, платформа автоматически подтягивает поля этой таблицы. Но если вы добавляете вычисляемые поля или поля из других таблиц через ЛЕВОЕ СОЕДИНЕНИЕ, программная модификация текста запроса становится строго обязательной.

Следуя этим рекомендациям и учитывая порядок выполнения событий в расширениях 1С, мы сможем гарантировать стабильное отображение данных в динамических списках любого уровня сложности.

← На главную