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

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

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

Понимаем природу Динамического Списка

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

Динамический список — это механизм, который самостоятельно обращается к базе данных, порционно считывает информацию и отображает её. Если мы напишем в коде Запрос.Выполнить(), мы получим данные в памяти сервера, но наш список на форме об этом ничего не узнает. Чтобы добавить колонку в список, мы должны изменить инструкцию, по которой этот список работает, то есть его ТекстЗапроса.

Шаг 1. Модификация запроса динамического списка

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

Чтобы добавить свое поле, нам необходимо вмешаться в этот процесс. Рассмотрим, как это сделать правильно. Вместо создания нового запроса, мы должны обратиться к основной таблице формы (обычно она называется Список).

Пример неправильного подхода (как делать не надо):


// Это ошибка! Этот код никак не повлияет на отображение списка
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ..."; 
Результат = Запрос.Выполнить();

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Добавляем новое поле в текст запроса
    // Важно: убедитесь, что синтаксис запроса позволяет просто заменить строку
    ТекстЗапроса = Список.ТекстЗапроса;
    ТекстЗапроса = СтрЗаменить(ТекстЗапроса, 
                               "ВЫБРАТЬ", 
                               "ВЫБРАТЬ ДополнительнаяТаблица.НужноеПоле КАК МояНоваяКолонка,");
    
    // Если нужно добавить соединение
    ТекстЗапроса = ТекстЗапроса + " 
    | ЛЕВОЕ СОЕДИНЕНИЕ Справочник.НовыйСправочник КАК ДополнительнаяТаблица 
    | ПО ...";
    
    Список.ТекстЗапроса = ТекстЗапроса;

КонецПроцедуры

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

Шаг 2. Программное создание элемента формы

Даже если мы изменили текст запроса и поле МояНоваяКолонка появилось в наборе данных списка, платформа не всегда автоматически выводит его на форму, особенно если мы модифицируем форму программно или через внешнюю обработку. Нам нужно явно сказать платформе: "Создай элемент управления для этого поля".

Используем коллекцию Элементы. Рассмотрим универсальный код добавления колонки:


// Создаем новый элемент формы
// 1-й параметр: Уникальное имя элемента на форме
// 2-й параметр: Тип элемента (Поле формы)
// 3-й параметр: Родитель (в данном случае сама таблица списка)
НовыйЭлемент = Элементы.Добавить("МояНоваяКолонка", Тип("ПолеФормы"), Элементы.Список);

// Связываем визуальный элемент с данными запроса
// Важно: ПутьКДанным должен точно совпадать с Алиасом поля в запросе
НовыйЭлемент.ПутьКДанным = "Список.МояНоваяКолонка";

// Настраиваем внешний вид
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода; // Или ПолеНадписи
НовыйЭлемент.Заголовок = "Название колонки для пользователя";

Обратите внимание на свойство ПутьКДанным. Оно строится по принципу ИмяРеквизитаДанных.ИмяПоля. Для динамического списка это обычно Список.ИмяПоляВЗапросе.

Шаг 3. Проблема "Кеша" и пользовательских настроек

Очень часто разработчики делают все правильно в коде, но колонка все равно не появляется. Причина кроется в механизме сохранения пользовательских настроек 1С. Если вы хотя бы раз открывали эту форму ранее, платформа запомнила состав колонок, который был на тот момент. Новая колонка считается "скрытой" или "несуществующей" в сохраненной настройке.

Разберем способы решения этой проблемы:

  1. В режиме Предприятия: Откройте форму списка. Нажмите кнопку "Ещё" (обычно в правом верхнем углу списка) -> "Установить стандартные настройки". Это сбросит кеш текущего пользователя и заставит форму перечитать структуру метаданных.
  2. Проверка видимости: Там же в меню "Ещё" выберите "Изменить форму". Проверьте, появилась ли ваша новая колонка в дереве элементов и установлена ли напротив нее галочка видимости.
  3. Свойство "Использовать всегда": Если колонка нужна вам для каких-то внутренних вычислений или условного оформления, но не обязательно должна быть видна пользователю, в конфигураторе в настройках Динамического Списка для этого поля установите флаг Использовать всегда. Иначе оптимизатор запросов 1С может просто не включать это поле в выборку SQL, если оно не выведено на экран.

Особенности передачи параметров

В теме также обсуждался вопрос фильтрации данных. Если вы добавляете в запрос параметры (например, &Менеджер), не забудьте установить их значение для самого списка. Установка параметров для объекта Запрос, как мы выяснили ранее, не поможет.

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


// Получаем значение параметра (например, текущего пользователя)
ТекущийПользователь = Пользователи.ТекущийПользователь();

// Устанавливаем параметр в структуру параметров списка
Список.Параметры.УстановитьЗначениеПараметра("Менеджер", ТекущийПользователь);

Рекомендации по коду (Best Practices)

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


// Плохо: жесткая привязка к коду
НД_Инструменты = Справочники.ЮТ_ОсновныеНаправленияДеятельности.НайтиПоКоду("000000003");

Вместо этого используйте:

Итог

Для успешного добавления колонки во внешней обработке:

  1. Изменяйте свойство Список.ТекстЗапроса, а не создавайте новый запрос.
  2. Программно добавляйте элемент через Элементы.Добавить() с правильным ПутьКДанным.
  3. Не забывайте сбрасывать пользовательские настройки формы ("Ещё" - "Установить стандартные настройки") для проверки результата.
← На главную