Как исправить ошибку «В случае использования операторов ОБЪЕДИНИТЬ, поля предложений УПОРЯДОЧИТЬ ПО и ИТОГИ ПО должны находиться в списке выбора» в 1С?

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

При доработке печатных форм и отчетов в конфигурациях 1С (например, 1С:Управление торговлей 10.3) разработчики часто сталкиваются с ошибкой синтаксиса запроса: «В случае использования операторов ОБЪЕДИНИТЬ, поля предложений УПОРЯДОЧИТЬ ПО и ИТОГИ ПО должны находиться в списке выбора».

Разберем подробно, почему возникает эта ошибка, какие правила языка запросов 1С нарушаются при составлении кода и как правильно исправить ситуацию на практических примерах.

Выясним причину возникновения ошибки

Проанализируем механику работы платформы 1С при объединении нескольких таблиц с помощью конструкций ОБЪЕДИНИТЬ или ОБЪЕДИНИТЬ ВСЕ. Ошибка возникает в двух основных случаях:

  1. Несовпадение количества выводимых полей в блоках выборки. Каждая секция ВЫБРАТЬ, участвующая в объединении, должна содержать строго одинаковое количество колонок. Если в первой выборке указано 11 полей, а во второй или третьей — 9 или 10, платформа не может сопоставить структуру результата и выдает ошибку.
  2. Отсутствие сортируемого поля в списке итоговой выборки. При использовании объединений предложение УПОРЯДОЧИТЬ ПО может обращаться только к тем полям и псевдонимам, которые явно присутствуют в самом первом блоке ВЫБРАТЬ (или во внешнем запросе, если объединение вынесено во вложенную таблицу). Если поле из УПОРЯДОЧИТЬ ПО сдвигается по позиции из-за пропущенных колонок в соседних ветках объединения, платформа не может его идентифицировать.

Способ 1. Выравнивание состава и порядка полей во всех ветках объединения

Рассмотрим ситуацию, когда в запросе объединяются данные из нескольких табличных частей (например, «Товары», «Услуги» и «ВозвратнаяТара»). Чтобы запрос с оператором ОБЪЕДИНИТЬ ВСЕ и конструкцией УПОРЯДОЧИТЬ ПО работал корректно, необходимо синхронизировать состав всех выборок.

Посмотрим на пример правильного заполнения недостающих полей пустыми значениями NULL или фиктивными значениями в каждом блоке:


Запрос.Текст = "
|ВЫБРАТЬ
|    ВложенныйЗапрос.Номенклатура КАK Номенклатура,
|    ВЫРАЗИТЬ(ВложенныйЗапрос.Номенклатура.НаименованиеПолное КАK Строка(1000)) КАK НаименованиеПолное,
|    ВложенныйЗапрос.Номенклатура.Код КАK Код,
|    ВложенныйЗапрос.Номенклатура.Артикул КАK Артикул,
|    ВложенныйЗапрос.Количество КАK Количество,
|    ВложенныйЗапрос.ЕдиницаИзмерения.Представление КАK ЕдиницаИзмерения,
|    ВложенныйЗапрос.Размещение КАK Размещение,
|    ВложенныйЗапрос.Характеристика КАK Характеристика,
|    NULL КАK Серия,
|    ВложенныйЗапрос.НомерСтроки КАK НомерСтроки,
|    ВложенныйЗапрос.Метка КАK Метка
|ИЗ
|    (ВЫБРАТЬ
|        ЗаказПокупателя.Номенклатура КАK Номенклатура,
|        ЗаказПокупателя.ЕдиницаИзмерения КАK ЕдиницаИзмерения,
|        ЗаказПокупателя.Размещение КАK Размещение,
|        СУММА(ЗаказПокупателя.Количество) КАK Количество,
|        ЗаказПокупателя.ХарактеристикаНоменклатуры КАK Характеристика,
|        МИНИМУМ(ЗаказПокупателя.НомерСтроки) КАK НомерСтроки,
|        0 КАK Метка
|    ИЗ
|        Документ.ЗаказПокупателя.Товары КАK ЗаказПокупателя
|    ГДЕ
|        ЗаказПокупателя.Ссылка = &ТекущийДокумент
|    СГРУППИРОВАТЬ ПО
|        ЗаказПокупателя.Номенклатура,
|        ЗаказПокупателя.ЕдиницаИзмерения,
|        ЗаказПокупателя.Размещение,
|        ЗаказПокупателя.ХарактеристикаНоменклатуры) КАK ВложенныйЗапрос
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|    ЗаказПокупателя.Номенклатура КАK Номенклатура,
|    ПРЕДСТАВЛЕНИЕ(ЗаказПокупателя.Номенклатура) КАK НаименованиеПолное,
|    ЗаказПокупателя.Номенклатура.Код КАK Код,
|    ЗаказПокупателя.Номенклатура.Артикул КАK Артикул,
|    ЗаказПокупателя.Количество КАK Количество,
|    ЗаказПокупателя.Номенклатура.ЕдиницаХраненияОстатков КАK ЕдиницаИзмерения,
|    NULL КАK Размещение,
|    NULL КАK Характеристика,
|    NULL КАK Серия,
|    ЗаказПокупателя.НомерСтроки КАK НомерСтроки,
|    1 КАK Метка
|ИЗ
|    Документ.ЗаказПокупателя.Услуги КАK ЗаказПокупателя
|ГДЕ
|    ЗаказПокупателя.Ссылка = &ТекущийДокумент
|
|УПОРЯДОЧИТЬ ПО
|    Метка ВОЗР,
|    НомерСтроки ВОЗР
|";

