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