Как в 1С записать одну кавычку и убрать удвоение

· 9 мин

Содержание

Двойная кавычка внутри строки в 1С пишется удвоением: чтобы получить один символ ", в коде нужно поставить два подряд. Это не ошибка платформы, а механизм экранирования. Если нужна ровно одна кавычка в значении — берите Символ(34) или заменяйте удвоенные кавычки на одинарные функцией СтрЗаменить.

Удвоение всплывает в трёх местах: в строковых литералах встроенного языка, в тексте запроса, собранном в модуле, и при обмене данными — XML, JSON, CSV. В каждом случае причина одна, а приём свой.

Ниже — как записать одинарную кавычку, как убрать лишние при чтении данных и почему в консоли запросов кавычки ведут себя иначе, чем в коде.

Почему кавычка удваивается: экранирование строк

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

Разберём по шагам, что видит компилятор:

  • "" — пустая строка (открыли и сразу закрыли);
  • """" — строка из одного символа " (открыли, экранированная кавычка, закрыли);
  • """""" — строка из двух символов "" (две экранированные кавычки).

Пример со словом в кавычках внутри предложения:

Текст = "Он сказал ""Привет"" и ушёл";
Сообщить(Текст); // Он сказал "Привет" и ушёл

Здесь каждая внутренняя кавычка записана дважды, а на экране остаётся по одной. Правило простое: сколько кавычек нужно в результате — столько пар пишете в коде.

Когда кавычек в тексте много, удвоение превращает литерал в нечитаемую «лесенку». В таких случаях удобнее собрать строку через Символ(34) — об этом ниже.

Как записать одну кавычку в значении

Есть два надёжных способа получить ровно одну кавычку, и оба работают в любом контексте — реквизит, элемент справочника, параметр отчёта.

Способ 1. Удвоение прямо в литерале. Подходит, когда кавычек одна-две и текст известен заранее:

Наименование = "Болт ""Люкс"" оцинкованный";

Способ 2. Через Символ(34). Код 34 в таблице символов — это двойная кавычка. Способ незаменим, когда строка собирается из частей или кавычек много:

Кавычка = Символ(34);
Наименование = "Болт " + Кавычка + "Люкс" + Кавычка + " оцинкованный";

Способ 3. Через СтрШаблон. Когда строка собирается из нескольких подстановок, шаблон убирает конкатенацию и путаницу с кавычками: кавычки ставите один раз в шаблоне, подстановки идут через %1, %2:

Кавычка = Символ(34);
Текст = СтрШаблон("Товар %1%2%1 остаток %3 шт", Кавычка, "Люкс", 10);
// Товар "Люкс" остаток 10 шт

СтрШаблон заодно корректно приводит число к строке, так что отдельное преобразование не нужно.

Все три варианта дают одинаковый результат: Болт "Люкс" оцинкованный. Удвоение хорошо для коротких готовых текстов, Символ(34) и СтрШаблон — для строк, которые собираются из частей.

Для одинарной (машинописной) кавычки ' экранирование не нужно вовсе — она не является ограничителем строки, пишется как обычный символ:

Текст = "Файл 'отчёт' не найден";

Не путайте машинописную кавычку " (код 34) с типографскими «ёлочками» и „лапками“. Типографские кавычки — отдельные символы, они не удваиваются и не экранируются. Если в данных вперемешку оба вида, замена по символу " типографские не затронет.

Удвоенные кавычки в тексте запроса

В тексте запроса, который вы собираете как строку в модуле, строковые константы тоже ограничены двойными кавычками — и тоже требуют удвоения. Это самый частый источник путаницы: кавычек в одном литерале оказывается сразу по две пары.

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

Внешние кавычки ограничивают строку модуля. Внутренние ""Болт М8"" после снятия экранирования превращаются в "Болт М8" — это уже кавычки языка запросов вокруг константы.

Чтобы не плодить удвоения, выносите значения в параметры. Так запрос становится читаемым, а заодно защищённым от подстановок:

Запрос.Текст =
"ВЫБРАТЬ
|    Номенклатура.Ссылка
|ИЗ
|    Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|    Номенклатура.Наименование = &Наименование";
Запрос.УстановитьПараметр("Наименование", "Болт М8");

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

Чем консоль запросов отличается от кода

Здесь кроется корень большинства недоразумений. В консоли запросов (обработка «Консоль запросов» или аналог) вы вводите чистый текст запроса, а не строковый литерал модуля. Поэтому кавычки вокруг константы пишутся по одной паре:

ВЫБРАТЬ
    Номенклатура.Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Наименование = "Болт М8"

Тот же запрос в модуле требует удвоения, потому что он обёрнут в строку. Отсюда типичная ситуация: запрос прекрасно отрабатывает в консоли, а при переносе в код падает с ошибкой — забыли удвоить кавычки у констант.

Порядок переноса запроса из консоли в модуль:

  1. Отладьте запрос в консоли с одинарными парами кавычек.
  2. Оберните текст в строковый литерал модуля (внешние кавычки + символы продолжения строки |).
  3. Удвойте каждую кавычку внутри запроса.
  4. А лучше — замените константы на параметры и УстановитьПараметр, тогда удваивать нечего.

В конфигураторе удобен другой путь: наберите текст запроса через конструктор запроса (контекстное меню в модуле → «Конструктор запроса»). Платформа сама расставит удвоения и символы |.

Кавычки при выгрузке в XML и JSON

При обмене кавычка — спецсимвол формата, и платформа экранирует её сама, если пользоваться штатными объектами записи, а не собирать текст руками.

XML. Пишите через объект ЗаписьXML. В значениях атрибутов двойная кавычка автоматически заменяется на сущность " — это корректный XML, читается он обратно без потерь:

Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ИмяФайла);
Запись.ЗаписатьНачалоЭлемента("Товар");
Запись.ЗаписатьАтрибут("Название", "Болт ""Люкс""");
Запись.ЗаписатьКонецЭлемента();
Запись.Закрыть();

