При разработке отчетов, выгрузок в формате CSV или подготовке данных для внешних систем программисты 1С часто сталкиваются с необходимостью изменить формат вывода строковых данных. Одной из типичных задач является обрамление текстового значения в двойные кавычки прямо на уровне SQL-запроса. Несмотря на кажущуюся простоту, здесь есть несколько подводных камней, связанных с типами данных и особенностями синтаксиса встроенного языка запросов 1С. Рассмотрим подробно, как решить эту задачу и какие ограничения существуют.
Для того чтобы добавить произвольные символы (включая кавычки) к результату поля в запросе, мы используем оператор конкатенации (сложения строк) — +. Однако в языке запросов кавычка является служебным символом, определяющим границы строкового литерала. Чтобы система восприняла кавычку как часть текста, её необходимо «экранировать» путем удвоения.
Разберем стандартный пример. Допустим, у нас есть поле Номенклатура.Наименование, и мы хотим получить его в кавычках. В конструкторе запроса или в тексте запроса это будет выглядеть следующим образом:
ВЫБРАТЬ
"""" + Номенклатура.Наименование + """" КАК НаименованиеВКавычках
ИЗ
Справочник.Номенклатура КАК Номенклатура
В этом примере """" (четыре кавычки подряд) означают следующее: крайние кавычки указывают, что внутри находится строковая константа, а две внутренние кавычки преобразуются в один символ кавычки в результирующей строке. Проанализируем ситуацию: если нам нужно добавить кавычку и в начале, и в конце, мы просто «склеиваем» эти литералы со значением поля таблицы.
Часто проблема возникает при попытке применить оператор + к полям, которые в базе данных имеют тип «Строка» с неограниченной длиной. В 1С такие поля (например, содержание документа или ссылки на фото, как в обсуждении) хранятся иначе, чем строки фиксированной длины. Прямая конкатенация для них запрещена и вызовет ошибку выполнения запроса.
Чтобы обойти это ограничение, необходимо использовать функцию ВЫРАЗИТЬ. Рассмотрим, как это сделать правильно:
ВЫБРАТЬ
"""" + ВЫРАЗИТЬ(НоменклатураСсылки.Фото КАК СТРОКА(1024)) + """" КАК ФотоВКавычках
ИЗ
РегистрСведений.НоменклатураСсылки КАК НоменклатураСсылки
Здесь крайне важно помнить о жестком ограничении платформы 1С: функция ВЫРАЗИТЬ для строковых типов в запросе поддерживает максимальную длину в 1024 символа. Если ваша строка (например, список ссылок на фотографии через точку с запятой) длиннее, она будет безвозвратно обрезана до этого лимита. Если вам требуется обрабатывать строки большей длины, добавление кавычек в самом запросе станет невозможным, и эту операцию придется перенести в код обработки результата запроса на встроенном языке. При возникновении ошибок несовместимости типов в процессе приведения полей неограниченной длины можно использовать руководство по исправлению ошибок ВЫРАЗИТЬ и сравнению строк в запросах.
Если вы формируете строку запроса динамически в модуле (в переменной типа Строка), количество кавычек увеличивается, что часто путает начинающих разработчиков. В языке 1С внутри строковой переменной символ кавычки также экранируется удвоением.
Посмотрим на пример формирования строки программно, чтобы в итоге получить рабочую конструкцию в запросе:
ТекстЗапроса = "ВЫБРАТЬ
| """""""" + ВЫРАЗИТЬ(Таблица.Поле КАК СТРОКА(100)) + """""""" КАК Результат
|ИЗ
| Справочник.Тест КАК Таблица";
Обратите внимание: чтобы в итоговом тексте запроса появилось """", в коде модуля нам нужно написать 8 кавычек подряд (""""""""). Каждые две кавычки в коде превращаются в одну в строковом значении. Таким образом, 8 кавычек в коде станут 4 кавычками в тексте запроса, которые, в свою очередь, превратятся в 1 кавычку в результате выполнения запроса SQL.
Если вам нужно добавить кавычки, значения которых передаются извне, можно воспользоваться параметрами. Это делает код более читаемым, особенно если вы проводите предварительный анализ структуры метаданных. Разберем такой случай:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| &Кавычка + ВЫРАЗИТЬ(Регистр.Данные КАК СТРОКА(250)) + &Кавычка КАК ПолеСКавычками
|ИЗ
| РегистрСведений.Данные КАК Регистр";
Запрос.УстановитьПараметр("Кавычка", """"); // Здесь мы передаем одну кавычку как параметр
Этот метод позволяет избежать нагромождения кавычек в самом тексте запроса, делая его структуру прозрачной.
В некоторых случаях вместо ВЫРАЗИТЬ можно использовать функцию ПОДСТРОКА. Она также позволяет работать со строками неограниченной длины, преобразуя их в строки фиксированной длины. Рассмотрим пример:
ВЫБРАТЬ
"""" + ПОДСТРОКА(Таблица.ДлинныйТекст, 1, 1024) + """" КАК Результат
ИЗ
Документ.Событие КАК Таблица
Функция ПОДСТРОКА(Поле, Начало, Длина) вернет строку указанной длины (максимум также 1024), что позволит системе успешно выполнить операцию сложения строк. Если в дополнение к ограничению длины вам необходимо узнать точный размер текстового поля на уровне базы данных, можно использовать метод определения длины строки в запросе.
Проанализируем ситуации, когда лучше перенести логику оформления данных на другие уровни системы:
Результат = """" + Выборка.Фото + """";.=""значение"".Таким образом, мы выяснили, что основной секрет успеха заключается в правильном определении типа данных поля (ограниченная или неограниченная строка) и соблюдении правил экранирования. Выбор между ВЫРАЗИТЬ в запросе и постобработкой в коде должен зависеть прежде всего от максимально возможной длины ваших данных.