Почему программно добавленное поле ввода на форме списка 1С неактивно и как это исправить

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

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

Анализ основной причины проблемы

Разберем ситуацию: вы добавили элемент формы типа ПолеФормы с видом ПолеВвода через Элементы.Добавить() или Элементы.Вставить(). Вы указали ПутьКДанным, например, "Список.ОтборСтатусЗаказа", но поле все равно не активно. Выясним причину этого поведения.

В платформе 1С:Предприятие 8 элемент формы — это лишь визуальное представление. Для того чтобы в поле можно было что-то ввести или выбрать, оно должно быть связано с реквизитом формы. Реквизит — это «ячейка памяти» в структуре формы, где хранится значение. Если вы указываете в ПутьКДанным строку, которой не соответствует реальный реквизит в дереве объектов формы, платформа блокирует это поле, так как ей некуда записывать выбранное значение.

Ошибка в коде автора заключалась в попытке обращения к Список.ОтборСтатусЗаказа. Объект ДинамическийСписок (которым является Список) не имеет произвольных свойств. Мы не можем просто так «дописать» новое свойство к динамическому списку через точку в пути к данным.

Шаг 1: Программное создание реквизита формы

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


// 1. Создаем массив для новых реквизитов
МассивРеквизитов = Новый Массив;

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

// 3. Добавляем определение реквизита в массив
// Имя: "ОтборСтатусЗаказа", Тип: ОписаниеТипаСтатуса
НовыйРеквизит = Новый РеквизитФормы("ОтборСтатусЗаказа", ОписаниеТипаСтатуса, , "Статус заказа", Истина);
МассивРеквизитов.Добавить(НовыйРеквизит);

// 4. Физически добавляем реквизит на форму
ЭтаФорма.ИзменитьРеквизиты(МассивРеквизитов);

Только после выполнения этого кода в структуре формы появится переменная ОтборСтатусЗаказа, к которой можно привязывать элементы управления.

Шаг 2: Правильное создание элемента формы и привязка данных

Теперь, когда реквизит существует, мы можем создать само поле ввода. Обратите внимание, что в ПутьКДанным теперь нужно указывать просто имя созданного реквизита (без префикса "Список"). Разберем по шагам:


// Создаем группу для отбора (если нужно)
ГруппаОтбор = Элементы.Добавить("ГруппаОтборСтатус", Тип("ГруппаФормы"), Элементы.ГруппаОтборы);
ГруппаОтбор.Вид = ВидГруппыФормы.ОбычнаяГруппа;
ГруппаОтбор.ОтображатьЗаголовок = Ложь;

// Добавляем само поле
ПолеОтбора = Элементы.Добавить("ПолеОтборСтатусЗаказа", Тип("ПолеФормы"), ГруппаОтбор);
ПолеОтбора.Вид = ВидПоляФормы.ПолеВвода;

// КРИТИЧЕСКИ ВАЖНО: Путь к данным должен совпадать с именем созданного реквизита
ПолеОтбора.ПутьКДанным = "ОтборСтатусЗаказа"; 

ПолеОтбора.РежимВыбораИзСписка = Истина;
ПолеОтбора.КнопкаСпискаВыбора = Истина;

Шаг 3: Заполнение списка выбора корректными типами

Посмотрим на типичную ошибку при заполнении СписокВыбора. В исходном коде автора добавлялись строковые значения: "Создан", "На отгрузке". Однако, если реквизит имеет тип ссылки на перечисление, то и в список выбора нужно добавлять именно ссылки, а не строки. В противном случае платформа не сможет сопоставить типы, и отбор не сработает.

Проанализируем исправленную процедуру заполнения списка:


Процедура ЗаполнитьСписокВыбораСтатусов(ПолеФормы)
    
    Список = ПолеФормы.СписокВыбора;
    Список.Очистить();
    
    // Вместо строки "Создан" добавляем реальную ссылку из перечисления
    ЗначениеСтатуса = Перечисления.СостоянияЗаказов.Создан;
    
    // Для красивого отображения можно использовать ФорматированнуюСтроку с картинкой
    КомпонентыКартинки = Новый Массив;
    КомпонентыКартинки.Добавить(БиблиотекаКартинок.СтатусЗаказаСоздан); // Ваша картинка
    КомпонентыКартинки.Добавить(" ");
    КомпонентыКартинки.Добавить("Создан");
    Представление = Новый ФорматированнаяСтрока(КомпонентыКартинки);
    
    Список.Добавить(ЗначениеСтатуса, Представление);
    
    // Повторяем для остальных статусов...
    Список.Добавить(Перечисления.СостоянияЗаказов.ВРаботе, "В работе");
    
КонецПроцедуры

Шаг 4: Реализация логики фильтрации

После того как пользователь выбрал значение в поле, нам нужно применить этот отбор к динамическому списку. Это делается в событии ПриИзменении созданного поля. Выясним, как программно установить отбор в КомпоновкеДанных списка.


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

Важный момент: если вы используете типовые механизмы УНФ (функцию УстановитьМеткуИОтборСписка), убедитесь, что структура групп на форме соответствует ожиданиям БСП. Обычно такие поля помещаются в специальные группы "быстрых отборов", где система сама управляет их видимостью и "метками" (визуальными прямоугольниками с выбранным значением).

Подведем итоги

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

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

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

← На главную