Обратим внимание: во втором блоке объединения (выборка услуг) явным образом добавлены отсутствующие поля NULL КАK Размещение, NULL КАK Характеристика и NULL КАK Серия. Порядок и количество колонок полностью совпадают с первым блоком, благодаря чему платформа свободно выполняет сортировку по полям Метка и НомерСтроки.

Способ 2. Оптимизация запроса при получении узкого набора данных

Проанализируем бизнес-задачу. Очень часто при создании специализированных документов (например, сборочного листа для склада) услуги или возвратная тара на печать выводиться не должны. В этом случае объединение с другими табличными частями оказывается лишним.

Если исключить ненужные операторы ОБЪЕДИНИТЬ ВСЕ, структура запроса существенно упрощается, а риск получения ошибок синтаксиса сводится к нулю:


Запрос.Текст = "
|ВЫБРАТЬ
|    ВложенныйЗапрос.Номенклатура КАK Номенклатура,
|    ВЫРАЗИТЬ(ВложенныйЗапрос.Номенклатура.НаименованиеПолное КАK Строка(1000)) КАK НаименованиеПолное,
|    ВложенныйЗапрос.Номенклатура.Код КАK Код,
|    ВложенныйЗапрос.Номенклатура.Артикул КАK Артикул,
|    ВложенныйЗапрос.Количество КАK Количество,
|    ВложенныйЗапрос.ЕдиницаИзмерения.Представление КАK ЕдиницаИзмерения,
|    ВложенныйЗапрос.Размещение КАK Размещение,
|    ВложенныйЗапрос.Характеристика КАK Характеристика,
|    NULL КАK Серия,
|    ВложенныйЗапрос.НомерСтроки КАK НомерСтроки,
|    ВложенныйЗапрос.Метка КАK Метка
|ИЗ
|    (ВЫБРАТЬ
|        ЗаказПокупателя.Номенклатура КАK Номенклатура,
|        ЗаказПокупателя.ЕдиницаИзмерения КАK ЕдиницаИзмерения,
|        ЗаказПокупателя.Размещение КАK Размещение,
|        СУММА(ЗаказПокупателя.Количество) КАK Количество,
|        ЗаказПокупателя.ХарактеристикаНоменклатуры КАK Характеристика,
|        МИНИМУМ(ЗаказПокупателя.НомерСтроки) КАK НомерСтроки,
|        0 КАK Метка
|    ИЗ
|        Документ.ЗаказПокупателя.Товары КАK ЗаказПокупателя
|    ГДЕ
|        ЗаказПокупателя.Ссылка = &ТекущийДокумент
|    СГРУППИРОВАТЬ ПО
|        ЗаказПокупателя.Номенклатура,
|        ЗаказПокупателя.ЕдиницаИзмерения,
|        ЗаказПокупателя.Размещение,
|        ЗаказПокупателя.ХарактеристикаНоменклатуры) КАK ВложенныйЗапрос
|
|УПОРЯДОЧИТЬ ПО
|    Метка ВОЗР,
|    НомерСтроки ВОЗР
|";

Рекомендации по предотвращению ошибок в запросах с объединениями

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