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