Как исправить ошибку «Ожидается выражение "ВЫБРАТЬ"» в 1С:Предприятии?

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

Каждый разработчик на платформе «1С:Предприятие» рано или поздно сталкивается с системным сообщением: «{(1, 1)}: Ожидается выражение "ВЫБРАТЬ"» (или аналогичным англоязычным вариантом Expected expression "SELECT"). Эта ошибка относится к классическим проблемам встроенного синтаксического анализатора (парсера) запросов 1С. Она возникает в тех случаях, когда платформа ожидает получить валидный текст запроса, но вместо этого на вход парсера поступает пустая строка, некорректный тип данных или поврежденный синтаксис.

Особенно часто, как справедливо отмечают практикующие разработчики на форумах, этот сбой проявляется при работе в тонком клиенте и использовании конструктора запросов для управляемых форм и динамических списков. В этой статье мы подробно проанализируем причины возникновения этой ошибки и разберем по шагам практические методы её устранения.

1. Инициализация конструктора с пустым текстом в консолях запросов

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

При вызове конструктора программный код консоли обычно пытается выполнить стандартный метод инициализации:


Конструктор = Новый КонструкторЗапроса(ТекстЗапросаВФорме);

Если поле ввода на форме абсолютно пустое, переменная ТекстЗапросаВФорме содержит пустую строку "". Платформа пытается распарсить эту строку как готовый запрос. Поскольку правила синтаксиса 1С требуют, чтобы любой запрос начинался с ключевого слова ВЫБРАТЬ (или ВЫБРАТЬ... ИЗ...), анализатор не находит этого слова и блокирует открытие конструктора, выдавая ошибку.

Как решить эту проблему:

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


ВЫБРАТЬ 1

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


Если СокращенноЛП(ТекстЗапросаВФорме) = "" Тогда
    ТекстЗапросаВФорме = "ВЫБРАТЬ 1";
КонецЕсли;
Конструктор = Новый КонструкторЗапроса(ТекстЗапросаВФорме);

2. Случайное выделение фрагментов текста в конфигураторе

Часто ошибка возникает непосредственно во время написания кода модуля в конфигураторе. Мы устанавливаем курсор на строку с текстом запроса, нажимаем правую кнопку мыши и выбираем пункт «Конструктор запроса...».

Проанализируем, почему в этот момент может произойти сбой. Если в процессе работы с кодом вы случайно выделили мышью даже один лишний символ (например, закрывающую скобку, пробел, запятую или кусок комментария) рядом с переменной запроса, конфигуратор попытается передать в конструктор именно этот выделенный некорректный фрагмент. Парсер моментально вернет ошибку ожидания выражения ВЫБРАТЬ.

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

3. Ошибки программного изменения динамических списков

Отдельного внимания заслуживает работа с динамическими списками в управляемых формах. Разработчики часто сталкиваются со сбоем парсера, когда пытаются динамически «на лету» модифицировать текст запроса списка.

Например, при изменении какого-либо фильтра на форме мы перестраиваем текст запроса динамического списка:


&НаСервере
Процедура ПриИзмененииОтбораНаСервере()
    // Опасный способ изменения запроса
    Текст = "ВЫБРАТЬ * ИЗ Справочник.Номенклатура ГДЕ Ссылка В (&МассивНоменклатуры)";
    Список.ТекстЗапроса = Текст;
КонецПроцедуры

Если в процессе формирования переменной Текст из-за сложного условия или ошибки в коде запишется пустая строка или некорректный синтаксис (например, забыли символ закрытия кавычки или перенос строки), то при попытке отобразить данные на клиенте платформа выдаст ошибку «Ожидается выражение "ВЫБРАТЬ"» и может аварийно завершить работу всего сеанса пользователя.

Как правильно поступать в таких случаях:

  1. Избегайте полного динамического перестроения строки текста запроса динамического списка. Вместо этого используйте параметры запроса и стандартные настройки компоновки данных.
  2. Если изменить текст запроса программно всё же необходимо, всегда делайте предварительную проверку результирующей строки в отладчике.
  3. Используйте безопасную установку параметров:

// Вместо изменения текста запроса используйте параметры
Список.Параметры.УстановитьЗначениеПараметра("ИспользоватьОтбор", Истина);
Список.Параметры.УстановитьЗначениеПараметра("МассивНоменклатуры", ПолучитьМассивДанных());

4. Конфликты с расширениями конфигурации в тонком клиенте

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

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

Тонкий клиент получает от сервера некорректно сформированное или поврежденное описание структуры данных. При попытке отобразить дерево таблиц конструктор "затыкается" на поврежденном узле, не может прочитать схему и падает с ошибкой «Ожидается выражение "ВЫБРАТЬ"», полностью блокируя дальнейшую работу.

Методы обхода проблемы с расширениями:

5. Передача неверных типов данных в построители

При использовании устаревших, но до сих пор популярных механизмов ПостроительЗапроса или ПостроительОтчета разработчики нередко совершают типичную ошибку при передаче параметров. Посмотрим на следующий пример кода:


// ОШИБОЧНЫЙ КОД
Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты");
Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(Запрос.Выполнить()); 

В данном случае разработчик ошибочно пытается передать в источник данных результат выполнения запроса вместо самого объекта Запрос. Построитель пытается интерпретировать переданные данные как структуру описания метаданных запроса, не находит в них текстового тела, начинающегося со слова ВЫБРАТЬ, и возвращает анализируемую нами ошибку.

Правильный вариант работы с построителем:


// ПРАВИЛЬНЫЙ КОД
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты";

Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(Запрос); // Передаем сам объект Запрос!

6. Оформление многострочного текста в коде модулей

Иногда синтаксическая ошибка возникает еще на этапе компиляции модуля в Конфигураторе, когда мы пишем текст запроса вручную на нескольких строках. Проанализируем типичную синтаксическую ошибку форматирования:


// Код, который вызовет ошибку компиляции
Запрос.Текст = "ВЫБРАТЬ
|   Ссылка
ИЗ
|   Справочник.Номенклатура";

Обратите внимание на слово ИЗ. Если при переносе строк была пропущена вертикальная черта | (обозначающая продолжение многострочного строкового литерала в 1С) или кавычка, синтаксический анализатор воспримет слово ИЗ как команду встроенного языка, а не часть строки запроса. Это приведет к нарушению всей структуры строки запроса, и компилятор выдаст ошибку ожидания выражения ВЫБРАТЬ.

Правильное оформление многострочного запроса:


Запрос.Текст = 
"ВЫБРАТЬ
|	Номенклатура.Ссылка КАК Ссылка,
|	Номенклатура.Код КАК Код
|ИЗ
|	Справочник.Номенклатура КАК Номенклатура";

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

Резюме

Мы подробно разобрали природу ошибки «Ожидается выражение "ВЫБРАТЬ"» в 1С. Чтобы быстро локализовать и устранить этот сбой, придерживайтесь простого алгоритма самопроверки:

  1. Если вы запускаете конструктор в консоли запросов — убедитесь, что поле ввода не пустое (напишите ВЫБРАТЬ 1).
  2. Если вы работаете в конфигураторе — проверьте, не выделен ли лишний текст на форме или в коде модуля.
  3. Если сбой происходит в тонком клиенте при выборе таблицы — попробуйте запустить сеанс в толстом клиенте или проверьте влияние активных расширений конфигурации.
  4. Если ошибка вылетает на динамическом списке — внимательно проанализируйте код, формирующий текст запроса этого списка в режиме реального времени.
← На главную