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