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