Долгое время искал способ программного добавления реквизитов на обычную форму. Не хотелось изменять и включать возможность редактирования у типовой формы, так как это вызывает трудности при обновлении типовой конфигурации. Но в виду того что надо было добавить один - два реквизита в один - два типовых документам, острой необходимости не было. И вот потребовалось добавить в более чем 30 документах реквизит "Подразделение организации" с типом справочник "Подразделения организаций", справочник типовой.
Итак. В данном случае выводим новые реквизиты снизу формы. Исходим от того, что у нас в типовых формах есть процедура обновления заголовка, которая выводить текущее состояние документа (новый, проведен, не проведен или записан), в ней и вызовем процедуру вывода новых реквизитов.
Вкраце последовательность действий:
1. Выводиться форма
2. Увеличиваем высоту формы на общую высоту добавляемых реквизитов (некая высота - n).
3. Обратно уменьшаем высоту растягиваемых элементов на n, а остальные элементы формы, которые прикреплены к нижнему краю, смещаем на n вверх.
4. Добавляем новые реквизиты, устанавливаем их свойства и привязки. Profit!
На форме появляются новые реквизиты, привязки корректно отрабатывают, так как мы их не трогали и не меняли. Раньше моя ошибка заключалась в том что я пытался отключить привязку элементов к нижней границе формы, а после добавления новых элементов, пытался их восстановить. В итоге формы нещадно глючили, ломались привязки. А решение оказалось на поверхности. Не надо трогать привязки, все корректируется высотой и положением самого элемента.
З.Ы. Возможно будут проблемы с элементами которые привязаны к нижней границе через другой элемент, но в моих 30 документах такого не наблюдалось. В крайнем случае можно сохранить параметры всех элементов на форме: верхняя точка и высота элемента. И после увеличения высоты формы восстановить эти параметры.
Примеры кода, думаю комментариев будет достаточно:
Функция ВыводитьДополнительныеРеквизиты(ДокументОбъект, ФормаДокумента)
Результат = Ложь;
Если ДокументОбъект.Метаданные().Реквизиты.Найти("ПодразделениеОрганизации") <> Неопределено Тогда
Для Каждого Стр из ФормаДокумента.ЭлементыФормы Цикл
Если Стр.Данные = "ПодразделениеОрганизации" Тогда
Возврат Результат;
КонецЕсли;
КонецЦикла;
Результат = Истина;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ВыводДополнительныхРеквизитов(ДокументОбъект, ФормаДокумента) Экспорт
// Проверка на наличие дополнительных реквизитов
Если Не ВыводитьДополнительныеРеквизиты(ДокументОбъект, ФормаДокумента) Тогда Возврат КонецЕсли;
// Вывод или сохранение дополнительных реквизитов
// Если элемент формы существует то сохраняем значение
Элемент = ФормаДокумента.ЭлементыФормы.Найти("_ПодразделениеОрганизации");
Если Элемент = Неопределено Тогда
ВысотаОбщаяДобавляемыхЭлементовПоВертикали = 27; // Общая высота всех добавляемых элементов
ВысотаОдногоЭлемента = 19;
ВысотаНижнейПанели = 0; // будет вычислятся если нижняя панель есть
РасстояниеМеждуЭлементами = 8;
// Увеличение высоты
ФормаДокумента.Высота = ФормаДокумента.Высота + ВысотаОбщаяДобавляемыхЭлементовПоВертикали;
// Обработка элементов формы
Для Каждого Стр из ФормаДокумента.ЭлементыФормы Цикл
_ПервыйЭлемент = Неопределено;
_ГраницаПервогоЭлемента = Неопределено;
_ВторойЭлемент = Неопределено;
_ГраницаВторогоЭлемента = Неопределено;
Стр.ПолучитьПривязку(ГраницаЭлементаУправления.Низ, _ПервыйЭлемент, _ГраницаПервогоЭлемента, _ВторойЭлемент, _ГраницаВторогоЭлемента);
Если _ПервыйЭлемент = ФормаДокумента.Панель И _ГраницаПервогоЭлемента = ГраницаЭлементаУправления.Низ Тогда
// Исключаем нижнюю панель команд
Если ВРЕГ(СокрЛП(Стр.Имя)) = "ОСНОВНЫЕДЕЙСТВИЯФОРМЫ" Тогда
ВысотаНижнейПанели = Стр.Высота;
Продолжить;
КонецЕсли;
// У растягиваемых элементов уменьшаем высоту, а элементы с фиксированной высотой смещаем вверх
Стр.ПолучитьПривязку(ГраницаЭлементаУправления.Верх, _ПервыйЭлемент, _ГраницаПервогоЭлемента, _ВторойЭлемент, _ГраницаВторогоЭлемента);
Если _ПервыйЭлемент = ФормаДокумента.Панель И _ГраницаПервогоЭлемента = ГраницаЭлементаУправления.Низ Тогда
Стр.Верх = Стр.Верх - ВысотаОбщаяДобавляемыхЭлементовПоВертикали;
Иначе
Стр.Высота = Стр.Высота - ВысотаОбщаяДобавляемыхЭлементовПоВертикали;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ПоложениеПервогоЭлемента = ФормаДокумента.Высота - ВысотаОбщаяДобавляемыхЭлементовПоВертикали - ВысотаНижнейПанели - ВысотаОбщаяДобавляемыхЭлементовПоВертикали;
// Создание заголовка
Элемент = ФормаДокумента.ЭлементыФормы.Добавить(Тип("Надпись"), "_ЗаголовокПодразделениеОрганизации", Истина, ФормаДокумента.Панель);
Элемент.Заголовок = "Подразделение организации:";
// Настройка
Элемент.Лево = РасстояниеМеждуЭлементами;
Элемент.Верх = ПоложениеПервогоЭлемента;
Элемент.Высота = ВысотаОдногоЭлемента;
Элемент.Ширина = 155;
// Установка привязок
Элемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ФормаДокумента.Панель, ГраницаЭлементаУправления.Низ);
Элемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ФормаДокумента.Панель, ГраницаЭлементаУправления.Низ);
Элемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, ФормаДокумента.Панель, ГраницаЭлементаУправления.Лево);
Элемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ФормаДокумента.Панель, ГраницаЭлементаУправления.Лево);
// Создание поле ввода
Элемент = ФормаДокумента.ЭлементыФормы.Добавить(Тип("ПолеВвода"), "_ПодразделениеОрганизации", Истина, ФормаДокумента.Панель);
Элемент.ТипЗначения = Новый ОписаниеТипов("СправочникСсылка.ПодразделенияОрганизаций");
Элемент.Данные = "ПодразделениеОрганизации";
// Настройка
Элемент.Лево = РасстояниеМеждуЭлементами + 155 + РасстояниеМеждуЭлементами;
Элемент.Верх = ПоложениеПервогоЭлемента;
Элемент.Высота = ВысотаОдногоЭлемента;
Элемент.Ширина = ФормаДокумента.Ширина - (РасстояниеМеждуЭлементами * 3) - 155;
// Установка привязок
Элемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ФормаДокумента.Панель, ГраницаЭлементаУправления.Низ);
Элемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ФормаДокумента.Панель, ГраницаЭлементаУправления.Низ);
Элемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, ФормаДокумента.Панель, ГраницаЭлементаУправления.Право);
Элемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ФормаДокумента.Панель, ГраницаЭлементаУправления.Лево);
// Заполнение значения
Если ДокументОбъект.ЭтоНовый() Тогда
Элемент.Значение = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глЗначениеПеременной("глТекущийПользователь"), "ОсновноеПодразделениеОрганизации");
КонецЕсли;
КонецЕсли;
КонецПроцедуры