Как программно получить список реквизитов управляемой формы внешней обработки

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработчика 1С часто возникает задача: получить список всех реквизитов управляемой формы программным путем. Например, это может понадобиться для создания динамических настроек, построения универсальных печатных форм или автоматического заполнения данных. Однако платформа 1С накладывает существенные ограничения на доступ к метаданным формы «снаружи», особенно если речь идет о внешних обработках.

Разберем подробно, почему стандартные методы могут не работать на клиенте, и рассмотрим проверенные способы решения этой задачи.

Анализ проблемы: контекст исполнения и ограничения платформы

Основная сложность заключается в разделении контекстов между клиентом и сервером. Метод ПолучитьРеквизитыФормы() является методом контекста самой формы и доступен только на сервере. Когда мы находимся в сторонней форме и пытаемся получить объект другой формы через ПолучитьФорму(), мы получаем объект типа ФормаКлиентскогоПриложения. Передать этот объект обратно на сервер для анализа нельзя, так как объекты этого типа не сериализуются и не могут выступать параметрами серверных процедур.

Проанализируем ключевые моменты, которые нужно учитывать:

  1. Реквизиты vs Элементы: Коллекция ЭтаФорма.Элементы (кнопки, поля ввода, группы) доступна везде, но она содержит визуальные объекты. Коллекция реквизитов (данных) недоступна для прямого перебора извне.
  2. Внешние обработки: У внешних обработок нельзя просто прочитать метаданные через менеджер, так как состав реквизитов формы может отличаться от состава реквизитов самой обработки (объекта).
  3. Контекстный вызов: Единственный надежный способ вызвать ПолучитьРеквизиты() — сделать это внутри модуля самой формы, к которой мы обращаемся.

Способ 1: Использование экспортной функции в модуле формы

Если у нас есть возможность изменять код целевой обработки, это самый правильный и «чистый» метод. Мы создаем интерфейс взаимодействия, который позволит форме самой рассказать о своих реквизитах.

Рассмотрим реализацию. В модуле формы внешней обработки добавим следующую функцию:


&НаСервере
Функция ПолучитьСписокРеквизитовНаСервере() Экспорт
    
    МассивРезультат = Новый Массив;
    МассивРеквизитов = ПолучитьРеквизитыФормы();
    
    Для Каждого Реквизит Из МассивРеквизитов Цикл
        СтруктураРеквизита = Новый Структура;
        СтруктураРеквизита.Вставить("Имя", Реквизит.Имя);
        СтруктураРеквизита.Вставить("Заголовок", Реквизит.Заголовок);
        СтруктураРеквизита.Вставить("ТипЗначения", Реквизит.ТипЗначения);
        МассивРезультат.Добавить(СтруктураРеквизита);
    КонецЦикла;
    
    Возврат МассивРезультат;
    
КонецФункции

Теперь в вызывающем коде (в другой форме) мы можем легко получить эти данные:


&НаКлиенте
Процедура ПолучитьРеквизитыВнешнейФормы()
    
    ПутьКФайлу = "C:\MyExternalProcessing.epf";
    ИмяФормы = "ВнешняяОбработка.ИмяОбработки.Форма.ФормаОбъекта";
    
    // Получаем форму (на клиенте)
    ФормаОбъекта = ПолучитьФорму(ИмяФормы, , , Истина); 
    
    // Вызываем экспортную серверную функцию формы
    СписокРеквизитов = ФормаОбъекта.ПолучитьСписокРеквизитовНаСервере();
    
    // Обрабатываем результат
    Для Каждого СтрРеквизит Из СписокРеквизитов Цикл
        Сообщить("Найден реквизит: " + СтрРеквизит.Имя);
    КонецЦикла;
    
КонецПроцедуры

Способ 2: «Суррогатный» вызов через механизм оповещений

Бывают ситуации, когда нам нужно получить данные без явного открытия формы пользователю или когда мы хотим максимально универсализировать процесс. Рассмотрим оригинальный подход с использованием метода ОповеститьОВыборе().

Суть метода заключается в следующем: мы открываем форму программно, передаем ей специальный параметр, по которому она понимает, что открыта «для опроса», собирает данные о своих реквизитах на сервере и возвращает их через закрытие с результатом выбора.

В модуле вызываемой формы в обработчике ПриСозданииНаСервере или ПриОткрытии пропишем логику:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Если Параметры.Свойство("РежимПолученияСпискаРеквизитов") Тогда
        // Получаем массив объектов РеквизитФормы
        МассивРеквизитов = ПолучитьРеквизитыФормы();
        
        // Преобразуем в массив имен для передачи на клиент
        СписокИмен = Новый Массив;
        Для Каждого Рек Из МассивРеквизитов Цикл
            СписокИмен.Добавить(Рек.Имя);
        КонецЦикла;
        
        // Помещаем во временное хранилище или возвращаем напрямую
        Параметры.Вставить("РезультатРеквизиты", СписокИмен);
    КонецЕсли;
    
КонецПроцедуры

Важный нюанс: Чтобы форма не мелькала на экране, можно использовать параметры открытия с флагом закрытия или вообще не доводить до открытия, если данные получены в ПриСозданииНаСервере. Однако для внешних обработок удобнее использовать механизм ОповеститьОВыборе, вызываемый сразу после открытия в невидимом режиме.

Способ 3: Анализ элементов формы (если нельзя менять код)

Если форма чужая и добавлять в нее экспортные функции нельзя, проанализируем коллекцию Элементы. Это менее точный способ, так как не все реквизиты могут быть выведены на форму, но для задач UI (выбор поля для заполнения) он подходит идеально.

Выясним, как извлечь путь к данным из визуальных элементов. Нам понадобится серверная процедура, в которую мы передадим имя формы (не саму форму!).


&НаСервереБезКонтекста
Функция ПолучитьПутиКДаннымЭлементов(ИмяФормы)
    
    Результат = Новый СписокЗначений;
    
    // На сервере мы можем создать экземпляр формы по имени
    ТестоваяФорма = ПолучитьФорму(ИмяФормы);
    
    Для Каждого Элемент Из ТестоваяФорма.Элементы Цикл
        // Проверяем наличие свойства ПутьКДанным (есть у Полей, Таблиц и т.д.)
        Попытка
            Если ЗначениеЗаполнено(Элемент.ПутьКДанным) Тогда
                Результат.Добавить(Элемент.ПутьКДанным, Элемент.Заголовок);
            КонецЕсли;
        Исключение
            // Элемент не связан с данными (например, Группа или Декорация)
        КонецПопытки;
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции

Этот метод позволяет увидеть только те реквизиты, которые «видны» пользователю. Системные реквизиты или служебные переменные формы таким образом не получить. Для интерактивного исследования структуры и свойств открытых форм без написания кода можно использовать обработку для редактирования и анализа свойств управляемых форм.

Резюме и рекомендации

Подводя итоги нашего разбора, выделим основные правила работы с реквизитами управляемых форм:

Таким образом, несмотря на отсутствие прямой «рефлексии» (reflection) в 1С, задача решается через правильное использование контекстных серверных вызовов и понимание жизненного цикла управляемой формы.

← На главную