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