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