При разработке сложных систем на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью получить данные типового отчета не в виде печатной формы, а в виде таблицы значений для дальнейшей программной обработки. Однако иногда результат такого вывода может неприятно удивить: в таблице могут отсутствовать строки, которые прекрасно видны в обычном режиме работы отчета, или же вместо отрицательных чисел (например, убытка) в колонках ресурса оказываются нули.
Рассмотрим эту ситуацию на примере типового отчета АнализДоходовРасходов в конфигурации Управление торговлей 11. Разберем, почему возникает этот "глюк" и как правильно инициализировать схему компоновки данных, чтобы избежать потерь.
Обычно программист использует стандартную последовательность действий для получения данных из СКД в коллекцию. Проанализируем типичный фрагмент кода, который используется для этих целей:
// 1. Получаем схему и настройки
СхемаОст = Отчеты[ИмяОтчета].Создать().СхемаКомпоновкиДанных;
НастройкаОтчета = ВариантОтчетаСсылка.Настройки.Получить();
// 2. Инициализируем компоновщик
КомпоновщикНастроекНастройки = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроекНастройки.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаОст));
КомпоновщикНастроекНастройки.ЗагрузитьНастройки(НастройкаОтчета);
// 3. Устанавливаем параметры (период и т.д.)
КомпоновщикНастроекНастройки.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период", НужныйПериод);
// 4. Формируем макет для коллекции значений
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаОст, КомпоновщикНастроекНастройки.Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
// 5. Инициализируем процессор компоновки и выводим в ТЗ
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ДанныеТЗ = Новый ТаблицаЗначений;
ПроцессорВывода.УстановитьОбъект(ДанныеТЗ);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
На первый взгляд, код выглядит корректно. Однако именно здесь скрывается ловушка. В типовых конфигурациях (УТ 11, ERP, КА) отчеты — это не просто набор запросов в СКД. Это сложные механизмы, где часть логики вынесена в Модуль менеджера или Модуль объекта отчета.
Выясним причину, по которой данные могут искажаться. В СКД существуют параметры, которые могут быть помечены как Ограничение доступности. Это значит, что пользователь не видит их в форме настроек отчета. Однако эти параметры активно используются внутри запросов, особенно если речь идет о виртуальных таблицах или расчете сложных финансовых показателей, таких как ПрибыльУбыток.
Когда вы запускаете отчет в режиме предприятия, срабатывает событие ПриКомпоновкеРезультата. В типовых решениях в этом обработчике вызываются специальные процедуры (например, из общих модулей типа ОтчетыКлиентСервер.УстановитьПараметры...), которые программно дозаполняют скрытые параметры, такие как:
NULL или 0.Если вы просто загружаете сохраненные настройки и выполняете компоновку вручную, эти "служебные" параметры остаются пустыми. В результате запрос внутри СКД отрабатывает некорректно. Отрицательные значения могут отсекаться условиями ГДЕ или обнуляться функциями ЕСТЬNULL в выражениях ресурсов.
Для того чтобы программный вывод в таблицу значений соответствовал результату на экране, необходимо выполнить следующие действия:
Шаг 1. Анализ параметров схемы. Нам нужно внимательно изучить вкладку "Параметры" в схеме компоновки данных. Обратим внимание на те параметры, у которых стоит галочка "Ограничение доступности". Если в поле "Выражение" для них ничего не указано, значит, они должны заполняться программно.
Шаг 2. Проверка модуля менеджера. Посмотрим в модуль менеджера отчета. Найдем процедуру ПриКомпоновкеРезультата. Там мы увидим, какие именно параметры система устанавливает перед выводом. Например, для отчета "Анализ доходов и расходов" критично заполнение параметров валюты и учета НДС.
Шаг 3. Явное заполнение параметров в коде. Дополним наш код установкой этих значений. Если мы используем макет компоновки, значения параметров нужно устанавливать в КомпоновщикНастроек.Настройки.ПараметрыДанных перед вызовом КомпоновщикМакета.Выполнить или непосредственно в МакетКомпоновкиДанных.ЗначенияПараметров.
// Пример дозаполнения параметров
ПараметрыДанных = КомпоновщикНастроекНастройки.Настройки.ПараметрыДанных;
Если ПараметрыДанных.Элементы.Найти("ВалютаУправленческогоУчета") <> Неопределено Тогда
ПараметрыДанных.УстановитьЗначениеПараметра("ВалютаУправленческогоУчета", Константы.ВалютаУправленческогоУчета.Получить());
КонецЕсли;
Если ПараметрыДанных.Элементы.Найти("ВключатьНДС") <> Неопределено Тогда
ПараметрыДанных.УстановитьЗначениеПараметра("ВключатьНДС", Ложь);
КонецЕсли;
Проанализируем еще несколько технических моментов, которые могут приводить к потере данных при выводе в ТаблицаЗначений:
Типизация колонок. В отличие от табличного документа, ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений жестко типизирует колонки создаваемой таблицы значений. Если в СКД поле ресурса определено как Число(15, 2), но из-за некорректных параметров туда попадает NULL, платформа может инициализировать колонку типом Неопределено или Число со значением по умолчанию 0. Всегда проверяйте, чтобы ресурс в СКД имел четко заданный тип и выражение расчета ресурса было обернуто в ЕСТЬNULL(..., 0).
Иерархия и группировки. Если в настройках отчета, которые вы загружаете, установлены группировки (например, по иерархии статей), то при выводе в таблицу значений вы получите древовидную структуру или дублирующиеся итоги. Если вам нужны только "чистые" данные (детальные записи), перед выводом в ТЗ рекомендуется программно очистить структуру группировок в КомпоновщикНастроек.Настройки.Структура и оставить там только детальные записи.
Условное оформление. Помните, что условное оформление (например, выделение отрицательных чисел красным) при выводе в таблицу значений игнорируется. Если "исчезновение" минуса связано с тем, что в интерфейсе вы видите его благодаря какому-то хитрому форматированию, а в базе число хранится иначе — проверяйте именно исходные данные запроса.
Ситуация, когда программный вывод СКД отличается от визуального — это не "мистика" и не баг платформы, а следствие неполной инициализации контекста отчета. В современных конфигурациях 1С отчет — это сплав визуальных настроек СКД и программного кода в модулях. При программном обращении к отчету вся ответственность за заполнение скрытых параметров и фильтров ложится на плечи разработчика.
Главный совет: Если данные в таблице значений "чудят", сравните состав и значения параметров в объекте МакетКомпоновкиДанных непосредственно перед инициализацией процессора компоновки с теми параметрами, которые видны в консоли компоновки данных или в отладчике при обычном формировании отчета пользователем. Это кратчайший путь к поиску недостающего звена.