При разработке динамических интерфейсов в 1С 8.3 программисты часто сталкиваются с необходимостью программного добавления элементов на форму. Основная сложность возникает в момент обработки события ПриИзменении: если элементов много и они созданы динамически, мы не можем просто обратиться к ним по заранее известному имени в коде. Разберем подробно, как правильно извлекать данные из таких элементов, избегая типичных ошибок.
Представим ситуацию: вы программно добавили на форму несколько полей ввода и назначили им один и тот же обработчик события ПриИзменении. В этот обработчик передается параметр Элемент, который содержит ссылку на элемент управления (поле ввода, флажок и т.д.), вызвавший событие. Наша задача — получить текущее значение, которое ввел пользователь, и использовать его в дальнейшей логике, например, для записи в таблицу параметров.
Рассмотрим стандартный заголовок такого обработчика на стороне клиента:
&НаКлиенте
Процедура ПриИзмененииПараметра(Элемент)
// Как здесь получить значение?
КонецПроцедуры
Проанализируем наиболее эффективный и правильный способ для управляемых форм. Поскольку в модуле формы ключевое слово ЭтотОбъект (а также ЭтаФорма, хотя оно считается устаревшим) предоставляет доступ к коллекции реквизитов формы, мы можем использовать имя элемента как ключ.
Если при программном создании вы дали элементу управления и реквизиту формы одинаковые имена, то получить значение можно следующим образом:
Значение = ЭтотОбъект[Элемент.Имя];
Почему это работает? В управляемом приложении 1С ЭтотОбъект внутри модуля формы — это сама форма. Обращаясь к ней через квадратные скобки, мы получаем доступ к значению реквизита по его строковому имени. Это идеально подходит для динамического кода, где имя реквизита хранится в свойстве Элемент.Имя.
Посмотрим на практический пример реализации, где данные сохраняются в служебную таблицу:
&НаКлиенте
Процедура ПриИзмененииПараметра(Элемент) Экспорт
// Ищем строку в таблице параметров по идентификатору элемента
МасИзменить = ТаблицаПараметров.НайтиСтроки(Новый Структура("Идентификатор", Элемент.Имя));
Если МасИзменить.Количество() Тогда
МасИзменить[0].ДанныеИзменены = Истина;
// Получаем значение реквизита формы динамически
МасИзменить[0].Значение = ЭтотОбъект[Элемент.Имя];
КонецЕсли;
КонецПроцедуры
Иногда имя элемента управления не совпадает с именем реквизита. В таких случаях следует использовать свойство элемента ПутьКДанным. Это свойство содержит строку, указывающую, с каким именно реквизитом связан данный элемент управления.
Рассмотрим, как это реализовать:
Элемент.ПутьКДанным.ЭтотОбъект[ПутьКДанным].Для простых реквизитов формы код будет выглядеть так:
ИмяРеквизита = Элемент.ПутьКДанным;
Значение = ЭтотОбъект[ИмяРеквизита];
В начале обсуждения часто всплывает вариант использования Элементы[Элемент.Имя].ТекстРедактирования. Проанализируем, почему этот путь является ошибочным:
ТекстРедактирования — это всегда строка. Если ваше поле предназначено для ввода даты или числа, вам придется вручную преобразовывать тип, что чревато ошибками.ПриИзменении платформа уже обновила значение связанного реквизита. Следовательно, правильнее и надежнее брать значение именно из реквизита через ЭтотОбъект.Если ваши программно созданные элементы находятся не в корне формы, а внутри таблицы (в колонках), то прямой доступ через ЭтотОбъект[Элемент.Имя] не даст нужного результата, так как значение принадлежит конкретной строке. В этом случае нужно использовать коллекцию ТекущиеДанные:
&НаКлиенте
Процедура ПриИзмененииЭлементаТаблицы(Элемент)
ДанныеСтроки = Элементы.ВашаТаблица.ТекущиеДанные;
Если ДанныеСтроки <> Неопределено Тогда
// Получаем значение из колонки, имя которой совпадает с именем элемента
Значение = ДанныеСтроки[Элемент.Имя];
КонецЕсли;
КонецПроцедуры
При программной работе с формой всегда помните о контексте исполнения. Большинство операций с данными в событии ПриИзменении можно выполнить на клиенте, не нагружая сервер лишними вызовами. Обращение к ЭтотОбъект[...] на клиенте работает быстро и возвращает уже типизированное значение.
Подведем итог:
ПриИзменении используйте конструкцию ЭтотОбъект[Элемент.Имя] для получения значения.ТекстРедактирования, так как это нарушает строгую типизацию данных в 1С.ПутьКДанным для определения источника.Использование этих методов позволит вам создавать гибкие, динамические интерфейсы, которые легко поддерживать и отлаживать.