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