При работе с динамическими списками в 1С часто возникает необходимость изменить отображение данных, не меняя при этом их исходное значение в базе. Например, нам требуется добавить к строковому представлению какого-либо поля декоративный элемент, такой как троеточие. Рассмотрим, как мы можем решить эту задачу несколькими способами, учитывая различные сценарии, включая работу с составными типами данных.
Основная проблема, с которой мы можем столкнуться, заключается в том, что к ссылочным типам данных напрямую добавить строку невозможно. Для этого их сначала необходимо преобразовать в строковое представление. Также, если поле имеет составной тип, простое преобразование может не дать ожидаемого результата или вызвать ошибку, поскольку система не всегда может однозначно определить, какое из возможных представлений следует использовать.
Один из наиболее прямых способов изменить отображение поля — это внести изменения непосредственно в текст запроса динамического списка. Нам нужно получить строковое представление поля и уже к нему добавить необходимый текст.
Если мы попытаемся добавить строку к ссылочному полю напрямую, например: ДвиженияКнигСрезПоследних.Владелец + "...", система выдаст ошибку, так как оператор + не предназначен для конкатенации ссылок со строками. Нам необходимо использовать функцию ПРЕДСТАВЛЕНИЕ(), которая возвращает строковое представление ссылочного типа данных.
Таким образом, для простых ссылочных типов выражение будет выглядеть так:
ПРЕДСТАВЛЕНИЕ(ДвиженияКнигСрезПоследних.Владелец) + "..." КАК Читатель
Однако, как показала практика на форуме, при наличии составного типа данных для поля (например, когда поле Владелец может быть как СправочникСсылка.Читатели, так и ПеречислениеСсылка.МестоКниги), простое использование ПРЕДСТАВЛЕНИЕ(Поле) + "..." может вызвать ошибку или привести к непредсказуемому результату. В такой ситуации система не знает, какое именно представление из составного типа следует использовать по умолчанию.
Когда поле имеет составной тип, нам потребуется явно указать, как обрабатывать каждый возможный тип. Для этого мы воспользуемся конструкцией ВЫБОР КОГДА ... КОНЕЦ в запросе. Эта конструкция позволяет нам проверить тип значения поля с помощью функции ТИПЗНАЧЕНИЯ() и выполнить соответствующее действие.
Давайте посмотрим на пример запроса, который был предложен в обсуждении, и доработаем его для обработки составного типа Владелец:
ВЫБРАТЬ
СправочникКниги.Ссылка КАК Ссылка,
СправочникКниги.ПометкаУдаления КАК ПометкаУдаления,
СправочникКниги.Владелец КАК Владелец,
СправочникКниги.Код КАК Код,
СправочникКниги.Наименование КАК Наименование,
СправочникКниги.ГодИздания КАК ГодИздания,
СправочникКниги.КоличествоСтраниц КАК КоличествоСтраниц,
СправочникКниги.СерийныйНомер КАК СерийныйНомер,
СправочникКниги.Предопределенный КАК Предопределенный,
СправочникКниги.ИмяПредопределенныхДанных КАК ИмяПредопределенныхДанных,
ВЫБОР
КОГДА ТИПЗНАЧЕНИЯ(ДвиженияКнигСрезПоследних.Владелец) = ТИП(СправочникСсылка.Читатели)
ТОГДА ПРЕДСТАВЛЕНИЕ(ДвиженияКнигСрезПоследних.Владелец)
КОГДА ТИПЗНАЧЕНИЯ(ДвиженияКнигСрезПоследних.Владелец) = ТИП(ПеречислениеСсылка.МестоКниги)
ТОГДА ПРЕДСТАВЛЕНИЕ(ДвиженияКнигСрезПоследних.Владелец)
ИНАЧЕ "" // Важно предусмотреть случай, если значение Неопределено или другого типа
КОНЕЦ + "..." КАК Читатель
ИЗ
Справочник.Книги КАК СправочникКниги
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДвиженияКниг.СрезПоследних КАК ДвиженияКнигСрезПоследних
ПО (ДвиженияКнигСрезПоследних.Книга = СправочникКниги.Ссылка)
В этом примере мы явно проверяем тип значения поля ДвиженияКнигСрезПоследних.Владелец. Если это СправочникСсылка.Читатели, мы получаем его представление. Аналогично поступаем, если это ПеречислениеСсылка.МестоКниги. Ветвь ИНАЧЕ "" позволяет нам избежать ошибок, если поле по какой-то причине окажется Неопределено или другого, непредусмотренного типа. После получения строкового представления мы к нему уже безопасно добавляем троеточие + "...".
Этот подход делает запрос более надежным и универсальным при работе с полями, имеющими составной тип.
Еще один очень удобный и часто рекомендуемый способ решения подобных задач — это создание вычисляемого поля непосредственно в настройках динамического списка. Этот метод переносит логику форматирования с уровня запроса на уровень интерфейса, что может упростить запрос и сделать его более читабельным.
Рассмотрим шаги для добавления вычисляемого поля:
ДинамическийСписок на форме.ПредставлениеВладельцаСТроеточием.
ПРЕДСТАВЛЕНИЕ(Владелец) + "..."
Если же поле Владелец имеет составной тип и мы хотим более явного контроля, как в случае с запросом, мы можем использовать аналогичную конструкцию ВЫБОР КОГДА ... КОНЕЦ. Однако, для вычисляемых полей в динамическом списке, система часто справляется с преобразованием составных типов в строку по умолчанию (используя первое подходящее представление или стандартный алгоритм). Поэтому сначала попробуйте более простой вариант. Если возникнут проблемы, переходите к более сложной конструкции ВЫБОР КОГДА.
ВЫБОР
КОГДА ТИПЗНАЧЕНИЯ(Владелец) = ТИП(СправочникСсылка.Читатели)
ТОГДА ПРЕДСТАВЛЕНИЕ(Владелец)
КОГДА ТИПЗНАЧЕНИЯ(Владелец) = ТИП(ПеречислениеСсылка.МестоКниги)
ТОГДА ПРЕДСТАВЛЕНИЕ(Владелец)
ИНАЧЕ ""
КОНЕЦ + "..."
Преимущества этого подхода:
Для случаев, когда логика форматирования становится слишком сложной для выражения в запросе или вычисляемом поле (например, требуется выполнять какие-либо дополнительные вычисления или обращения к другим данным), мы можем использовать событие динамического списка ОбработкаПолученияДанных на сервере. Это событие возникает после выполнения основного запроса динамического списка, но до того, как данные будут отображены пользователю.
Рассмотрим по шагам, как мы можем применить этот метод:
Нам потребуется создать в динамическом списке новое вычисляемое поле. Это поле будет служить "заглушкой" или контейнером, в который мы будем записывать отформатированный текст. Его "Выражение" может быть пустым или просто возвращать пустую строку, так как мы будем заполнять его программно. Назовем его, например, ПолеДляОтображенияСТроеточием.
Затем, в дереве элементов формы, мы создаем колонку в динамическом списке и привязываем ее к этому новому полю.
ОбработкаПолученияДанных:
Перейдите в свойства динамического списка на форме, найдите событие ОбработкаПолученияДанных и создайте обработчик на сервере. В этом обработчике мы получим коллекцию данных, обойдем каждую строку и модифицируем наше вспомогательное поле.
Процедура ДинамическийСписокНаСервере_ОбработкаПолученияДанных(Элемент, Данные, Отказ)
Для Каждого Строка Из Данные Цикл
// Проверяем, что поле Владелец не пустое
Если Строка.Владелец <> Неопределено ИЛИ Строка.Владелец <> Null Тогда
// Преобразуем значение Владельца к строке и добавляем троеточие
// Для составных типов Строка() сама часто справляется корректно,
// но можно и явно проверить ТипЗначения, как в запросе, если нужно специфическое поведение
Строка.ПолеДляОтображенияСТроеточием = Строка(Строка.Владелец) + "...";
Иначе
// Если Владелец не определен, можно установить пустую строку или другое значение
Строка.ПолеДляОтображенияСТроеточием = "";
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Преимущества этого подхода:
Недостатки и особенности:
Мы рассмотрели три основных способа добавления троеточия (или любого другого текста) к представлению поля в динамическом списке 1С, каждый из которых подходит для определенных сценариев:
ВЫБОР КОГДА. Это эффективный способ, так как обработка происходит на уровне СУБД.ОбработкаПолученияДанных): Используйте этот метод, когда требуется очень сложная или специфическая логика форматирования, которую невозможно выразить в запросе или вычисляемом поле. Помните о потенциальном влиянии на производительность.Выбор конкретного метода зависит от сложности требуемого форматирования, типа данных обрабатываемого поля и требований к производительности системы. В большинстве случаев мы рекомендуем начинать с вычисляемого поля или модификации запроса, переходя к программной обработке только при наличии веских на то причин.