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