Как исправить ошибку СКД «В выборке должно быть указано хотя бы одно измерение или ресурс»?

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

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

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

Выясним причину: агрессивная оптимизация СКД

Разберем механизм работы платформы. В отличие от обычного запроса, текст которого остается неизменным, СКД — это динамический конструктор. Перед исполнением запроса компоновщик анализирует текущие настройки пользователя: выбранные поля, группировки, отборы и сортировки. На основе этого анализа СКД «пересобирает» исходный текст запроса, чтобы не выбирать лишние данные из базы.

Проанализируем ситуацию подробнее. Если в итоговых настройках отчета (на вкладке «Настройки» в схеме компоновки или в пользовательском режиме) не выбрано ни одно поле, которое «проистекает» из конкретной виртуальной таблицы (например, Остатки), СКД решает, что эта таблица не нужна. Однако, если эта таблица является частью пакета и на нее есть ссылки в других частях запроса, СКД может оставить обращение к ней в секции ИЗ, но полностью очистить секцию ВЫБРАТЬ.

В результате получается SQL-запрос вида ВЫБРАТЬ ПОМЕСТИТЬ ВТ_Остатки ИЗ РегистрБухгалтерии.Хозрасчетный.Остатки(...), где после ключевого слова ВЫБРАТЬ нет ни одного поля. Платформа 1С:Предприятие не умеет обрабатывать пустые выборки из виртуальных таблиц, что и приводит к ошибке «В выборке должно быть указано хотя бы одно измерение или ресурс».

Решение 1: Установка роли «Обязательное» для полей

Рассмотрим самый надежный и правильный метод решения проблемы через интерфейс схемы компоновки данных. Этот способ заставляет СКД всегда включать определенные поля в запрос, даже если пользователь не выбрал их в настройках отчета.

Разберем по шагам, как это сделать:

  1. Откроем Схему компоновки данных нашего отчета.
  2. Перейдем на закладку Наборы данных.
  3. Найдем наш набор данных (запрос) и в списке полей обратим внимание на колонку Роль.
  4. Нажмем на кнопку выбора в колонке роли для критически важных полей (например, тех, что выбираются из виртуальной таблицы Остатки).
  5. В открывшемся окне установим флаг Обязательное.

Когда поле помечено как обязательное, компоновщик не имеет права исключить его из секции ВЫБРАТЬ. Для виртуальных таблиц регистра бухгалтерии рекомендуется делать обязательными ключевые ресурсы (СуммаОстаток, КоличествоОстаток) или измерения (Счет, Субконто), если они используются в промежуточных временных таблицах.

Решение 2: Принудительное «протаскивание» полей через пакет запросов

Зачастую проблема кроется в том, что поля выбираются в первой временной таблице пакета, но не выбираются из нее в последующих таблицах или в финальном запросе. СКД видит, что результат поля в конечном итоге нигде не используется, и «отрезает» его в самом начале цепочки.

Посмотрим на пример логики исправления в тексте запроса. Предположим, у нас есть выборка остатков:


ВЫБРАТЬ
    Остатки.СуммаОстаток КАК Сумма
ПОМЕСТИТЬ ВТ_Данные
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, Счет = &Счет, , ) КАК Остатки
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Данные.Сумма
ИЗ
    ВТ_Данные КАК ВТ_Данные

Если в настройках отчета поле Сумма не выбрано, СКД может выкинуть его из обеих частей пакета. Чтобы этого избежать, мы можем использовать конструкцию фигурных скобок { }, которая управляет включением полей, или гарантировать выборку поля в конечном запросе. Однако, если мы хотим сохранить динамику, лучше всего объединить этот метод с установкой роли Обязательное в метаданных набора данных СКД.

Решение 3: Использование фиктивных группировок

Существует еще один технический прием. Если мы добавим поле в Группировки в настройках компоновки (даже если эта группировка не выводится или является вложенной), СКД будет обязана включить это поле в запрос. Но этот метод менее элегантен, так как перегружает настройки отчета лишними элементами.

Проанализируем ситуацию с виртуальными таблицами, использующими Автозаполнение. Если флаг «Автозаполнение» в наборе данных включен, СКД сама расставляет роли и доступные поля. Попробуем отключить автозаполнение и прописать все поля в секции {ВЫБРАТЬ ...} вручную. Это даст нам полный контроль над тем, какие измерения и ресурсы будут считаться доступными для компоновщика.

Решение 4: Диагностика через макет компоновки

Если причина ошибки не очевидна, нам необходимо увидеть тот запрос, который реально пытается выполнить платформа. Для этого можно использовать программный вывод отчета и проанализировать объект МакетКомпоновкиДанных.

Рассмотрим фрагмент кода для отладки в модуле отчета:


Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    // Здесь создается макет, который содержит реальные SQL-запросы
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
    
    // В этот момент в переменной МакетКомпоновки.НаборыДанных можно найти 
    // итоговый текст запроса и увидеть, что секция ВЫБРАТЬ пуста.
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(Результат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Изучив итоговый текст запроса в отладчике, мы точно увидим, на какой временной таблице «споткнулся» оптимизатор. Обычно там будет пустой список полей между ВЫБРАТЬ и ПОМЕСТИТЬ.

Важные рекомендации по работе с виртуальными таблицами в СКД

При проектировании сложных бухгалтерских отчетов (таких как «Карточка счета» или «Оборотно-сальдовая ведомость») следуйте этим правилам, чтобы избежать ошибок представления:

Подведем итог. Ошибка Ошибка обработки представления в СКД — это не ошибка вашего кода как такового, а результат работы «умного» генератора запросов 1С. Используя флаг «Обязательное» в ролях полей и контролируя прохождение данных через пакет запросов, вы сможете создавать стабильные и быстрые отчеты любой сложности.

← На главную