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