Почему в табличной части 1С вместо представления из списка выбора отображается значение и как это исправить?

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

Приветствуем вас, уважаемые коллеги! Сегодня мы разберем одну из классических проблем, с которой рано или поздно сталкивается любой разработчик при проектировании интерфейсов в платформе 1С:Предприятие 8 на управляемых формах. Представьте ситуацию: вы настроили список выбора для поля ввода. Если это поле находится непосредственно на самой форме, то всё работает идеально — пользователь выбирает нужную строку, и на экране всегда красуется понятное текстовое представление. Но стоит перенести точно такое же поле внутрь таблицы (табличной части или таблицы значений), как начинается странное поведение. При редактировании строки отображается текст, но стоит убрать фокус с ячейки, как представление мгновенно сменяется "сырым" значением (числовым кодом, идентификатором или строковым ключом).

Давайте подробно проанализируем, почему так происходит, заглянем во внутреннюю архитектуру управляемого интерфейса платформы 1С и изучим три эффективных способа решения этой проблемы шаг за шагом.

Выясняем причину: особенности работы управляемого интерфейса

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

Когда вы размещаете обычное поле ввода на форме, это статический элемент управления. Он постоянно существует в памяти клиента, связан с конкретным реквизитом и "помнит" свойства своего элемента, включая свойство РежимВыбораИзСписка и сам СписокВыбора. Платформа в любой момент времени может сопоставить текущее значение реквизита со списком выбора и вывести пользователю соответствующее текстовое представление.

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

Как только пользователь завершает редактирование (нажимает Enter или переводит фокус на другую ячейку), элемент управления уничтожается. Платформа видит, что в реквизите строки хранится, например, число 2. Поскольку постоянного элемента управления над этой ячейкой больше нет, платформа "забывает" связь со списком выбора и просто выводит на экран то, что записано в базе данных или коллекции — число 2 вместо красивого представления "Доставка курьером".

Теперь, когда мы понимаем природу этой особенности, давайте рассмотрим три практических способа заставить платформу выводить правильные данные.

Способ 1. Условное оформление формы (Рекомендуемый и декларативный метод)

Это самый элегантный способ, который не требует изменения структуры метаданных и отлично подходит для статичных или динамически формируемых списков средней длины. Мы будем использовать механизм условного оформления формы. Его суть заключается в следующем: мы говорим платформе, что если в определенной колонке таблицы содержится значение А, то отображать вместо него нужно текст Б.

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

Допустим, у нас есть табличная часть ДокументТЧ и колонка ТипДоставки (тип данных — Число). Нам нужно выводить текстовые представления вместо чисел. Пропишем следующий код в модуле управляемой формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Сначала наполняем список выбора нашей колонки
    КолонкаФормы = Элементы.ДокументТЧТипДоставки;
    КолонкаФормы.СписокВыбора.Добавить(1, "Самовывоз");
    КолонкаФормы.СписокВыбора.Добавить(2, "Доставка курьером");
    КолонкаФормы.СписокВыбора.Добавить(3, "Транспортная компания");
    
    // Вызываем процедуру, которая автоматически создаст правила оформления
    УстановитьПредставленияДляКолонки(КолонкаФормы, "Объект.ДокументТЧ.ТипДоставки");
    
КонецПроцедуры

Теперь давайте создадим вспомогательную процедуру УстановитьПредставленияДляКолонки, которая в цикле обойдет все элементы нашего списка выбора и добавит правила в коллекцию УсловноеОформление формы:


&НаСервере
Процедура УстановитьПредставленияДляКолонки(ЭлементКолонка, ПутьКДаннымКолонки)
    
    ИмяОформляемогоПоля = ЭлементКолонка.Имя;
    
    Для Каждого ЭлементСписка Из ЭлементКолонка.СписокВыбора Цикл
        
        // Добавляем новый элемент условного оформления
        ЭлементОформления = УсловноеОформление.Элементы.Добавить();
        
        // Задаем параметр оформления - отображаемый Текст
        ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Текст", ЭлементСписка.Представление);
        
        // Настраиваем условие (Отбор): когда значение в ячейке равно значению из списка
        ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ПутьКДаннымКолонки);
        ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
        ЭлементОтбора.ПравоеЗначение = ЭлементСписка.Значение;
        
        // Указываем, к какому именно полю на форме применять данное оформление
        ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
        ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных(ИмяОформляемогоПоля);
        
    КонецЦикла;
    
КонецПроцедуры

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

Способ 2. Использование вспомогательной текстовой колонки

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

Проанализируем этот алгоритм по шагам:

  1. В табличную часть объекта добавляем реквизит хранения значения (например, СпособОплатыКод с типом Число). Его мы не будем показывать пользователю напрямую на форме.
  2. На саму форму в таблицу добавляем строковую колонку (например, СпособОплатыТекст). Именно ее и будет видеть пользователь.
  3. Для строковой колонки настраиваем событие НачалоВыбора или кнопку выбора, перехватывая управление.
  4. Программно вызываем метод выбора из списка, записываем выбранный код в скрытый реквизит, а текстовое представление — в видимую строковую колонку.

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


&НаКлиенте
Процедура ДокументТЧСпособОплатыТекстНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Получаем текущую строку таблицы
    ТекущаяСтрока = Элементы.ДокументТЧ.ТекущиеДанные;
    Если ТекущаяСтрока = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Формируем список выбора динамически
    СписокПараметров = Новый СписокЗначений;
    СписокПараметров.Добавить(1, "Наличные");
    СписокПараметров.Добавить(2, "Безналичный расчет");
    СписокПараметров.Добавить(3, "Оплата картой");
    
    // Показываем меню выбора пользователю рядом с ячейкой
    ВыбранныйЭлемент = ВыбратьИзСписка(СписокПараметров, Элемент);
    
    Если ВыбранныйЭлемент <> Неопределено Тогда
        // Записываем код для базы данных
        ТекущаяСтрока.СпособОплатыКод = ВыбранныйЭлемент.Значение;
        // Записываем строковое представление для отображения на форме
        ТекущаяСтрока.СпособОплатыТекст = ВыбранныйЭлемент.Представление;
    КонецЕсли;
    
КонецПроцедуры

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

Способ 3. Переход на ссылочные типы данных (Архитектурно верный путь)

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

Рассмотрим два сценария правильного архитектурного решения:

  1. Перечисления (Enums): Если список возможных вариантов фиксирован на этапе разработки и не должен меняться пользователем (например, статусы документа: "Проект", "На согласовании", "Утвержден"), лучшим решением будет создать объект метаданных Перечисление. Измените тип реквизита вашей табличной части на ссылку на это перечисление. Платформа 1С "из коробки" берет на себя все задачи по выводу синонимов перечисления в любых таблицах, списках и отчетах без написания кода.
  2. Справочники: Если список вариантов может пополняться в процессе работы предприятия (например, виды тары, способы доставки, категории покупателей), создайте для этого отдельный Справочник. Измените тип колонки на ссылку на этот справочник. В табличной части у вас всегда будет отображаться наименование элемента, а храниться будет надежная ссылка (GUID), гарантирующая ссылочную целостность базы данных.

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

← На главную