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