Почему запрос к регистру бухгалтерии перестает работать при переносе в СКД и как исправить ошибку «Поле не найдено (Субконто2)»?

Программист 1С v8.3 (Управляемые формы) Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При разработке отчетов в среде 1С:Предприятие программисты часто сталкиваются с ситуацией, когда идеально работающий в консоли запросов код внезапно выдает ошибку после переноса в Систему компоновки данных (СКД). Особенно часто это происходит при работе с виртуальными таблицами регистра бухгалтерии, такими как Остатки, Обороты или ОстаткиИОбороты, в том числе когда настраивается пользовательская СКД. Ошибка вида Ошибка обработки представления ... Поле не найдено (Субконто2) может поставить в тупик, так как в обычном запросе поле существует и данные по нему возвращаются. Проанализируем ситуацию, выясним причины такого поведения системы и разберем способы решения проблемы.

Причина возникновения ошибки в механизме СКД

Рассмотрим подробнее, как работают виртуальные таблицы бухгалтерии (как в решении универсальный отчет по проводкам). Поля Субконто1, Субконто2, Субконто3 не являются статическими полями таблицы базы данных. Это динамические псевдонимы, которые создаются «на лету» в зависимости от того, какие виды субконто переданы в соответствующий параметр виртуальной таблицы. В обычном запросе, когда мы передаем массив или список значений в параметр ВидыСубконто, платформа четко сопоставляет индекс в массиве с номером поля: первый элемент массива — это Субконто1, второй — Субконто2.

Однако при работе через СКД в дело вступает процессор компоновки данных. Он не просто выполняет ваш текст запроса, а перестраивает его (генерирует исполняемый запрос) на основе настроек пользователя, выбранных полей и группировок. Если СКД посчитает, что какое-то условие или поле является лишним для получения итогового результата, она может исключить параметр ВидыСубконто из запроса или изменить состав полей виртуальной таблицы. Как только из генерируемого запроса пропадает информация о том, что нужно выбирать именно два или три вида субконто, поле Субконто2 мгновенно перестает существовать для системы, что и вызывает ошибку Поле не найдено.

Решение 1: Настройка использования параметров в схеме компоновки

Посмотрим на настройки параметров в Схеме компоновки данных. Одной из самых частых причин является неверное значение в колонке «Использование» для параметра, отвечающего за виды субконто. По умолчанию там может стоять значение «Авто».

Проанализируем шаги для исправления:

  1. Откроем вкладку Параметры в СКД.
  2. Найдем параметр ВидыСубконтоКДД (или аналогичный, используемый в вашем запросе).
  3. Установим в колонке Использование значение Всегда.
  4. Убедимся, что для параметра установлен флаг Доступен список значений, если передается массив или список.

Установка режима «Всегда» принуждает СКД включать этот параметр в исполняемый запрос даже в тех случаях, когда компоновщик пытается его оптимизировать. Это гарантирует наличие полей Субконто1, Субконто2 в структуре виртуальной таблицы.

Решение 2: Программная установка параметров в ПриКомпоновкеРезультата

Если параметры заполняются программно, важно делать это правильно, чтобы СКД «подхватила» типы данных. Разберем пример кода, который необходимо разместить в модуле отчета в процедуре ПриКомпоновкеРезультата:


Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Инициализируем настройки
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Подготовим список видов субконто
    ВидыСубконтоКДД = Новый СписокЗначений;
    ВидыСубконтоКДД.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
    ВидыСубконтоКДД.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры);
    
    // Установим значение в параметры СКД
    ПараметрВидыСубконто = Настройки.ПараметрыДанных.Элементы.Найти("ВидыСубконтоКДД");
    Если ПараметрВидыСубконто <> Неопределено Тогда
        ПараметрВидыСубконто.Значение = ВидыСубконтоКДД;
        ПараметрВидыСубконто.Использование = Истина;
    КонецЕсли;

    // Далее выполняем стандартный вывод отчета
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(Результат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Обратите внимание, что мы устанавливаем Использование = Истина программно. Это критически важно для корректного формирования текста запроса процессором компоновки.

Решение 3: Оптимизация текста запроса для СКД

Рассмотрим ситуацию, когда использование конструкции ВЫРАЗИТЬ внутри параметров виртуальной таблицы вызывает сбои парсера СКД. Проанализируем исходный текст запроса. Использование типизации субконто непосредственно в условиях виртуальной таблицы — это хороший тон для производительности, но СКД может некорректно интерпретировать такие условия при построении вложенных запросов.

Попробуем изменить подход: выберем данные из виртуальной таблицы без типизации в условиях, а фильтрацию перенесем в секцию ГДЕ. Это сделает запрос более устойчивым к изменениям компоновщика.

Посмотрим на пример измененного запроса:


ВЫБРАТЬ
    ВзаиморасчетыОстатки.Организация КАК Организация,
    ВзаиморасчетыОстатки.Счет КАК Счет,
    ВЫРАЗИТЬ(ВзаиморасчетыОстатки.Субконто1 КАК Справочник.Контрагенты) КАК Контрагент,
    ВЫРАЗИТЬ(ВзаиморасчетыОстатки.Субконто2 КАК Справочник.ДоговорыКонтрагентов) КАК Договор,
    ВзаиморасчетыОстатки.СуммаРазвернутыйОстатокКт КАК СуммаКт
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Остатки(&ДатаСреза, Счет В (&СчетаПоставщиков), &ВидыСубконтоКДД, ) КАК ВзаиморасчетыОстатки
ГДЕ
    ВЫРАЗИТЬ(ВзаиморасчетыОстатки.Субконто2 КАК Справочник.ДоговорыКонтрагентов).ВидДоговора В (&ВидыДоговоров)
    И (ВзаиморасчетыОстатки.Организация = &Орг1 ИЛИ ВзаиморасчетыОстатки.Организация = &Орг2)

Важный момент: если вы используете Субконто2, вы обязаны передать в параметр ВидыСубконто список, в котором содержится не менее двух элементов. Если в какой-то момент в список попадет только один вид субконто, СКД просто не создаст поле Субконто2, и отчет упадет с ошибкой.

Использование консоли компоновки данных

Для окончательной диагностики рекомендуется использовать инструмент «Консоль компоновки данных». В отличие от обычной консоли запросов, она позволяет увидеть не тот текст, который вы написали в конфигураторе, а тот фактический SQL-подобный запрос, который СКД отправляет к СУБД. Проанализировав его, вы увидите, присутствуют ли в секции SELECT поля Subkonto2 и правильно ли передаются параметры в виртуальную таблицу.

Часто выясняется, что СКД «оптимизировала» запрос до такой степени, что удалила связи с субконто, так как они не были выведены в выбранные поля отчета. В этом случае добавление этих полей в список выбранных (даже если они скрыты) также помогает решить проблему.

Резюме действий для исправления ошибки:

Соблюдение этих правил позволит создавать надежные отчеты на базе СКД, корректно работающие с бухгалтерскими данными в любых режимах запуска.

← На главную