При интеграции различных конфигураций 1С (например, БГУ и ЗКГУ) часто возникает необходимость получения аналитических данных, которые уже реализованы в типовых отчетах одной из баз. Использование COM-соединения для обращения к Системе Компоновки Данных (СКД) — мощный инструмент, но он сопряжен с рядом тонкостей: от ошибок инициализации объектов до ограничений вывода данных в коллекции. Рассмотрим подробно, как преодолеть основные препятствия и эффективно «дернуть» данные из внешнего отчета. Для выявления расхождений после подобных доработок или обмена можно автоматически сравнить бухгалтерские и налоговые проводки через COM-соединение.
Часто программисты пытаются получить схему компоновки напрямую через менеджер отчетов, используя конструкцию вида ВнешнееСоединение.Отчеты.ИмяОтчета.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"). На этом этапе нередко возникает ошибка «Несоответствие типов». Проанализируем причину: это происходит из-за того, что контекст менеджера отчета во внешнем соединении может быть не полностью инициализирован для прямой передачи макета как объекта СКД в вызывающую базу.
Чтобы избежать этой проблемы, используем более надежный метод — создание объекта отчета. Это гарантирует, что все внутренние механизмы и свойства объекта (включая схему) будут доступны корректно. Посмотрим на правильный пример инициализации:
// Вместо прямого обращения к макету создаем объект отчета
ОтчетОбъект = ВнешнееСоединение.Отчеты.АнализНачисленийИУдержаний.Создать();
СхемаКомпоновкиДанных = ОтчетОбъект.СхемаКомпоновкиДанных;
// Теперь СхемаКомпоновкиДанных — это полноценный объект COM-соединения
Этот подход позволяет избежать «капризов» платформы при десериализации метаданных через COM-прослойку.
Следующий «камень преткновения» — ошибка «Не поддерживается вывод таблиц и диаграмм в универсальную коллекцию значений». Она возникает при использовании ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений, когда в настройках отчета (СКД) структура включает в себя элементы типа «Таблица» или «Диаграмма». Коллекция значений (Таблица значений или Дерево значений) по своей сути линейна или иерархична, но она не может хранить многомерную структуру кросс-таблицы.
Выясним, как выйти из этой ситуации. Единственный верный способ — программно изменить структуру настроек перед компоновкой макета, удалив из нее сложные элементы и заменив их на простую группировку. Разберем этот процесс по шагам:
ГруппировкаКомпоновкиДанных.Проанализируем программную реализацию этого алгоритма:
// 1. Очищаем структуру настроек, чтобы избавиться от таблиц и диаграмм
КомпоновщикНастроекНастройки.Настройки.Структура.Очистить();
// 2. Создаем новую детальную запись (группировку без полей группировки)
НоваяГруппировка = КомпоновщикНастроекНастройки.Настройки.Структура.Добавить(ВнешнееСоединение.Тип("ГруппировкаКомпоновкиДанных"));
НоваяГруппировка.Использование = Истина;
// 3. Если нужно получить просто плоский список данных, добавляем автополе или конкретные поля
ВыбранноеПоле = НоваяГруппировка.Выбор.Элементы.Добавить(ВнешнееСоединение.Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
ВыбранноеПоле.Использование = Истина;
После такой манипуляции ПроцессорВывода успешно отработает, так как структура станет совместимой с форматом ТаблицаЗначений. Для упрощения программной настройки структуры и элементов схемы можно использовать модуль для быстрого формирования структуры СКД.
Если в базе-источнике (например, ЗКГУ) уже настроен идеальный вариант отчета, нам не обязательно настраивать всё с нуля. Мы можем программно загрузить настройки конкретного варианта. Рассмотрим, как это сделать:
Все предопределенные варианты хранятся в свойстве схемы ВариантыНастроек. Нам нужно найти подходящий по имени и передать его настройки в компоновщик:
ИмяНужногоВарианта = "РасчетныйЛисток"; // Имя из Конфигуратора
Для каждого Вариант Из СхемаКомпоновкиДанных.ВариантыНастроек Цикл
Если Вариант.Имя = ИмяНужногоВарианта Тогда
КомпоновщикНастроекНастройки.ЗагрузитьНастройки(Вариант.Настройки);
Прервать;
КонецЕсли;
КонецЦикла;
Важный нюанс: Если вы загрузили настройки варианта, который содержит таблицы, вам все равно придется выполнить очистку структуры (как описано выше), иначе ошибка вывода в коллекцию сохранится. Вы можете сначала загрузить настройки (чтобы получить параметры и отборы), а затем программно упростить структуру до группировки.
При установке параметров через COM-соединение крайне важно следить за типами. Объект СтандартныйПериод вызывающей базы (БГУ) не является идентичным объекту СтандартныйПериод внешней базы (ЗКГУ) с точки зрения COM. Поэтому всегда передавайте простые типы — Дата, Число, Строка или Булево.
Рассмотрим пример правильной установки периода:
// ПериодБГУ - это переменная типа СтандартныйПериод в вашей текущей базе
НачалоПериода = ПериодБГУ.ДатаНачала;
КонецПериода = ПериодБГУ.ДатаОкончания;
ПараметрыДанных = КомпоновщикНастроекНастройки.Настройки.ПараметрыДанных;
ПараметрыДанных.УстановитьЗначениеПараметра("НачалоПериода", НачалоПериода);
ПараметрыДанных.УстановитьЗначениеПараметра("КонецПериода", КонецПериода);
Также помните, что если в СКД параметр является вложенным (например, входит в состав другого параметра), обращение к нему может потребовать использования метода Найти в коллекции значений параметров.
Когда вы выполнили ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных), вы получаете объект ТаблицаЗначений, который физически находится в памяти внешней базы. Если вы начнете обходить эту таблицу обычным циклом Для каждого Строка Из ДанныеТЗ в основной базе, каждое обращение к ячейке будет инициировать сетевой вызов через COM-прослойку. При объеме в несколько тысяч строк это займет вечность.
Разберем стратегию ускорения. Самый эффективный способ — превратить таблицу в строку (XML или JSON) на стороне внешней базы и передать одну длинную строку в основную базу. Посмотрим, как это реализовать через СериализаторXDTO:
// На стороне ВнешнегоСоединения (внешняя база)
ЗаписьXML = ВнешнееСоединение.NewObject("ЗаписьXML");
ЗаписьXML.УстановитьСтроку();
ВнешнееСоединение.СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ДанныеТЗ);
СтрокаДанных = ЗаписьXML.Закрыть();
// В основной базе (БГУ)
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаДанных);
ТЗ_Локальная = СериализаторXDTO.ПрочитатьXML(ЧтениеXML, Тип("ТаблицаЗначений"));
Этот метод позволяет передать весь объем данных за один вызов, что сокращает время работы алгоритма в десятки раз. Теперь у вас в руках полноценная локальная ТаблицаЗначений, с которой можно работать стандартными средствами 1С. Для прямой выгрузки результатов отчета в структурированный формат также можно использовать процессор вывода результата компоновки данных в JSON.
Подведем итог нашей совместной работы по получению данных СКД через COM:
ОтчетОбъект через ВнешнееСоединение для получения схемы.КомпоновщикНастроек и загружаем настройки (из варианта или по умолчанию).Настройки.Структура и добавляем простую группировку, если планируем вывод в ТаблицаЗначений.Следуя этим правилам, вы сможете эффективно интегрировать отчетность различных систем, используя всю мощь СКД без необходимости переписывания сложных запросов вручную. Если операцию требуется выполнять регулярно, можно автоматизировать регулярный обмен данными между базами по расписанию.