При чтении через ЧтениеXML сущность " раскрывается обратно в " автоматически. Ручная сборка XML конкатенацией строк — главная причина «съехавших» кавычек: вы экранируете сами, платформа не помогает, и легко получить либо "", либо незакрытый атрибут.

JSON. Объект ЗаписьJSON экранирует кавычку обратным слэшем — \", как требует стандарт JSON. Обратное чтение через ПрочитатьJSON возвращает чистое значение:

Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, "Болт ""Люкс""");
Результат = Запись.Закрыть(); // "Болт \"Люкс\""

Если после чтения JSON в значении остались \" — почти всегда это двойное кодирование: строку с JSON положили в другой JSON. Проверьте, не сериализуется ли значение дважды.

Кавычки в обмене через Excel и CSV

CSV. Текстовый формат с разделителями подчиняется правилу: если в значении есть разделитель, перенос строки или кавычка — всё поле заключается в двойные кавычки, а внутренние кавычки удваиваются. Это стандарт CSV, а не причуда 1С.

Значение Болт "Люкс", М8 в корректном CSV выглядит так:

"Болт ""Люкс"", М8"

При выгрузке собирайте строку CSV по этому правилу; при загрузке — снимайте обёртку и схлопывайте удвоенные кавычки обратно в одинарные. Если формируете CSV вручную, не забывайте оборачивать поля с кавычками, иначе принимающая сторона разберёт строку неправильно.

При ручном разборе CSV не делите строку просто по разделителю СтрРазделить — внутри обёрнутого поля может быть и разделитель, и перенос строки. Сначала найдите границы полей по кавычкам-обёрткам, затем схлопните удвоенные кавычки внутри. Для типовых случаев проще загрузить CSV в табличный документ штатными средствами, чем писать разбор вручную.

