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