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