Как программно выбрать нужный вариант отчета СКД из другой базы?

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

При интеграции различных систем на базе 1С часто возникает задача получения аналитических данных из одной конфигурации в другую. Одним из самых эффективных способов является использование механизмов Системы компоновки данных (СКД) через COM-соединение. Это позволяет не дублировать сложную логику расчетов, а использовать уже готовые отчеты. Однако при реализации такого подхода программисты часто сталкиваются с трудностями: как выбрать конкретный вариант настроек, созданный в конфигураторе, и как обработать внешние наборы данных. Рассмотрим эти вопросы подробно.

Этап 1: Установка внешнего соединения и получение схемы

Для начала проанализируем процесс подключения к базе-источнику. Мы используем объект V83.COMConnector для создания моста между базами. После успешного подключения нам необходимо получить доступ к метаданным отчета и его основной схеме компоновки.

Рассмотрим пример кода для инициализации соединения и получения макета схемы:


// Устанавливаем соединение с внешней базой (ЗУП, ERP или БП)
ПараметрыСоединения = "Srvr=""ServerName"";Ref=""BaseName"";Usr=""Admin"";Pwd=""111"";";
ВнешнееСоединение = Новый COMОбъект("V83.COMConnector");
Соединение = ВнешнееСоединение.Connect(ПараметрыСоединения);

// Получаем схему компоновки из нужного отчета
СхемаКомпоновки = Соединение.Отчеты.АнализНачисленийИУдержаний.GetTemplate("ОсновнаяСхемаКомпоновкиДанных");

Обратите внимание, что метод GetTemplate (или ПолучитьМакет) вызывается в контексте внешнего соединения. Это критически важно, так как объект схемы должен существовать в памяти той базы, где будут выполняться запросы к данным.

Этап 2: Программный выбор варианта настроек

В СКД может быть множество вариантов отчета («Краткий», «Подробный», «По сотрудникам» и т.д.). По умолчанию компоновщик берет основные настройки, но нам зачастую нужен конкретный вариант, в котором уже настроены группировки, отборы и выбранные поля. Выясним, как обратиться к нужному варианту.

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


// Выбираем конкретный вариант по его имени (например, "ЗПВыплачено")
ИмяВарианта = "ЗПВыплачено";
ВариантНастроек = СхемаКомпоновки.SettingVariants.Find(ИмяВарианта);

Если ВариантНастроек = Неопределено Тогда
    // Если по имени не нашли, можно обратиться напрямую через точку, если имя предопределенное
    ВариантНастроек = СхемаКомпоновки.ВариантыНастроек.ЗПВыплачено;
КонецЕсли;

НастройкиДляРаботы = ВариантНастроек.Settings; // Получаем объект настроек

Важно понимать разницу: ВариантыНастроек — это элементы схемы, а Настройки — это конкретный объект типа НастройкиКомпоновкиДанных, который мы будем загружать в компоновщик.

Этап 3: Инициализация компоновщика и установка параметров

После того как мы получили настройки варианта, их нужно применить к компоновщику настроек. Поскольку мы работаем через COM, все объекты (Компоновщик, Источник доступных настроек) должны создаваться через Соединение.NewObject().

Рассмотрим по шагам процесс настройки параметров данных, таких как период:


// Создаем компоновщик настроек во внешней базе
КомпоновщикНастроек = Соединение.NewObject("КомпоновщикНастроекКомпоновкиДанных");
ИсточникДоступныхНастроек = Соединение.NewObject("ИсточникДоступныхНастроекКомпоновкиДанных", СхемаКомпоновки);
КомпоновщикНастроек.Initialize(ИсточникДоступныхНастроек);

// Загружаем выбранные настройки варианта
КомпоновщикНастроек.LoadSettings(НастройкиДляРаботы);

// Устанавливаем параметры (например, Период)
// Помните: простые типы (Дата, Число) передаются легко, сложные объекты лучше разбирать
ПараметрПериод = КомпоновщикНастроек.Settings.DataParameters.Elements.Find("Период");
Если ПараметрПериод <> Неопределено Тогда
    ПараметрПериод.Value = ТекущаяДата(); // Устанавливаем нужную дату
    ПараметрПериод.Use = Истина;
КонецЕсли;

Этап 4: Решение проблемы внешних наборов данных

Разберем ситуацию, когда при выполнении метода Выполнить() возникает ошибка: «Не найден внешний набор данных». Это происходит, если в схеме компоновки используется тип Набор данных - объект. СКД ожидает, что вы передадите таблицу значений вручную во время инициализации процессора компоновки.

Чтобы решить эту проблему, выполним следующие действия:

  1. Выясним имя внешнего набора данных в схеме (например, "НачисленияУдержанияДокумента").
  2. Сформируем таблицу данных на стороне внешней базы.
  3. Передадим эту таблицу в структуру внешних наборов данных.

Проанализируем пример кода:


// Создаем структуру для внешних наборов данных
ВнешниеНаборыДанных = Соединение.NewObject("Структура");

// Если данные для набора нужно предварительно подготовить
// (например, запросом или программно во внешней базе)
ТаблицаДанных = Соединение.NewObject("ТаблицаЗначений");
// ... здесь логика заполнения таблицы ТаблицаДанных ...

// Добавляем таблицу в структуру. Ключ должен СТРОГО совпадать с именем в СКД
ВнешниеНаборыДанных.Insert("НачисленияУдержанияДокумента", ТаблицаДанных);

// Инициализируем процессор компоновки с учетом внешних данных
ПроцессорКомпоновки = Соединение.NewObject("ПроцессорКомпоновкиДанных");
ПроцессорКомпоновки.Initialize(МакетКомпоновки, ВнешниеНаборыДанных);

Этап 5: Вывод результата в коллекцию

На заключительном этапе нам необходимо получить результат компоновки. Чаще всего данные требуются в виде таблицы значений для последующей обработки в основной базе. Посмотрим, как это реализовать через ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений.


// Создаем макет компоновки
КомпоновщикМакета = Соединение.NewObject("КомпоновщикМакетаКомпоновкиДанных");
МакетКомпоновки = КомпоновщикМакета.Execute(СхемаКомпоновки, КомпоновщикНастроек.Settings);

// Выводим результат в таблицу значений (во внешней базе)
ПроцессорВывода = Соединение.NewObject("ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений");
ДанныеТЗ = Соединение.NewObject("ТаблицаЗначений");
ПроцессорВывода.SetObject(ДанныеТЗ);
ПроцессорВывода.Output(ПроцессорКомпоновки);

// Теперь ДанныеТЗ содержит результат отчета. 
// Однако обращение к строкам таблицы через COM может быть медленным.
// Рекомендуется скопировать данные в локальную таблицу значений.
ЛокальнаяТЗ = Новый ТаблицаЗначений;
// Пройдем по колонкам и строкам для переноса данных...

Важный совет: Если данных очень много, передача ТаблицыЗначений через COM-объект будет работать медленно из-за постоянных сетевых вызовов при обращении к каждой ячейке. В таких случаях эффективнее на стороне внешней базы сериализовать таблицу в XML или JSON, передать строку и десериализовать её уже в текущей базе.

Подведем итог: для успешного получения варианта отчета из другой базы необходимо не только подключиться через COMConnector, но и правильно инициализировать всю цепочку объектов СКД в контексте внешнего соединения, уделяя особое внимание коллекции SettingVariants и передаче внешних наборов данных в ПроцессорКомпоновкиДанных.

← На главную