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