При разработке расширений для 1С:Управление нашей фирмой (УНФ) или других конфигураций на управляемых формах программисты часто сталкиваются с ситуацией, когда визуальный элемент (поле ввода) на форме появляется, но остается недоступным для редактирования (серым). Рассмотрим подробнее, почему это происходит и как правильно реализовать программное добавление отборов.
Разберем ситуацию: вы добавили элемент формы типа ПолеФормы с видом ПолеВвода через Элементы.Добавить() или Элементы.Вставить(). Вы указали ПутьКДанным, например, "Список.ОтборСтатусЗаказа", но поле все равно не активно. Выясним причину этого поведения.
В платформе 1С:Предприятие 8 элемент формы — это лишь визуальное представление. Для того чтобы в поле можно было что-то ввести или выбрать, оно должно быть связано с реквизитом формы. Реквизит — это «ячейка памяти» в структуре формы, где хранится значение. Если вы указываете в ПутьКДанным строку, которой не соответствует реальный реквизит в дереве объектов формы, платформа блокирует это поле, так как ей некуда записывать выбранное значение.
Ошибка в коде автора заключалась в попытке обращения к Список.ОтборСтатусЗаказа. Объект ДинамическийСписок (которым является Список) не имеет произвольных свойств. Мы не можем просто так «дописать» новое свойство к динамическому списку через точку в пути к данным.
Проанализируем правильный алгоритм. Чтобы поле стало активным, нам нужно сначала создать сам реквизит формы программно. Для этого используется метод ИзменитьРеквизиты(). Рассмотрим пример кода, который необходимо добавить в начало процедуры ПриСозданииНаСервере:
// 1. Создаем массив для новых реквизитов
МассивРеквизитов = Новый Массив;
// 2. Описываем тип данных будущего реквизита.
// Если это статус из перечисления, указываем ссылку на это перечисление.
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("ПеречислениеСсылка.СостоянияЗаказов")); // Укажите ваш тип
ОписаниеТипаСтатуса = Новый ОписаниеТипов(МассивТипов);
// 3. Добавляем определение реквизита в массив
// Имя: "ОтборСтатусЗаказа", Тип: ОписаниеТипаСтатуса
НовыйРеквизит = Новый РеквизитФормы("ОтборСтатусЗаказа", ОписаниеТипаСтатуса, , "Статус заказа", Истина);
МассивРеквизитов.Добавить(НовыйРеквизит);
// 4. Физически добавляем реквизит на форму
ЭтаФорма.ИзменитьРеквизиты(МассивРеквизитов);
Только после выполнения этого кода в структуре формы появится переменная ОтборСтатусЗаказа, к которой можно привязывать элементы управления.
Теперь, когда реквизит существует, мы можем создать само поле ввода. Обратите внимание, что в ПутьКДанным теперь нужно указывать просто имя созданного реквизита (без префикса "Список"). Разберем по шагам:
// Создаем группу для отбора (если нужно)
ГруппаОтбор = Элементы.Добавить("ГруппаОтборСтатус", Тип("ГруппаФормы"), Элементы.ГруппаОтборы);
ГруппаОтбор.Вид = ВидГруппыФормы.ОбычнаяГруппа;
ГруппаОтбор.ОтображатьЗаголовок = Ложь;
// Добавляем само поле
ПолеОтбора = Элементы.Добавить("ПолеОтборСтатусЗаказа", Тип("ПолеФормы"), ГруппаОтбор);
ПолеОтбора.Вид = ВидПоляФормы.ПолеВвода;
// КРИТИЧЕСКИ ВАЖНО: Путь к данным должен совпадать с именем созданного реквизита
ПолеОтбора.ПутьКДанным = "ОтборСтатусЗаказа";
ПолеОтбора.РежимВыбораИзСписка = Истина;
ПолеОтбора.КнопкаСпискаВыбора = Истина;
Посмотрим на типичную ошибку при заполнении СписокВыбора. В исходном коде автора добавлялись строковые значения: "Создан", "На отгрузке". Однако, если реквизит имеет тип ссылки на перечисление, то и в список выбора нужно добавлять именно ссылки, а не строки. В противном случае платформа не сможет сопоставить типы, и отбор не сработает.
Проанализируем исправленную процедуру заполнения списка:
Процедура ЗаполнитьСписокВыбораСтатусов(ПолеФормы)
Список = ПолеФормы.СписокВыбора;
Список.Очистить();
// Вместо строки "Создан" добавляем реальную ссылку из перечисления
ЗначениеСтатуса = Перечисления.СостоянияЗаказов.Создан;
// Для красивого отображения можно использовать ФорматированнуюСтроку с картинкой
КомпонентыКартинки = Новый Массив;
КомпонентыКартинки.Добавить(БиблиотекаКартинок.СтатусЗаказаСоздан); // Ваша картинка
КомпонентыКартинки.Добавить(" ");
КомпонентыКартинки.Добавить("Создан");
Представление = Новый ФорматированнаяСтрока(КомпонентыКартинки);
Список.Добавить(ЗначениеСтатуса, Представление);
// Повторяем для остальных статусов...
Список.Добавить(Перечисления.СостоянияЗаказов.ВРаботе, "В работе");
КонецПроцедуры
После того как пользователь выбрал значение в поле, нам нужно применить этот отбор к динамическому списку. Это делается в событии ПриИзменении созданного поля. Выясним, как программно установить отбор в КомпоновкеДанных списка.
&НаКлиенте
Процедура ОтборСтатусЗаказаПриИзменении(Элемент)
// Получаем значение из реквизита формы
ТекущееЗначениеОтбора = ОтборСтатусЗаказа;
// Устанавливаем отбор в динамическом списке
// Параметры: ИмяПоля, Значение, Использование
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
Список,
"Состояние", // Имя поля в запросе динамического списка
ТекущееЗначениеОтбора,
ЗначениеЗаполнено(ТекущееЗначениеОтбора)
);
КонецПроцедуры
Важный момент: если вы используете типовые механизмы УНФ (функцию УстановитьМеткуИОтборСписка), убедитесь, что структура групп на форме соответствует ожиданиям БСП. Обычно такие поля помещаются в специальные группы "быстрых отборов", где система сама управляет их видимостью и "метками" (визуальными прямоугольниками с выбранным значением).
Для успешного добавления активного поля отбора необходимо соблюдать три условия:
ИзменитьРеквизиты().ПутьКДанным элемента формы должно указывать на этот реквизит.СписокВыбора должны иметь тот же тип данных (например, ПеречислениеСсылка), что и сам реквизит формы и поле в динамическом списке.Используя этот системный подход, вы сможете динамически изменять интерфейс форм списка, делая их максимально удобными для пользователей, при этом сохраняя стабильность работы конфигурации.