Excel. При работе через табличный документ или COM-подключение к Excel кавычка в значении ячейки не экранируется — вы кладёте в ячейку обычную строку, и там она так и хранится. Удвоение всплывает, только если вы предварительно сохраняете данные в CSV и уже оттуда открываете в Excel. То есть «двойные кавычки в экспорте в Excel» почти всегда означают, что промежуточным звеном был CSV, а не прямая выгрузка.

ФорматКто экранируетСимвол кавычки на выходе
Строка модулявы, удвоением"" → "
Запрос (константа)вы, удвоением"" → "
XML (ЗаписьXML)платформа"
JSON (ЗаписьJSON)платформа\"
CSVвы, по правилу RFC"" в обёрнутом поле

Как заменить удвоенные кавычки на одинарные

Если в данных уже накопились удвоенные кавычки (чаще — после неудачной загрузки), чистят их функцией СтрЗаменить. Ищем два символа кавычки, заменяем на один:

Очищенное = СтрЗаменить(ИсходнаяСтрока, """""", """");

Разберём аргументы, чтобы не запутаться в «частоколе»:

  • """""" — это два символа "" (то, что ищем);
  • """" — это один символ " (на что меняем).

Тот же код через Символ(34) читается яснее:

ДвеКавычки = Символ(34) + Символ(34);
ОднаКавычка = Символ(34);
Очищенное = СтрЗаменить(ИсходнаяСтрока, ДвеКавычки, ОднаКавычка);

Замена вслепую опасна, если в тексте законно встречаются две кавычки подряд (например, обозначение дюймов: 5"" трубы). Прежде чем массово чистить справочник, проверьте выборку через СтрНайти и убедитесь, что удвоение — артефакт загрузки, а не часть данных.

Найти проблемные строки заранее:

Если СтрНайти(Наименование, Символ(34) + Символ(34)) > 0 Тогда
    Сообщить("Удвоенные кавычки в: " + Наименование);
КонецЕсли;

Частые ошибки и быстрая диагностика

Диагностика: выберите симптом

Отдельно про отладку: ставьте точку останова и смотрите значение в табло. Табло показывает строку без экранирования — ровно так, как она хранится. Если в табло одна кавычка, а в коде литерала две — всё правильно. Если в данных две кавычки подряд там, где нужна одна, — проблема на этапе загрузки, а не в коде записи.

Частые вопросы

Почему 1С ставит две кавычки вместо одной?
Двойная кавычка ограничивает строку, поэтому внутри строки её нельзя написать «как есть». Две подряд — это экранирование: компилятор читает их как один символ. На экране и в данных остаётся одна кавычка.
Как вставить кавычку, не удваивая её вручную?
Используйте Символ(34) — функция возвращает один символ двойной кавычки. Собирайте строку конкатенацией: Символ(34) + Текст + Символ(34). Это читаемее, чем частокол из удвоений.
Чем кавычки в консоли запросов отличаются от кода?
В консоли вы вводите чистый текст запроса, поэтому вокруг константы пишется одна пара кавычек. В модуле тот же запрос обёрнут в строку, и каждую кавычку нужно удвоить. Поэтому запрос из консоли нельзя копировать в код без правки.
Нужно ли экранировать кавычки при выгрузке в XML или JSON?
Нет, если пользуетесь объектами ЗаписьXML и ЗаписьJSON — они экранируют сами (" для XML, \" для JSON). Экранировать руками приходится только при сборке формата конкатенацией строк, чего лучше избегать.
Как массово убрать удвоенные кавычки из справочника?
Через СтрЗаменить(Строка, """""", """") в обработке по справочнику. Перед запуском проверьте выборку СтрНайти: если две кавычки подряд встречаются законно (дюймы, цитаты), замена испортит данные — обработайте такие строки отдельно.
Нужно ли удваивать одинарную кавычку `'`?
Нет. Одинарная кавычка не ограничивает строку во встроенном языке, пишется как обычный символ. Экранирования требует только двойная кавычка (код 34).