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