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