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