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

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

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

Постановка задачи и начальные условия

Представим ситуацию: в основную конфигурацию (например, 1С:ITIL или любую другую типовую систему) были добавлены новые реквизиты в документ (например, ЧисловойПриоритет и КрайнийСрок). Теперь нам нужно вывести их в форму списка через расширение, при этом программно модифицируя состав колонок. Мы хотим избежать визуального изменения формы в расширении, чтобы минимизировать проблемы при будущих обновлениях.

Для решения этой задачи нам потребуется выполнить три основных шага:

  1. Модифицировать текст запроса динамического списка.
  2. Программно создать элементы формы (колонки).
  3. Связать созданные элементы с данными запроса.

Шаг 1: Программная модификация текста запроса

Первым делом проанализируем, как добавить новые поля в запрос динамического списка. Обычно это делается в обработчике события ПриСозданииНаСервере. Мы будем использовать метод СтрЗаменить, чтобы внедрить наши поля в существующий список выборки ВЫБРАТЬ.

Рассмотрим пример кода, который внедряет новые реквизиты:


&НаСервере
Процедура ДобавитьПоляВЗапрос()
    // Получаем текущий текст запроса
    ТекстЗапроса = Список.ТекстЗапроса;
    
    // Добавляем новые поля через замену существующего фрагмента
    // Важно найти уникальный фрагмент, чтобы замена прошла корректно
    НовыйТекст = СтрЗаменить(ТекстЗапроса, 
        "itilprofИнциденты.КодЗавершения,", 
        "itilprofИнциденты.КодЗавершения, itilprofИнциденты.ЧисловойПриоритет, itilprofИнциденты.КрайнийСрок, ");
    
    Список.ТекстЗапроса = НовыйТекст;
КонецПроцедуры

Важный нюанс: Если в основной конфигурации динамический список имеет включенное свойство Автозаполнение, платформа может подхватить новые поля автоматически. Однако для полной уверенности и возможности управления порядком полей, ручная правка запроса является более надежной.

Шаг 2: Программное создание колонок на форме

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

Проанализируем процедуру создания элементов:


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

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

Шаг 3: Выяснение причины пустых колонок

Бывают случаи, когда код написан верно, отладчик показывает наличие данных в объекте Список (в коллекции Данные), но на экране пользователь видит пустоту. Рассмотрим причины, по которым это может происходить:

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

Решение проблемы с перезаписью запроса

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

Выясним причину на конкретном примере. Если в коде формы основной конфигурации в процедуре ПриОткрытии стоит жесткое присваивание:

Список.ТекстЗапроса = "ВЫБРАТЬ ... ";

...то любые ваши манипуляции в ПриСозданииНаСервере окажутся бесполезными. В этом случае правильный алгоритм действий будет следующим:


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

    // Проверяем наличие колонок, чтобы не создать дубли при повторном вызове
    Если Элементы.Найти("СписокЧисловойПриоритет") = Неопределено Тогда
        // Код создания элементов формы...
    КонецЕсли;
КонецПроцедуры

Дополнительные инструменты: БСП и УстановитьСвойстваДинамическогоСписка

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

Рассмотрим использование метода ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка. Этот метод помогает правильно инициализировать список после изменения его текста запроса или основной таблицы:


&НаСервере
Процедура ОбновитьСвойстваСписка()
    СвойстваСписка = ОбщегоНазначения.СтруктураСвойствДинамическогоСписка();
    СвойстваСписка.ТекстЗапроса = Список.ТекстЗапроса;
    СвойстваСписка.ОсновнаяТаблица = "Документ.itilprofИнциденты";
    СвойстваСписка.ДинамическоеСчитываниеДанных = Истина;
    
    ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(Элементы.Список, СвойстваСписка);
КонецПроцедуры

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

Резюмируем: Для стабильного отображения программных колонок в расширении всегда проверяйте, в какой момент и как модифицируется ТекстЗапроса. Если данные есть в отладке, но их нет на форме — ищите место, где платформа или программный код основной конфигурации перекрывает ваши настройки. Используйте аннотацию &После для событий, выполняющихся позже всего в жизненном цикле формы, и не забывайте связывать элементы через ПутьКДанным.

← На главную