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

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

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

Почему не удается добавить поле стандартным способом?

Проанализируем архитектуру динамического списка в платформе 1С:Предприятие 8.3:

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

Таким образом, автор темы совершенно прав в своих опасениях: без включения произвольного запроса добавить произвольное поле программно невозможно.

Способ 1. Программный перевод динамического списка на произвольный запрос

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

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

Разберем реализацию по шагам:

  1. Включаем свойство ПроизвольныйЗапрос = Истина.
  2. Формируем текст запроса, где к стандартной таблице журнала добавляем пустое строковое поле с явным ограничением длины через функцию ВЫРАЗИТЬ.
  3. Критически важно: обязательно явно заполняем свойство ОсновнаяТаблица. Если его не указать, платформа отключит динамическое считывание данных порциями, перестанут отображаться стандартные пиктограммы проведения и пропадут стандартные команды управления документами.
  4. Создаем элемент управления на форме и привязываем его к новому полю списка.

Посмотрим на пример программного кода:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // 1. Включаем режим произвольного запроса
    Список.ПроизвольныйЗапрос = Истина;
    
    // 2. Указываем текст запроса с добавлением строкового литерала
    Список.ТекстЗапроса = 
        "ВЫБРАТЬ
        |	Журнал.Ссылка КАК Ссылка,
        |	Журнал.Дата КАК Дата,
        |	Журнал.Номер КАК Номер,
        |	Журнал.ПометкаУдаления КАК ПометкаУдаления,
        |	Журнал.Проведен КАК Проведен,
        |	ВЫРАЗИТЬ("""" КАК СТРОКА(150)) КАК ПроизвольныйТекст
        |ИЗ
        |	ЖурналДокументов.СкладскиеОрдера КАК Журнал";
        
    // 3. Сохраняем основную таблицу для динамического считывания данных
    Список.ОсновнаяТаблица = "ЖурналДокументов.СкладскиеОрдера";
    
    // 4. Программно создаем колонку в таблице формы
    ТаблицаСписка = Элементы.Список;
    НоваяКолонка = Элементы.Добавить("СписокПроизвольныйТекст", Тип("ПолеФормы"), ТаблицаСписка);
    НоваяКолонка.Вид = ВидПоляФормы.ПолеНадписи;
    НоваяКолонка.ПутьКДанным = "Список.ПроизвольныйТекст";
    НоваяКолонка.Заголовок = "Дополнительная информация";
    
КонецПроцедуры

Способ 2. Заполнение колонки расчетными данными через событие «ПриПолученииДанныхНаСервере»

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

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

Разберем особенности этого обработчика:

  1. Обработчик является внеконтекстным (директива &НаСервереБезКонтекста), благодаря чему выполняется максимально быстро.
  2. Он вызывается платформой порционно — исключительно для тех строк, которые в данный момент видны пользователю на экране монитора.
  3. Заполнение данных выполняется непосредственно через коллекцию Строки.

Посмотрим на пример реализации обработчика:


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

Обратите внимание на важное ограничение: пользователь не сможет настроить платформенный отбор, группировку или сортировку по значениям, сформированным в событии ПриПолученииДанныхНаСервере, поскольку СУБД применяет фильтры на уровне выполнения SQL-запроса еще до передачи порции данных в интерфейс.

Альтернативные варианты решения задачи

Если нет необходимости переписывать запрос списка программным кодом, рассмотрим два альтернативных пути:

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