Почему в динамическом запросе 1С возникает ошибка «Неправильный псевдоним» при использовании конструкции ПЕРВЫЕ?

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

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

«Неправильный псевдоним Т.Ссылка» (или аналогичное поле выборки).

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

Анализ исходной ситуации

Рассмотрим типовой пример формирования динамического запроса к таблице изменений для плана обмена:


ТекстЗапроса = "ВЫБРАТЬ " + ?(КоличествоЭлементов = 0, "", "Первые " + КоличествоЭлементов)
    + "
    |    Т.Ссылка КАК Номенклатура
    |ИЗ
    |    Справочник." + ИмяСправочникаНоменклатура + ".Изменения КАК Т
    |ГДЕ
    |    Т.Узел = &Узел
    |    И ВЫБОР КОГДА &НомерСообщения = &Неопределено ТОГДА ИСТИНА
    |        ИНАЧЕ Т.НомерСообщения = &НомерСообщения
    |    КОНЕЦ";

Если переменная КоличествоЭлементов содержит значение от 1000 и выше (например, 1000), при выполнении запроса генерируется ошибка синтаксиса. При этом попытки переименовать псевдоним таблицы или поля (например, сменить Т на Тов или проверить русскую/латинскую раскладку символов) не дают результата.

Причина возникновения ошибки

Проанализируем, как платформа 1С преобразует числовые значения в строку при конкатенации:

  1. Неявное преобразование типов: При сложении строки с числом через оператор + платформа неявно преобразует число в строку с учетом региональных настроек текущего сеанса. По умолчанию для чисел от 1000 применяется группировка триад с использованием неразрывного пробела (символ НПП с кодом 160).
  2. Итоговый текст запроса: Выражение "Первые " + КоличествоЭлементов при значении 1000 превращается в строку "Первые 1 000".
  3. Специфика парсера запросов 1С: Парсер считывает конструкцию ВЫБРАТЬ Первые 1, где число 1 воспринимается как ограничение количества строк. Следующая часть 000 воспринимается парсером как первое поле списка выборки (числовой литерал). Идущее следом выражение Т.Ссылка парсер пытается интерпретировать как псевдоним для поля 000 (без оператора КАК), что приводит к синтаксической ошибке «Неправильный псевдоним» из-за наличия точки в имени псевдонима.

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

Способ 1. Использование функции Формат (Рекомендуемый способ)

Чтобы исключить появление неразрывных пробелов при формировании строки, необходимо явно отключить группировку разрядов с помощью параметра ЧГ=0 или ЧГ= в функции Формат.

Посмотрим на пример корректного формирования фрагмента запроса:


ОграничениеКоличества = ?(КоличествоЭлементов = 0, "", "ПЕРВЫЕ " + Формат(КоличествоЭлементов, "ЧГ=0") + " ");

ТекстЗапроса = 
    "ВЫБРАТЬ " + ОграничениеКоличества + "
    |    Т.Ссылка КАК Номенклатура
    |ИЗ
    |    Справочник." + ИмяСправочникаНоменклатура + ".Изменения КАК Т
    |ГДЕ
    |    Т.Узел = &Узел
    |    И ВЫБОР КОГДА &НомерСообщения = &Неопределено ТОГДА ИСТИНА
    |        ИНАЧЕ Т.НомерСообщения = &НомерСообщения
    |    КОНЕЦ";

Способ 2. Применение функции XMLСтрока

Функция XMLСтрока преобразует базовые типы данных (в том числе числа) в канонический формат XML без форматирования, региональных стандартов и разделителей групп разрядов. Это делает её удобным инструментом для вставки чисел в тексты запросов.

Разберем пример с использованием функции XMLСтрока и метода СтрШаблон для повышения читаемости кода:


СтрокаОграничения = ?(КоличествоЭлементов = 0, "", "ПЕРВЫЕ " + XMLСтрока(КоличествоЭлементов));

ТекстЗапроса = СтрШаблон(
    "ВЫБРАТЬ %1
    |    Т.Ссылка КАК Номенклатура
    |ИЗ
    |    Справочник.%2.Изменения КАК Т
    |ГДЕ
    |    Т.Узел = &Узел
    |    И ВЫБОР КОГДА &НомерСообщения = &Неопределено ТОГДА ИСТИНА
    |        ИНАЧЕ Т.НомерСообщения = &НомерСообщения
    |    КОНЕЦ",
    СтрокаОграничения,
    ИмяСправочникаНоменклатура
);

Способ 3. Использование штатного метода ПланыОбмена.ВыбратьИзменения

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

Платформа 1С предоставляет специализированный метод ПланыОбмена.ВыбратьИзменения, который нативно поддерживает порционную выборку данных через параметр РазмерВыборки:


// Параметры метода: Узел, НомерСообщения, Фильтр, РазмерВыборки
ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(Узел, НомерСообщения, , КоличествоЭлементов);

Пока ВыборкаИзменений.Следующий() Цикл
    ДанныеОбъекта = ВыборкаИзменений.Получить();
    // Обработка полученных данных
КонецЦикла;

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

← На главную