При работе с Системой компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда запрос в консоли запросов возвращает данные, а программный вызов той же схемы выдает пустую таблицу значений. Это может сбивать с толку, так как визуально код кажется правильным. В данной статье мы подробно разберем, почему Результат = Новый ТаблицаЗначений остается пустым после выполнения процессора вывода, и проанализируем типичные ошибки при программной работе с макетом компоновки.
Разберем самый важный момент. СКД — это не просто выполнение запроса, это построение отчета на основе настроек. Даже если ваш запрос возвращает тысячи строк, процессор вывода ничего не запишет в ТаблицаЗначений, если в объекте Настройки не определена структура вывода.
Посмотрим на типичную ошибку в коде:
// Автор закомментировал добавление группировки, что привело к пустому результату
// ОсновнаяГруппировка = КомпоновщикСхемы.Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
// ОсновнаяГруппировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
Проанализируем ситуацию: если коллекция Настройки.Структура пуста, компоновщик макета создаст «пустой» макет. Для исправления необходимо убедиться, что в настройках есть хотя бы одна группировка (например, детальные записи). Если вы формируете настройки программно «с нуля», обязательно добавьте элемент структуры:
Группировка = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Группировка.Использование = Истина;
ПолеДетальныхЗаписей = Группировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
ПолеДетальныхЗаписей.Использование = Истина;
В сообщениях форума упоминается ошибка «Использование циклических параметров запрещено». Рассмотрим, почему она возникает. Это случается, когда имя параметра в запросе совпадает с именем поля в схеме или когда значение одного параметра зависит от другого через выражения в самой СКД.
Выясним причину на примере запроса автора:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка
ИЗ
Справочник.Номенклатура.Изменения КАК Номенклатура
ГДЕ
Номенклатура.Узел = &Узел
Если в схеме компоновки данных поле называется Узел и параметр называется Узел, СКД может запутаться в пространствах имен. Решение простое — переименуйте параметр в запросе, например в &УзелОбмена или &ПланОбменаУзел, и обновите настройки в компоновщике.
Проанализируем ситуацию, когда в консоли запросов данные есть, а в СКД — нет. Консоль запросов обычно игнорирует Функциональные опции (ФО). Если в вашей конфигурации справочник или его реквизиты связаны с функциональной опцией, которая выключена, СКД автоматически исключит эти поля из запроса «на лету».
Также не стоит забывать про RLS (Record Level Security). Если код выполняется не под полными правами, система ограничения прав доступа может неявно добавить условия в запрос, которые отсекут все строки. Чтобы проверить это, попробуйте выполнить код под пользователем с полными правами или временно отключите RLS для данного объекта. Для обхода ограничений прав также подойдёт способ формирования СКД в привилегированном режиме.
Часто программисты забывают, что КомпоновщикНастроек содержит несколько уровней настроек: основные настройки схемы, пользовательские настройки и текущие настройки. Рассмотрим правильный алгоритм загрузки настроек перед установкой параметров:
// Сначала загружаем настройки по умолчанию из схемы
КомпоновщикСхемы.ЗагрузитьНастройки(СхемаСКД.НастройкиПоУмолчанию);
// Только после этого ищем параметры и устанавливаем их
ПараметрДанных = КомпоновщикСхемы.Настройки.ПараметрыДанных.Элементы.Найти("УзелОбмена");
Если ПараметрДанных <> Неопределено Тогда
ПараметрДанных.Значение = ПланОбмена;
ПараметрДанных.Использование = Истина;
КонецЕсли;
Если пропустить ЗагрузитьНастройки, вы будете работать с абсолютно пустым объектом Настройки, где нет ни выбранных полей, ни структуры, ни параметров.
Проверьте, что поля, которые вы хотите видеть в ТаблицаЗначений, добавлены в Выбранные поля. Если поле доступно в наборе данных, но не отмечено галочкой в выбранных полях настроек компоновки, оно не попадет в итоговую таблицу. При использовании ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений, колонки таблицы значений создаются автоматически на основании именно выбранных полей компоновки.
Если вы зашли в тупик, воспользуйтесь следующим методом «перехвата» реального запроса, который генерирует СКД. Рассмотрим шаги:
МакетКомпоновки = КомпоновщикМакета.Выполнить(...).МакетКомпоновки.НаборыДанных, далее выберите ваш набор данных (обычно это НаборДанных1).Запрос.Этот текст запроса может сильно отличаться от того, что вы писали в конфигураторе, так как СКД добавляет туда условия отборов, параметры и проверки прав. Выполнив этот «финальный» запрос в консоли запросов с реальными параметрами, вы сразу увидите, почему он возвращает ноль строк.
Суммируя все вышесказанное, приведем эталонный код для выгрузки данных из СКД в таблицу:
СхемаСКД = ПолучитьМакет("МояСхемаВыгрузки");
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаСКД));
КомпоновщикНастроек.ЗагрузитьНастройки(СхемаСКД.НастройкиПоУмолчанию);
// Установка параметров
Параметр = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("ДатаНачала");
Если Параметр <> Неопределено Тогда
Параметр.Значение = ТекущаяДата();
Параметр.Использование = Истина;
КонецЕсли;
// Компоновка макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаСКД, КомпоновщикНастроек.ПолучитьНастройки(),,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
// Процессор компоновки
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
// Вывод в таблицу значений
РезультатТЗ = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(РезультатТЗ);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// Теперь РезультатТЗ содержит данные
Для Каждого Строка Из РезультатТЗ Цикл
// Обработка данных
КонецЦикла;
Соблюдение этой структуры и внимательная проверка имен параметров позволят избежать «пустого результата» и сделают работу с СКД предсказуемой и эффективной. Для упрощения программного формирования схемы и компоновки данных можно использовать модуль-обертку над объектной моделью СКД.