При разработке интерфейсов на управляемых формах нередко возникает задача вывести в список документов дополнительную расчетную или поясняющую информацию. Когда динамический список привязан к конкретному журналу документов без произвольного запроса, разработчики сталкиваются с ограничением платформы: просто так добавить произвольную колонку на форму не удается. Выясним причину такого поведения платформы 1С и подробно разберем по шагам правильные способы реализации этой задачи.
Проанализируем архитектуру динамического списка в платформе 1С:Предприятие 8.3:
ИзменитьРеквизиты(). В отличие от таблиц значений или табличных частей объектов, динамический список не позволяет добавлять вложенные реквизиты формы программно через вызов ИзменитьРеквизиты(). Попытка указать путь вроде "Список.НовоеПоле" приведет к ошибке платформы «Недопустимый путь к реквизиту». Состав полей динамического списка всегда жестко определяется либо полями его таблицы метаданных, либо полями выборки SQL-запроса.ПроизвольныйЗапрос выключено (установлено в Ложь), список считывает исключительно метаданные журнала: его стандартные реквизиты (Ссылка, Дата, Номер, Проведен и т. д.), графы журнала и общие реквизиты. Произвольных полей «из ниоткуда» в метаданных существовать не может.ПолеФормы обязательно должен быть привязан через свойство ПутьКДанным к реально существующему полю динамического списка, иначе платформа не сможет отобразить данные в строках.Таким образом, автор темы совершенно прав в своих опасениях: без включения произвольного запроса добавить произвольное поле программно невозможно.
Рассмотрим основной и самый надежный способ. Мы программно переведем динамический список в режим произвольного запроса, добавим поле-заглушку с нужным типом и создадим для него элемент интерфейса.
Выполнять эти действия необходимо на сервере при инициализации формы — в обработчике ПриСозданииНаСервере.
Разберем реализацию по шагам:
ПроизвольныйЗапрос = Истина.ВЫРАЗИТЬ.ОсновнаяТаблица. Если его не указать, платформа отключит динамическое считывание данных порциями, перестанут отображаться стандартные пиктограммы проведения и пропадут стандартные команды управления документами.Посмотрим на пример программного кода:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// 1. Включаем режим произвольного запроса
Список.ПроизвольныйЗапрос = Истина;
// 2. Указываем текст запроса с добавлением строкового литерала
Список.ТекстЗапроса =
"ВЫБРАТЬ
| Журнал.Ссылка КАК Ссылка,
| Журнал.Дата КАК Дата,
| Журнал.Номер КАК Номер,
| Журнал.ПометкаУдаления КАК ПометкаУдаления,
| Журнал.Проведен КАК Проведен,
| ВЫРАЗИТЬ("""" КАК СТРОКА(150)) КАК ПроизвольныйТекст
|ИЗ
| ЖурналДокументов.СкладскиеОрдера КАК Журнал";
// 3. Сохраняем основную таблицу для динамического считывания данных
Список.ОсновнаяТаблица = "ЖурналДокументов.СкладскиеОрдера";
// 4. Программно создаем колонку в таблице формы
ТаблицаСписка = Элементы.Список;
НоваяКолонка = Элементы.Добавить("СписокПроизвольныйТекст", Тип("ПолеФормы"), ТаблицаСписка);
НоваяКолонка.Вид = ВидПоляФормы.ПолеНадписи;
НоваяКолонка.ПутьКДанным = "Список.ПроизвольныйТекст";
НоваяКолонка.Заголовок = "Дополнительная информация";
КонецПроцедуры
Если произвольный текст нельзя жестко зашить в запрос (например, он зависит от сложных внешних функций, проверок или данных других не связанных регистров), рассмотрим механизм постобработки строк.
Для этого мы оставляем добавленное в запросе поле ПроизвольныйТекст в качестве буфера (как в Способе 1), а саму генерацию текста переносим в событие таблицы списка ПриПолученииДанныхНаСервере.
Разберем особенности этого обработчика:
&НаСервереБезКонтекста), благодаря чему выполняется максимально быстро.Строки.Посмотрим на пример реализации обработчика:
&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
Для Каждого КлючИСтрока Из Строки Цикл
СтрокаСписка = КлючИСтрока.Значение;
// Получаем ссылку на текущий документ строки
СсылкаНаДокумент = СтрокаСписка.Данные.Ссылка;
// Формируем произвольный текст на основе прикладной логики
Если ЗначениеЗаполнено(СсылкаНаДокумент) Тогда
СтрокаСписка.Данные.ПроизвольныйТекст = "Проверено: " + Строка(СтрокаСписка.Данные.Номер);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Обратите внимание на важное ограничение: пользователь не сможет настроить платформенный отбор, группировку или сортировку по значениям, сформированным в событии ПриПолученииДанныхНаСервере, поскольку СУБД применяет фильтры на уровне выполнения SQL-запроса еще до передачи порции данных в интерфейс.
Если нет необходимости переписывать запрос списка программным кодом, рассмотрим два альтернативных пути:
СкладскиеОрдера в расширение и добавить в него новую графу, включив в нее нужные реквизиты документов. В этом случае колонка появится в динамическом списке автоматически без перевода на произвольный запрос.УсловноеОформление. В нем для одной из стандартных колонок (например, для номера или комментария) по заданному условию программно подменяется отображаемый текст с помощью установки свойства Текст.