При разработке интерфейсов на управляемых формах часто возникает задача отобразить в динамическом списке вычисляемое поле со сложным форматированием — например, представить числовой срок использования или стаж в виде понятной строки: «9 лет 5 месяцев 3 дня». Реализовать подобное строковое форматирование средствами одного лишь языка запросов СУБД крайне затруднительно или неэффективно.
Разберем по шагам, как правильно добавить такую колонку в динамический список с произвольным запросом и заполнить ее данными с помощью серверных обработчиков платформы «1С:Предприятие 8.3».
Для того чтобы в схеме динамического списка и в элементах формы появилась возможность привязать колонку к данным, добавим в текст запроса списка пустую строку с нужным псевдонимом:
ВЫБРАТЬ
СправочникОС.Ссылка КАК Ссылка,
СправочникОС.Наименование КАК Наименование,
СправочникОС.СрокПолезногоИспользования КАК Стаж,
"" КАК СтажСтрокой
ИЗ
Справочник.ОсновныеСредства КАК СправочникОС
После изменения текста запроса добавим колонку СтажСтрокой из состава реквизита списка в таблицу на форме.
Начиная с платформы 8.3.8, для динамических списков доступно событие ПриПолученииДанныхНаСервере. Этот обработчик выполняется строго на сервере без контекста формы (&НаСервереБезКонтекста) и вызывается только для тех строк, которые непосредственно отображаются на экране пользователя.
Подключим событие динамического списка в свойствах формы и напишем процедуру обхода строк:
&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
Для Каждого Эл Из Строки Цикл
// Обращаемся к структуре данных текущей строки
ЗначениеСтажа = Эл.Значение.Данные.Стаж;
Эл.Значение.Данные.СтажСтрокой = РаботаСоСтроками.ДатаПрописьюГодМесяцДень(ЗначениеСтажа);
КонецЦикла;
КонецПроцедуры
Разберем пример функции, преобразующей числовое значение срока (в месяцах) в развернутую строку с правильными склонениями («год», «года», «лет», «месяц», «месяца», «дней»). Эту функцию удобно разместить в общем модуле (например, РаботаСоСтроками с флагом «Сервер»):
Функция ДатаПрописьюГодМесяцДень(СрокПолезногоИспользования) Экспорт
РасшифровкаСрокаПолезногоИспользования = "";
Если ЗначениеЗаполнено(СрокПолезногоИспользования) Тогда
ЧастьМесяца = СрокПолезногоИспользования - Цел(СрокПолезногоИспользования);
ЧислоДней = Цел(30 * ЧастьМесяца);
Суффикс = "";
Если ЧислоДней <> 0 Тогда
Суффикс = ЧислоПрописью(ЧислоДней, "НД = Ложь", "#$ень, #$ня, #$ней, м,,,,,0");
ПозицияПослеПрописи = Найти(Суффикс, "#$");
Суффикс = Сред(Суффикс, ПозицияПослеПрописи);
Суффикс = " " + СокрЛП(ЧислоДней) + " " + Суффикс;
КонецЕсли;
ЧислоЛет = Цел(СрокПолезногоИспользования / 12);
ЧислоМесяцев = Цел(СрокПолезногоИспользования % 12);
ЧислоЛетМесяцев = ЧислоЛет + ЧислоМесяцев / 100;
Если ЧислоЛет = 0 Тогда
СтрокаЧислоЛетМесяцев = ЧислоПрописью(ЧислоМесяцев, "НД = Ложь", "месяц, месяца, месяцев, м,,,,,0");
СтрокаПоиска = "месяц";
Иначе
СтрокаЧислоЛетМесяцев = ЧислоПрописью(ЧислоЛетМесяцев, ?(ЧислоМесяцев = 0, "НД = Ложь", "НД = Истина"), "год, года, лет, м" + ?(ЧислоМесяцев = 0, ",,,,,0", ", месяц, месяца, месяцев, м, 2"));
СтрокаПоиска = "год";
КонецЕсли;
ПозицияПослеЛет = Найти(СтрокаЧислоЛетМесяцев, СтрокаПоиска);
Если ПозицияПослеЛет = 0 Тогда
ПозицияПослеЛет = Найти(СтрокаЧислоЛетМесяцев, "лет");
КонецЕсли;
Если ПозицияПослеЛет > 0 Тогда
РасшифровкаСрокаПолезногоИспользования = СокрЛП(?(ЧислоЛет = 0, ЧислоМесяцев, ЧислоЛет)) + " " + Сред(СтрокаЧислоЛетМесяцев, ПозицияПослеЛет);
РасшифровкаСрокаПолезногоИспользования = СтрЗаменить(РасшифровкаСрокаПолезногоИспользования, " 0", " ") + СтрЗаменить(Суффикс, "#$", "д");
КонецЕсли;
КонецЕсли;
Возврат РасшифровкаСрокаПолезногоИспользования;
КонецФункции
Проанализируем ключевые нюансы работы данного механизма:
СтажСтрокой работать на уровне базы данных не будут. Сортировку и фильтрацию следует выполнять по исходному числовому полю Стаж.ЛЕВОЕ СОЕДИНЕНИЕ) возникают дубликаты ключевых полей (ссылок), либо если в настройках списка не задана или некорректно указана Основная таблица.Строки, выполните один пакетный запрос на всю видимую порцию, а затем раздайте полученные данные по строкам.Строки в обработчике ПриПолученииДанныхНаСервере можно управлять не только структурой Данные, но и коллекцией Оформление (свойства Текст, ЦветФона, ЦветТекста, Шрифт), что позволяет задавать форматированный текст ячейки без непосредственного изменения значения.