Как сделать, чтобы в поле со Списком Значений отображалось представление, а не идентификатор?

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

Часто при работе с управляемыми формами в 1С возникает задача: нужно предоставить пользователю выбор из списка, где каждый элемент имеет внутренний идентификатор (например, GUID) и понятное человеку представление (например, "Пользователь Иванов"). Стандартное поведение платформы таково, что после выбора в поле отображается именно внутреннее значение, что неудобно и неинформативно для пользователя. Давайте разберем, почему так происходит и как это исправить.

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

Причина такого поведения кроется в механизме связывания данных. Поле на форме напрямую связано с реквизитом, и платформа записывает в него именно Значение выбранного элемента, так как оно соответствует типу данных. Представление используется лишь как подсказка в момент выбора. Наша задача — "обмануть" механизм отображения, не меняя при этом хранимое значение. Рассмотрим несколько способов решения этой задачи.

Решение 1: Использование условного оформления (основной способ)

Это самый гибкий и часто используемый метод для решения подобных задач. Идея заключается в том, чтобы подменить отображаемый в поле текст, не затрагивая его реальное значение. Условное оформление позволяет задавать правила, по которым внешний вид элементов формы будет меняться в зависимости от данных.

Разберем по шагам, как это работает. Нам нужно для каждого возможного значения из списка создать правило: "Если значение в поле равно X, то отображать текст Y".

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

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

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

  1. Создаем реквизит формы Пользователи с типом СписокЗначений.
  2. В процедуре ПриСозданииНаСервере получаем данные и заполняем список выбора для нашего поля, а также программно настраиваем условное оформление.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // 1. Очищаем старые настройки, если они есть
    Элементы.Пользователи.СписокВыбора.Очистить();
    УсловноеОформление.Элементы.Очистить();
    
    // 2. Получаем данные для выбора. 
    // В реальной задаче здесь будет запрос к веб-сервису или к базе данных.
    // Для примера создадим структуру.
    ВариантыВыбора = Новый Структура;
    ВариантыВыбора.Вставить("a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6", "Иванов Иван Иванович");
    ВариантыВыбора.Вставить("b2c3d4e5-f6g7-h8i9-j0k1-l2m3n4o5p6q7", "Петров Петр Петрович");
    ВариантыВыбора.Вставить("c3d4e5f6-g7h8-i9j0-k1l2-m3n4o5p6q7r8", "Сидоров Сидор Сидорович");
    
    // 3. Заполняем список выбора для элемента формы и программно создаем условное оформление
    Для Каждого КлючИЗначение Из ВариантыВыбора Цикл
        
        // Добавляем элемент в выпадающий список
        Элементы.Пользователи.СписокВыбора.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
        
        // Создаем новый элемент условного оформления
        ЭлементУсловногоОформления = УсловноеОформление.Элементы.Добавить();
        
        // Указываем, что оформлять будем поле "Пользователи"
        ОформляемоеПоле = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
        ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("Пользователи");
        
        // Настраиваем отбор: правило будет срабатывать для конкретного значения
        ЭлементОтбора = ЭлементУсловногоОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Пользователи"); // Путь к данным реквизита
        ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
        ЭлементОтбора.ПравоеЗначение = КлючИЗначение.Ключ; // GUID нашего пользователя
        
        // Настраиваем оформление: устанавливаем нужный текст
        ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Текст", КлючИЗначение.Значение);
        
    КонецЦикла;
    
КонецПроцедуры

Что мы сделали? Мы в цикле обошли все возможные варианты. Для каждого варианта мы добавили элемент в список выбора (чтобы пользователь мог его выбрать) и создали персональное правило в условном оформлении. Это правило "говорит" форме: "когда в реквизите Объект.Пользователи будет лежать значение-идентификатор, покажи вместо него текст-представление".

Преимущества:

Недостатки:

Решение 2: Использование Таблицы Значений вместо Списка Значений

Платформа 1С предоставляет более системный и "правильный" механизм для подобных задач, особенно если речь идет о множественном выборе. Вместо реквизита типа СписокЗначений можно использовать ТаблицаЗначений.

Разберем по шагам:

  1. Создаем на форме реквизит (например, ВыбранныеПользователи) с типом ТаблицаЗначений.
  2. В этой таблице создаем две колонки: Идентификатор (тип УникальныйИдентификатор или Строка) и Представление (тип Строка).
  3. Перетаскиваем этот реквизит на форму. У созданного элемента формы (поля ввода) появятся важные свойства в палитре свойств.
  4. Находим свойство ПутьКДаннымЗначения и указываем в нем имя нашей колонки с идентификаторами — Идентификатор.
  5. Находим свойство ПутьКДаннымПредставления и указываем имя колонки с представлениями — Представление.
  6. Теперь осталось только заполнить список выбора для этого поля (Элементы.ВыбранныеПользователи.СписокВыбора) так же, как мы делали в первом способе.

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

Преимущества:

Решение 3: Программная обработка события `ПриИзменении` (альтернативный вариант)

В обсуждении на форуме был предложен еще один вариант — обрабатывать событие изменения поля на клиенте. Этот метод имеет свою специфику и подходит не во всех случаях.

Идея в том, чтобы после выбора значения пользователем принудительно обновить представление у элементов реквизита СписокЗначений.


&НаКлиенте
Процедура ПользователиПриИзменении(Элемент)
    
    // Перебираем элементы в реквизите формы "Пользователи"
    Для Индекс = 0 По Пользователи.Количество() - 1 Цикл
        ЭлементСписка = Пользователи[Индекс];
        
        // Если представление не заполнено, находим его в списке выбора
        Если НЕ ЗначениеЗаполнено(ЭлементСписка.Представление) Тогда
            НайденныйЭлементВыбора = Элементы.Пользователи.СписокВыбора.НайтиПоЗначению(ЭлементСписка.Значение);
            Если НайденныйЭлементВыбора <> Неопределено Тогда
                ЭлементСписка.Представление = НайденныйЭлементВыбора.Представление;
            КонецЕсли;
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Важный нюанс: Этот подход сработает корректно, если ваш реквизит СписокЗначений отображается на форме в виде таблицы, где видны и значение, и представление. Если же он выведен как простое поле ввода, то этот код, скорее всего, не изменит отображение в самом поле, так как поле показывает строковое представление всего объекта СписокЗначений, а не его отдельных элементов.

Выводы

Проанализировав ситуацию, мы можем дать следующие рекомендации:

Таким образом, стандартное поведение платформы можно и нужно настраивать под свои задачи, используя мощные инструменты, которые она предоставляет.

← На главную