При написании запросов в системе 1С:Предприятие разработчики иногда сталкиваются с ситуацией, когда платформа выдает ошибку синтаксиса на, казалось бы, корректном коде. Типичный пример — попытка присвоить полю псевдоним top. В этой статье мы подробно разберем, почему это происходит, какие еще слова находятся под запретом и как элегантно обойти это ограничение, если вам критически важно получить на выходе именно такое имя поля.
Рассмотрим исходный код запроса, который вызывает затруднение:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| ""0"" КАК top
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
Результат = Запрос.Выполнить();
На первый взгляд запрос выглядит логично, однако платформа выдает ошибку. Проанализируем причину. Язык запросов 1С не является «чистым» SQL, но он транслируется платформой в SQL-диалект той системы управления базами данных (СУБД), которая используется (Microsoft SQL Server, PostgreSQL, IBM DB2 или Oracle).
Слово TOP является ключевым зарезервированным словом в T-SQL (используемом в MS SQL Server). Оно выполняет функцию ограничения количества строк в выборке — в языке 1С этому соответствует оператор ПЕРВЫЕ. Когда встроенный синтаксический анализатор 1С видит слово top в качестве псевдонима, он распознает его как зарезервированную конструкцию, что приводит к конфликту.
Интересно, что если изменить псевдоним на top1 или top_field, ошибка исчезает, так как эти слова не являются зарезервированными. Однако часто программисту требуется именно конкретное имя (например, для интеграции с внешним API, который ожидает JSON с ключом "top").
Прежде чем переходить к решениям, выясним, какие еще псевдонимы могут привести к аналогичным проблемам. Рекомендуется избегать использования следующих литералов в качестве имен полей:
SELECT, FROM, WHERE, GROUP, ORDER, HAVING, JOIN, LEFT, INNER.TABLE, INDEX, VIEW, COLUMN, TOP, DISTINCT.SUM, COUNT, MIN, MAX, AVG.VALUE, REF, TYPE (ЗНАЧЕНИЕ, ССЫЛКА, ТИП).Важно помнить, что в 1С отсутствует механизм экранирования псевдонимов в запросах. Если в обычном SQL мы могли бы написать [TOP] или "TOP", то в 1С такой синтаксис не поддерживается.
Самый распространенный и надежный способ — это использование допустимого псевдонима в самом запросе с последующим переименованием колонки в полученном результате. Рассмотрим этот процесс по шагам.
1. В тексте запроса укажем временный псевдоним, например, ВременныйTop.
2. Выгрузим результат запроса в объект ТаблицаЗначений.
3. Изменим имя колонки программно.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| ""0"" КАК ВременныйTop
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
ТЗ = Запрос.Выполнить().Выгрузить();
// Проверим наличие колонки и переименуем её
Если ТЗ.Колонки.Найти("ВременныйTop") <> Неопределено Тогда
ТЗ.Колонки.ВременныйTop.Имя = "top";
КонецЕсли;
Этот метод отлично работает, так как ограничения на имена колонок в ТаблицеЗначений менее строгие, чем в языке запросов. Теперь при передаче этой таблицы в другие функции или при ее обходе поле будет называться именно так, как вам нужно.
Если ваша задача — подготовить данные для выгрузки в JSON для веб-сервиса, то переименование колонок в таблице может быть избыточным. Проанализируем более гибкий подход с использованием коллекций значений.
При обходе результата запроса мы можем помещать данные в Структуру или Соответствие. Стоит учесть, что имя ключа в Структуре также подчиняется правилам именования переменных (хотя top в коде 1С обычно разрешен, в отличие от запросов). Если же имя ключа должно быть совсем специфическим (например, содержать спецсимволы), лучше использовать Соответствие.
Выборка = Запрос.Выполнить().Выбрать();
СписокРезультатов = Новый Массив;
Пока Выборка.Следующий() Цикл
ДанныеСтроки = Новый Структура;
ДанныеСтроки.Вставить("ссылка", Выборка.Ссылка);
ДанныеСтроки.Вставить("top", Выборка.ВременныйTop); // Ключ "top" в структуре разрешен
СписокРезультатов.Добавить(ДанныеСтроки);
КонецЦикла;
// Теперь СписокРезультатов можно сериализовать в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СписокРезультатов);
РезультатJSON = ЗаписьJSON.Закрыть();
В сложных интеграционных решениях удобно использовать «словарь преобразования». Это позволяет сделать код универсальным. Выясним, как это реализовать:
Соответствие, где ключом будет имя поля в запросе, а значением — требуемое имя для внешней системы.Такой подход позволяет избежать жесткого кодирования имен в тексте программы и делает систему более масштабируемой. Критически важно помнить: всегда разделяйте внутреннюю логику хранения данных в 1С и внешнее представление этих данных. Псевдонимы в запросах лучше делать понятными на русском языке (например, ПоказательТопа), а преобразование в top выполнять на самом последнем этапе формирования ответа.
Мы выяснили, что ошибка в псевдониме top — это не баг платформы, а следствие трансляции запроса в SQL. Использование зарезервированных слов напрямую в тексте запроса невозможно из-за отсутствия экранирования. Однако, комбинируя запросы с методами постобработки (переименование колонок ТаблицыЗначений) или используя коллекции (Структура, Соответствие), вы можете получить любую требуемую структуру данных для ваших задач.