Как сериализовать управляемую форму в XML или JSON в режиме 1С:Предприятие?

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

В процессе разработки сложных систем автоматизации на платформе 1С:Предприятие иногда возникает необходимость получить полное описание интерфейса управляемой формы программным путем. Это может потребоваться для создания динамических форм, аудита интерфейсов, выгрузки метаданных «на лету» или сравнения конфигураций без использования конфигуратора. Однако стандартная попытка передать объект УправляемаяФорма в СериализаторXDTO или функцию ЗаписатьXML завершается ошибкой, так как этот объект не сериализуется платформой напрямую в режиме runtime.

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

---

Причина ограничения: почему форма не сериализуется «из коробки»

Для начала выясним причину проблемы. В конфигураторе 1С мы можем легко выгрузить конфигурацию в файлы, где каждая форма будет представлена в виде файлов XML (описание структуры и элементов интерфейса) и BSL (модуль формы). Платформа 1С:Предприятие выполняет эту операцию на уровне собственного ядра (написанного на C++), используя внутренние закрытые алгоритмы.

В режиме «1С:Предприятие» (в пользовательском сеансе) объект типа УправляемаяФорма, а также подчиненные ему объекты типов ГруппаФормы, ПолеФормы, КнопкаФормы и ТаблицаФормы не имеют признака сериализуемости. Они спроектированы исключительно для отображения интерфейса и управления интерактивным поведением. Попытка вызвать фабрику XDTO напрямую для формы выдаст системную ошибку о недопустимости сопоставления типов.

Давайте рассмотрим эффективные способы решения этой задачи.

---

Решение 1. Программный обход коллекции «Элементы» (Рекурсивный экспорт в JSON/XML)

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

Разберем этот алгоритм по шагам:

  1. Создадим рекурсивную функцию, которая принимает на вход родительский элемент формы (на верхнем уровне это сама форма ЭтаФорма).
  2. В цикле обойдем коллекцию Элементы.
  3. Для каждого элемента считаем его базовые свойства (имя, тип, видимость, доступность, заголовок).
  4. В зависимости от конкретного типа элемента (кнопка, поле, таблица) считаем специфические свойства (путь к данным, имя команды, вид поля).
  5. Если элемент является контейнером (например, ГруппаФормы или ТаблицаФормы), рекурсивно вызовем эту же функцию для обработки подчиненных элементов.

Посмотрим на пример реализации данного алгоритма на встроенном языке:


Функция ПолучитьСтруктуруЭлементов(РодительскийЭлемент) Экспорт

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

КонецФункции

После того как дерево элементов выгружено в массив структур, мы можем легко сериализовать полученный результат в формат JSON всего несколькими строками кода:


// Сериализация полученной структуры в JSON-строку
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();

ПараметрыЗаписи = Новый ПараметрыЗаписиJSON;
ЗаписатьJSON(ЗаписьJSON, ПолучитьСтруктуруЭлементов(ЭтаФорма), ПараметрыЗаписи);

СтрокаJSON = ЗаписьJSON.Закрыть();
// СтрокаJSON теперь содержит полное структурированное описание формы!

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

---

Решение 2. Использование системных хранилищ настроек

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

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

Проанализируем ситуацию на примере:


КлючОбъекта = "Справочник.Номенклатура.Форма.ФормаЭлемента/НастройкиФормы";
Пользователь = ИмяПользователя(); // Или конкретный пользователь, чьи настройки нас интересуют

// Загружаем настройки из системного хранилища
НастройкиФормы = ХранилищеСистемныхНастроек.Загрузить(КлючОбъекта, "", , Пользователь);

Если НастройкиФормы <> Неопределено Тогда
    // Результат представляет собой структуру настроек, которую можно сериализовать в XML
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку();
    
    СериализаторXDTO.ЗаписатьXML(ЗаписьXML, НастройкиФормы);
    XMLТекст = ЗаписьXML.Закрыть();
КонецЕсли;

Преимущества метода: Позволяет быстро «вытащить» XML-описание кастомного расположения элементов интерфейса, измененного пользователями в режиме предприятия.

---

Решение 3. Выгрузка в XML через CLI платформы в фоновом режиме

Если стоит бескомпромиссная задача получить оригинальный, эталонный файл XML-описания формы (точно такой же, как при выгрузке файлов конфигурации), то единственный рабочий способ — задействовать консольные утилиты платформы. Это можно сделать прямо из сеанса «1С:Предприятие» в фоновом режиме.

Рассмотрим этот процесс по шагам:

  1. Используя функцию ЗапуститьПриложение, мы вызываем утилиту командной строки ibcmd (для баз на платформе 8.3) или классический исполняемый файл designer.exe.
  2. Передаем параметры для частичной выгрузки конфигурации в файлы. Нам не нужно выгружать всю базу — мы указываем конкретный фильтр по объекту метаданных, например: /DumpFiles -Filter "Справочник.Номенклатура.Форма.ФормаЭлемента".
  3. Платформа выгрузит форму во временный каталог на диске. Там будут созданы файлы Form.xml (структура элементов и свойства формы) и Module.bsl (текст модуля формы).
  4. С помощью объекта ТекстовыйДокумент или ЧтениеXML мы считываем полученный XML-файл прямо из кода встроенного языка и обрабатываем его.

Пример кода для запуска выгрузки в фоновом режиме:


КаталогВыгрузки = КаталогВременныхФайлов() + "FormExport\";
СоздатьКаталог(КаталогВыгрузки);

ПараметрыЗапуска = "DESIGNER /F """ + ПутьКБазе + """ /N """ + Логин + """ /P """ + Пароль + """ /DumpPhysicalFiles """ + КаталогВыгрузки + """ -Filter ""Справочник.Номенклатура.Форма.ФормаЭлемента"" /Out ""log.txt""";

// Запуск процесса выгрузки во временный каталог
РезультатЗапуска = ЗапуститьПриложение(ПараметрыЗапуска, , Истина); // Третий параметр Истина заставит 1С ждать завершения выгрузки

Если РезультатЗапуска = 0 Тогда
    // Файл Form.xml успешно создан во временной папке. Считываем его:
    Чтение = Новый ЧтениеТекста;
    Чтение.Открыть(КаталогВыгрузки + "Справочник.Номенклатура.Форма.ФормаЭлемента\Form.xml", КодировкаТекста.UTF8);
    XMLОписаниеФормы = Чтение.Прочитать();
    Чтение.Закрыть();
КонецЕсли;

Преимущества метода: Вы получаете абсолютно точное, валидное и полное описание интерфейса формы, сгенерированное самим движком платформы 1С.

---

Решение 4. Использование XDTO и схемы logform

Как справедливо заметили участники обсуждения, у платформы 1С есть предопределенная модель XDTO для описания логической структуры управляемых форм. Пространство имен этой схемы: http://v8.1c.ru/8.2/managed-ui/logform.

Хотя напрямую передать живой объект формы в фабрику XDTO в режиме предприятия нельзя, мы можем использовать типы этой схемы для создания структуры XDTO-последовательностей. Если у вас есть XML-схема этой модели (ее можно извлечь из конфигурации), вы можете программно инициализировать объекты XDTO, соответствующие элементам формы, заполнить их свойствами реальных элементов и выполнить сериализацию через стандартный механизм ФабрикаXDTO.ЗаписатьXML().

Это более трудоемкий, но академически верный подход, гарантирующий соответствие структуры XML-документа внутренним стандартам 1С.

---

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

Мы проанализировали различные методы сериализации управляемой формы и можем сделать следующие выводы:

← На главную