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

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

При разработке интерфейсов на обычных формах разработчики часто сталкиваются с нестандартным поведением элементов управления. Типичная задача: на форме расположено поле ввода со ссылочным типом данных (например, составной тип ЛюбаяСсылка или конкретный справочник/документ), у которого отображается кнопка открытия для перехода к объекту. Если по логике работы программы в поле может попасть один из нескольких предопределенных вариантов, возникает соблазн программно включить свойство РежимВыбораИзСписка = Истина и заполнить выпадающий список.

Однако при интерактивном выборе значения из такого списка в связанный реквизит вместо ссылки записывается строковое представление, свойство ТипЗначения элемента формы сбрасывается, а стандартная кнопка открытия перестает функционировать. Разберем причины такого поведения платформы «1С:Предприятие» и рассмотрим несколько надежных способов реализации нужного сценария.

Причина проблемы заключается в механизме работы самого свойства РежимВыбораИзСписка в обычном приложении. При установке этого флага поле ввода концептуально превращается в выпадающий список (комбобокс), ориентированный на строковый ввод и текстовое сопоставление. Если у элемента включено редактирование текста (значение по умолчанию), платформа пытается зафиксировать введенное строковое значение. Для реквизита составного типа это приводит к тому, что тип реквизита принудительно преобразуется в Строка, а исходная ссылка из свойства Значение элемента списка значений теряется.

Способ 1. Использование кнопки списка выбора без смены режима поля (рекомендуемый)

Наиболее чистое и правильное решение, сохраняющее исходный тип данных и работу стандартных кнопок — оставить поле в классическом режиме поля ввода, но отобразить на нем специальную кнопку выпадающего списка.

Разберем реализацию по шагам:

  1. Оставим свойство элемента управления РежимВыбораИзСписка в значении Ложь.
  2. Включим отображение кнопки выпадающего списка: установим свойство КнопкаСпискаВыбора = Истина.
  3. Запретим прямой ввод произвольного текста с клавиатуры через свойство РедактированиеТекста = Ложь.
  4. Заполним СписокВыбора элемента ссылочными значениями (в свойство Значение каждого элемента списка помещаем ссылку).

Посмотрим на пример программной настройки элемента формы:


ЭлементФормы = ЭлементыФормы.ПолеСсылки;
ЭлементФормы.РежимВыбораИзСписка = Ложь;
ЭлементФормы.КнопкаСпискаВыбора = Истина;
ЭлементФормы.КнопкаОткрытия = Истина;
ЭлементФормы.РедактированиеТекста = Ложь;

// Заполняем список ссылками
ЭлементФормы.СписокВыбора.Очистить();
Для Каждого Ссылка Из МассивСсылок Цикл
    ЭлементФормы.СписокВыбора.Добавить(Ссылка, Строка(Ссылка));
КонецЦикла;

В этом сценарии платформа не сбрасывает ТипЗначения, при выборе из выпадающего меню подставляет реальную ссылку, а стандартная обработка кнопки открытия продолжает штатно открывать форму соответствующего объекта.

Способ 2. Программный вызов метода «ВыбратьИзСписка()» в событии «НачалоВыбора»

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

Разберем этот вариант:

  1. Оставляем свойства РежимВыбораИзСписка и КнопкаСпискаВыбора выключенными.
  2. Включаем стандартную кнопку выбора (КнопкаВыбора = Истина) или кнопку открытия.
  3. В обработчике события НачалоВыбора отключаем стандартную обработку и открываем всплывающий список.

Рассмотрим пример кода в модуле формы:


Процедура ПолеСсылкиНачалоВыбора(Элемент, СтандартнаяОбработка)
    
    Если НеобходимВыборИзСписка Тогда
        СтандартнаяОбработка = Ложь;
        
        СписокВариантов = Новый СписокЗначений;
        Для Каждого Ссылка Из МассивСсылок Цикл
            СписокВариантов.Добавить(Ссылка, Строка(Ссылка));
        КонецЦикла;
        
        ВыбранныйЭлемент = ВыбратьИзСписка(СписокВариантов, Элемент);
        
        Если ВыбранныйЭлемент <> Неопределено Тогда
            РеквизитСсылка = ВыбранныйЭлемент.Значение;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Метод ВыбратьИзСписка() модально или контекстно привязывает список к элементу управления. При выборе пользователя в реквизит напрямую попадает ссылка без промежуточных преобразований в строку.

Способ 3. Ручная обработка событий (подход типовых конфигураций)

В типовых решениях (например, в УПП) при необходимости использования режима РежимВыбораИзСписка = Истина проблему с потерей ссылок решают переопределением стандартных обработчиков событий ПриИзменении и Открытие.

Проанализируем шаги настройки:

  1. Для элемента управления отключаем редактирование текста: РедактированиеТекста = Ложь.
  2. В событии ПриИзменении сопоставляем выбранную строку со списком выбора и принудительно восстанавливаем ссылочное значение.
  3. В событии Открытие отключаем стандартную обработку и открываем объект с помощью глобальной процедуры ОткрытьЗначение().

Посмотрим на реализацию обработчиков:


Процедура ПолеСсылкиПриИзменении(Элемент)
    
    // Если в реквизит попала строка или представление, ищем исходный элемент
    ЭлементСписка = Элемент.СписокВыбора.НайтиПоПредставлению(РеквизитСсылка);
    Если ЭлементСписка <> Неопределено Тогда
        РеквизитСсылка = ЭлементСписка.Значение;
    Иначе
        ЭлементСписка = Элемент.СписокВыбора.НайтиПоЗначению(РеквизитСсылка);
        Если ЭлементСписка <> Неопределено Тогда
            РеквизитСсылка = ЭлементСписка.Значение;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Процедура ПолеСсылкиОткрытие(Элемент, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    Если ЗначениеЗаполнено(РеквизитСсылка) Тогда
        ОткрытьЗначение(РеквизитСсылка);
    КонецЕсли;
    
КонецПроцедуры

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

Выводы: Чтобы избежать потери ссылочного типа данных в обычных формах 1С, предпочтительно использовать комбинацию свойств КнопкаСпискаВыбора = Истина и РежимВыбораИзСписка = Ложь. Если же дизайн формы строго требует активации режима выбора из списка, синхронизацию ссылок и работу кнопки открытия следует реализовывать вручную в событиях элемента управления.

← На главную