В практике разработки на платформе 1С:Предприятие 8.3 часто возникает задача по динамическому изменению состава формы. Это может быть добавление информационных колонок в табличную часть, создание новых полей ввода или кнопок. Если такая задача встречается в нескольких документах или справочниках, логично вынести код в общий модуль для обеспечения принципа повторного использования кода. Однако начинающие разработчики часто сталкиваются с проблемой: метод ИзменитьРеквизиты кажется недоступным вне модуля самой формы.
В этой статье мы подробно разберем, как правильно реализовать программное добавление элементов из общего модуля, проанализируем типичные ошибки и составим универсальный алгоритм работы.
Разберем основную причину затруднений: метод ИзменитьРеквизиты является методом объекта УправляемаяФорма. В модуле самой формы мы вызываем его неявно (просто указывая имя метода), так как находимся в контексте этого объекта. При попытке вызвать его из общего модуля система «теряет» этот контекст.
Выясним причину ошибки: многие полагают, что этот метод доступен только «внутри» формы. На самом деле, чтобы вызвать его извне, достаточно передать саму Форму как параметр в процедуру общего модуля. Критически важно: вызов должен происходить в серверном контексте, так как изменение структуры данных формы — это операция, выполняемая строго на сервере.
Процесс добавления всегда разделяется на два этапа: сначала мы создаем данные (реквизиты), а затем — визуальное представление (элементы). Рассмотрим подробнее, как добавить новые реквизиты, включая колонки табличной части, через общий модуль.
Рассмотрим пример кода в общем модуле (например, МодификацияФормСервер):
Процедура ДобавитьКолонкуВТаблицу(ФормаОбъект, ИмяТаблицы, ИмяРеквизита, Заголовок) Экспорт
// 1. Описываем тип данных для нового реквизита
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Строка"));
ОписаниеТиповСтр = Новый ОписаниеТипов(МассивТипов, Новый КвалификаторыСтроки(100));
// 2. Создаем массив новых реквизитов формы
// Для колонки ТЧ важно указать путь к родителю (самой таблице)
ПутьКТаблице = "Объект." + ИмяТаблицы;
НовыйРеквизит = Новый РеквизитФормы(ИмяРеквизита, ОписаниеТиповСтр, ПутьКТаблице, Заголовок, Истина);
ДобавляемыеРеквизиты = Новый Массив;
ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
// 3. Вызываем метод изменения реквизитов у переданного объекта формы
ФормаОбъект.ИзменитьРеквизиты(ДобавляемыеРеквизиты);
КонецПроцедуры
Проанализируем параметры конструктора РеквизитФормы. Шестым параметром мы передаем путь к данным родителя. Если мы хотим добавить колонку в табличную часть Товары, путь должен быть "Объект.Товары". Если же мы добавляем реквизит в корень формы, этот параметр можно оставить пустым.
После того как данные созданы методом ИзменитьРеквизиты, они еще не видны пользователю. Теперь нам нужно создать элемент управления и связать его с данными. Посмотрим на пример добавления колонки в существующую таблицу на форме:
// Продолжение процедуры в общем модуле
// Определяем родительский элемент (саму таблицу на форме)
ЭлементТаблица = ФормаОбъект.Элементы[ИмяТаблицы];
// Добавляем новый элемент (поле формы) в коллекцию элементов таблицы
НовыйЭлемент = ФормаОбъект.Элементы.Добавить("Таблица_" + ИмяРеквизита, Тип("ПолеФормы"), ЭлементТаблица);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
// Указываем путь к данным. Он должен совпадать с полным путем реквизита
НовыйЭлемент.ПутьКДанным = ПутьКТаблице + "." + ИмяРеквизита;
НовыйЭлемент.Заголовок = Заголовок;
Обратите внимание на свойство ПутьКДанным. Оно является связующим звеном. Если вы ошибетесь в написании пути, форма при открытии выдаст ошибку о недопустимом значении пути к данным.
Если программно созданному элементу требуется назначить обработчик события (например, ПриИзменении), нужно помнить следующее:
УстановитьДействие.Пример назначения действия:
НовыйЭлемент.УстановитьДействие("ПриИзменении", "Подключаемый_ПриИзмененииКолонки");
Разберем важный нюанс: метод ИзменитьРеквизиты — это тяжелая операция. Она заставляет платформу полностью пересобирать структуру формы на сервере. Если вам нужно добавить 10 реквизитов, не вызывайте этот метод 10 раз в цикле. Вместо этого:
РеквизитФормы в один массив.ИзменитьРеквизиты один раз для всего массива.Элементы.Добавить.Проанализируем ситуацию с выбором обработчика для размещения кода. Оптимальное место для вызова ваших процедур из общего модуля — это стандартный обработчик формы ПриСозданииНаСервере. Добавление реквизитов на более поздних этапах (например, по нажатию кнопки) возможно, но требует осторожности: форма будет «моргать», а некоторые данные, введенные пользователем, могут потребовать дополнительного пересчета.
Если вы работаете в современной типовой конфигурации, мы рекомендуем обратить внимание на подсистему «Дополнительные отчеты и обработки» или «Свойства». Библиотека стандартных подсистем (БСП) уже содержит мощные общие модули, такие как УправлениеСвойствами. Проанализировав их код, вы увидите, что типовые решения используют именно ту схему, которую мы разобрали выше: передача контекста формы в серверный общий модуль и работа через ИзменитьРеквизиты.
Резюмируем: Программное добавление элементов из общего модуля — это абсолютно штатная процедура. Главное — передавать объект формы параметром, работать на сервере и четко разделять создание структуры данных и создание элементов интерфейса.