Как автоматически установить тип данных в списке значений при использовании составного типа в 1С?

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

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

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

Метод 1. Использование обработчика события «ПриИзменении»

Это самый простой и эффективный способ, подходящий для большинства случаев. Идея заключается в том, чтобы "перехватить" момент, когда пользователь выбрал тип СписокЗначений, и программно задать ему ТипЗначения. Рассмотрим ситуацию, когда реквизит Номенклатура находится в объекте обработки.

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

  1. Создадим на форме обработчик события ПриИзменении для нашего реквизита.
  2. Внутри обработчика проверим, является ли текущее значение списком.
  3. Если это список, инициализируем его описание типов.

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

Важный нюанс: если ваш реквизит является не частью Объект, а просто реквизитом формы, используйте обращение напрямую: ЭтаФорма.ИмяРеквизита.ТипЗначения. Этот метод позволяет избежать повторного появления окна выбора типа внутри самого списка значений.

Метод 2. Управление ограничением типа через элементы формы

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

Рассмотрим пример, когда на форме есть дополнительная логика (например, вид сравнения), и нам нужно программно ограничить выбор только одним типом или только списком:


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

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

Метод 3. Использование события «ОбработкаВыбораТипа»

Если вы хотите полностью исключить стандартное окно выбора типа 1С (где предлагается выбрать "СправочникСсылка..." или "Список значений"), проанализируем возможности события ОбработкаВыбораТипа. Это событие возникает в момент нажатия кнопки выбора типа.

В этом обработчике можно установить параметр СтандартнаяОбработка = Ложь и сразу присвоить нужный тип. Однако стоит учитывать, что для составного типа это может быть избыточным, если пользователь все же должен иметь возможность выбирать между ссылкой и списком. Но если вы реализуете свой собственный диалог выбора (например, через кнопки на форме), этот метод станет незаменимым.

Метод 4. Событие «НачалоВыбора» для полного контроля

Проанализируем ситуацию, когда стандартные механизмы не подходят. Мы можем полностью перехватить процесс выбора через событие НачалоВыбора. Это позволяет реализовать логику: "Если выбран режим списка — открыть форму редактирования списка, если одиночный — открыть форму выбора справочника".


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

Рекомендации по интерфейсному подходу

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

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

Этот подход наиболее дружелюбен к пользователю, так как исключает необходимость понимать, что такое "Тип значения" и зачем нажимать кнопку "Т". Система всегда четко отображает либо поле для выбора одной позиции, либо таблицу/поле для списка.

Подведем итог: для быстрого решения проблемы достаточно в событии ПриИзменении проверять тип и устанавливать свойство ТипЗначения для СписокЗначений. Для создания профессионального интерфейса лучше использовать программное управление свойством ОграничениеТипа или разделение на два разных элемента формы.

← На главную