При интеграции различных информационных систем на базе «1С:Предприятие» программисты часто сталкиваются с необходимостью получить настройки отчета или динамического списка из удаленной базы через COM-соединение. Одной из самых амбициозных задач в этом контексте является попытка вывести визуальный редактор отборов (часть КомпоновщикаНастроек) на управляемую форму текущей базы, чтобы пользователь мог интерактивно управлять фильтрацией данных в удаленной системе.
Рассмотрим ситуацию: мы успешно установили соединение, создали объект КомпоновщикНастроекКомпоновкиДанных в контексте COM, инициализировали его схемой, но при попытке назначить этот объект реквизиту формы получаем ошибку или пустую коллекцию. Проанализируем, почему это происходит и как решить задачу правильно.
Разберем основные причины технического ограничения, с которыми столкнулись участники обсуждения. Во-первых, для платформы 1С:Предприятие типы данных внутри текущей сессии и типы данных, полученные через COMОбъект, — это абсолютно разные сущности. Даже если в обеих базах используется одна и та же конфигурация, объект КомпоновщикНастроек из внешней базы для текущей базы является «вещью в себе».
Во-вторых, существует проблема контекста. COM-соединение обычно создается и живет на стороне сервера. Попытка «пробросить» COMОбъект на клиентскую часть (в форму) невозможна, так как этот объект не сериализуется стандартными средствами платформы для передачи между сервером и клиентом. Как только мы пытаемся присвоить реквизиту формы типа КомпоновщикНастроекКомпоновкиДанных значение, полученное из внешней базы, система выдает ошибку несоответствия типов.
Единственным надежным способом передачи сложных структур данных, таких как настройки компоновки, является их преобразование в промежуточный формат, понятный обеим сторонам. Идеально для этого подходит XML-сериализация. Нам необходимо превратить настройки компоновщика в COM-базе в строку XML, передать эту строку в нашу базу и восстановить из нее локальный объект.
Для начала нам нужно заставить удаленную базу «выгрузить» настройки в строку. Поскольку мы работаем через COM, мы используем методы XDTOSerializer или системную функцию XMLСтрока, если она доступна для данного типа в удаленном контексте. Посмотрим на пример кода, который выполняет эту операцию:
// В контексте текущей базы, где БазаЕРП - это установленное COM-соединение
НастройкиДляПередачи = БазаЕРП.КомпоновщикНастроек.Настройки;
СтрокаXML = БазаЕРП.XMLString(НастройкиДляПередачи);
// Или более универсальный способ через СериализаторXDTO
ЗаписьXML = БазаЕРП.NewObject("ЗаписьXML");
ЗаписьXML.SetString();
БазаЕРП.XDTOSerializer.WriteXML(ЗаписьXML, НастройкиДляПередачи);
СтрокаXML = ЗаписьXML.Close();
В этом фрагменте мы получаем объект настроек из COM и превращаем его в обычную текстовую строку. Строка без проблем передается с сервера на клиент и обратно.
Просто загрузить XML в пустой компоновщик недостаточно. Чтобы на форме отобразились доступные поля, виды сравнения и заголовки, компоновщик в вашей текущей базе обязательно должен быть инициализирован ИсточникомДоступныхНастроек. Это критически важный момент: если у вас в текущей базе нет схемы (СКД), аналогичной той, что в удаленной базе, редактор отбора будет пустым.
Рассмотрим, как подготовить локальный компоновщик:
// Создаем локальный компоновщик (реквизит формы с типом КомпоновщикНастроекКомпоновкиДанных)
// Допустим, у нас есть макет "ОсновнаяСхемаКомпоновкиДанных" в текущей обработке
СхемаСКД = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаСКД);
ЭтотОбъект.КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек);
Теперь, когда у нас есть текстовая строка XML из внешней базы и инициализированный локальный компоновщик, выполним «сборку» данных. Выясним, как правильно прочитать XML и применить настройки:
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаXML);
// Важно использовать локальный СериализаторXDTO
НовыеНастройки = СериализаторXDTO.ПрочитатьXML(ЧтениеXML, Тип("НастройкиКомпоновкиДанных"));
ЭтотОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(НовыеНастройки);
После выполнения метода ЗагрузитьНастройки(), локальный компоновщик, связанный с таблицей на форме, автоматически обновит визуальное представление. Пользователь увидит те же отборы, которые были установлены в базе-корреспонденте.
Проанализируем ситуацию, которая часто возникает при передаче отборов: наличие ссылочных типов. Если в базе ERP в отборе выбрана конкретная валюта USD, то в XML будет записана ссылка (обычно это GUID и тип). При десериализации в текущей базе система попытается найти объект с таким же уникальным идентификатором.
Важные нюансы сопоставления:
СправочникСсылка.Валюты может называться иначе или иметь другой внутренний идентификатор. В этом случае значение отбора превратится в «Объект не найден».GUID может отсутствовать в текущей базе.Для решения этой проблемы можно использовать один из двух подходов. Первый — предварительная синхронизация справочников. Второй — программный обход коллекции КомпоновщикНастроек.Настройки.Отбор.Элементы после загрузки и замена «битых» ссылок на актуальные локальные значения или представления.
Если по каким-то причинам XML-сериализация целиком вам не подходит, можно рассмотреть вариант ручного копирования элементов. Посмотрим на пример того, как можно обойти коллекцию COM-объектов:
// ЭлементыОтбораCOM - это коллекция из БазаЕРП
Для Каждого ЭлементCOM Из ЭлементыОтбораCOM Цикл
ЛокальныйЭлемент = ЭтотОбъект.КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЛокальныйЭлемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ЭлементCOM.ЛевоеЗначение);
ЛокальныйЭлемент.ВидСравнения = ВидСравненияКомпоновкиДанных[БазаЕРП.String(ЭлементCOM.ВидСравнения)];
// Здесь потребуется логика приведения типов для ПравогоЗначения
ЛокальныйЭлемент.Использование = ЭлементCOM.Использование;
КонецЦикла;
Этот метод значительно более трудоемкий, так как требует ручной обработки каждого свойства и каждого типа сравнения, но он позволяет тонко настроить сопоставление данных между базами.
Мы выяснили, что напрямую вывести Отбор из COM-соединения на форму невозможно из-за ограничений платформы на передачу контекстных объектов. Однако, используя XML-сериализацию настроек через XDTOSerializer и предварительную инициализацию локального КомпоновщикаНастроек правильной схемой компоновки, мы можем добиться полной визуальной идентичности и возможности редактирования внешних отборов.
Помните, что залог успеха в этом процессе — наличие идентичной (по именам полей) схемы компоновки данных в обеих базах и корректная обработка ссылочных типов данных при переносе настроек.