Разберем частую ситуацию: мы переносим внешний отчет из одной конфигурации в другую (например, из 1С:ЗУП в 1С:БП), но при его формировании платформа выдает ошибку о том, что отсутствует определенное поле. Самое интересное, что в стандартных настройках и выбранных полях отчета это поле визуально отсутствует, а отладка модуля отчета не дает результатов. Выясним причину такого поведения и рассмотрим рабочие способы решения проблемы по шагам.
Первое правило при работе с СКД — чудес не бывает. Если система ищет поле, значит, оно где-то прописано. Проблемное поле может скрываться не только в пользовательских настройках, но и глубоко в структуре самой схемы. Проанализируем следующие разделы схемы компоновки:
Практический совет: Чтобы не искать поле вручную по всем вкладкам конфигуратора, выгрузите схему компоновки данных отчета в XML-файл и просто выполните текстовый поиск по имени пропавшего поля. Это самый быстрый способ найти, где именно оно застряло.
Рассмотрим подробнее механизм работы с внешними отчетами. Платформа 1С жестко привязывает пользовательские настройки к уникальному идентификатору (UUID) внешнего файла отчета. Если в базе-приемнике (например, БП) уже запускался отчет с таким же внутренним идентификатором или загрузились старые настройки, СКД попытается применить их к новой схеме.
В результате система начнет искать поле, которое сохранилось в кэшированном варианте отчета, но уже было удалено из текущего набора данных. Как это исправить:
Платформа 1С генерирует итоговый запрос СКД динамически. Из-за алгоритмов оптимизации и проверки прав система может автоматически исключать из запроса левые соединения и целые таблицы, если считает, что поля из них недоступны пользователю.
Проанализируем ситуацию: поле или таблица могут быть недоступны из-за отсутствия прав на чтение объекта метаданных или из-за ограничений на уровне записей (RLS). СКД тихо «вырезает» таблицу из запроса, а затем при попытке вывести данные сообщает: «Поле не найдено». Убедитесь, что у пользователя есть полные права на чтение всех реквизитов, используемых в наборе данных.
Также поле могло быть добавлено в ЗУП через расширение конфигурации, которое забыли перенести в БП. Либо реквизит отключен функциональной опцией, из-за чего он недоступен для выборки.
Если запрос СКД обращается к реквизитам через поля составного типа (например, регистратор), система может некорректно определять доступные поля. Посмотрим на пример решения: используйте функцию ВЫРАЗИТЬ() для явного указания нужного типа документа в тексте запроса. Это поможет СКД правильно построить дерево полей и избежать ошибок компоновки.
Для точной диагностики проблемы, если стандартные методы не помогают, мы можем перехватить компоновку программно и посмотреть фактический SQL-запрос, который пытается выполнить 1С.
Для этого в модуле объекта отчета в обработчике ПриКомпоновкеРезультата сгенерируем макет компоновки с помощью объекта КомпоновщикМакетаКомпоновкиДанных. Разберем код, который поможет нам это сделать:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
ДанныеРасшифровкиОтчета = Новый ДанныеРасшифровкиКомпоновкиДанных;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровкиОтчета);
// Остановимся здесь точкой останова в отладчике.
// Проанализируем МакетКомпоновки.НаборыДанных[0].Текст
// Это покажет реальный текст запроса, который платформа сформировала после всех оптимизаций.
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровкиОтчета);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Проанализировав свойство Текст у элементов набора данных полученного макета в отладчике, мы четко увидим, какие именно поля платформа попыталась включить в итоговый запрос, а какие обрезала, и сможем окончательно локализовать причину ошибки.