Работа со строками в 1С:Предприятие — одна из самых частых задач при разработке конфигураций, обработок или отчетов. Замена символов может потребоваться для очистки данных, форматирования вывода, подготовки строк к обмену или просто для приведения информации к единому стандарту. Например, вам может понадобиться убрать лишние пробелы, заменить дефисы на точки в номерах документов или преобразовать регистр букв.
В этой статье мы разберем все доступные способы замены символов — от встроенных функций языка 1С до написания собственных алгоритмов. Особое внимание уделим нюансам работы с Юникодом, многострочными текстами и регулярными выражениями. Материал актуален для платформ 1С:Предприятие 8.3 и 8.2, но с учетом их особенностей.
Если вы новичок, начните с первых двух разделов — там описаны самые простые методы. Опытным разработчикам будет полезен раздел про регулярные выражения и оптимизацию производительности при массовой замене.
1. Стандартная функция СтрЗаменить(): базовый синтаксис
Самый простой способ заменить символ или подстроку в 1С — использовать встроенную функцию СтрЗаменить(). Она доступна во всех версиях платформы и работает одинаково как в тонком клиенте, так и на сервере.
Базовый синтаксис функции:
СтрЗаменить(ИсходнаяСтрока, ЧтоИскать, НаЧтоЗаменять[, НаправлениеПоиска[, НачальнаяПозиция[, КоличествоЗамен]]])
Обязательные параметры:
- 📌 ИсходнаяСтрока — строка, в которой будет производиться замена.
- 🔍 ЧтоИскать — символ или подстрока, которую нужно заменить.
- ✏️ НаЧтоЗаменять — новый символ или подстрока.
Пример простейшей замены точки на запятую в числовом формате:
Результат = СтрЗаменить("123.45", ".", ","); // Вернет "123,45"
Функция чувствительна к регистру! Если вам нужно заменить символы независимо от регистра, используйте НРег() или ВРег() для приведения строки к единому регистру перед заменой.
⚠️ Внимание: В платформе 1С:Предприятие 8.2 функцияСтрЗаменить()не поддерживает параметрыНаправлениеПоискаиКоличествоЗамен. При их указании возникнет ошибка.
2. Замена нескольких символов за один проход
Часто требуется заменить не один символ, а несколько разных. Например, привести телефонный номер к единому формату, убрав все разделители: скобки, дефисы и пробелы. В этом случае можно:
- Вызывать
СтрЗаменить()несколько раз подряд. - Использовать вложенные вызовы функции.
- Написать собственную функцию с циклом по массиву замен.
Пример с вложенными вызовами (замена всех разделителей в номере телефона):
ЧистыйНомер = СтрЗаменить(
СтрЗаменить(
СтрЗаменить(
СтрЗаменить("+7 (912) 345-67-89", " ", ""),
"-", ""),
"(", ""),
")", "");
// Результат: "+79123456789"
Такой подход работает, но неэффективен при большом количестве замен. Для оптимизации лучше использовать цикл по массиву замен:
Функция ЗаменитьНесколько(Строка, МассивЗамен)
Для Каждого Замена Из МассивЗамен Цикл
Строка = СтрЗаменить(Строка, Замена.Что, Замена.НаЧто);
КонецЦикла;
Возврат Строка;
КонецФункции
// Пример вызова:
Массив = Новый Массив;
Массив.Добавить(Новый Структура("Что,НаЧто", " ", ""));
Массив.Добавить(Новый Структура("Что,НаЧто", "-", ""));
Результат = ЗаменитьНесколько("+7 (912) 345-67-89", Массив);
3. Работа с регулярными выражениями (регексами)
Для сложных замен, когда нужно учитывать шаблоны (например, заменить все цифры на звездочки или привести даты к единому формату), удобно использовать регулярные выражения. В 1С 8.3 для этого есть объект РегулярноеВыражение.
Пример: замена всех цифр в строке на символ #:
РегВыражение = Новый РегулярноеВыражение("\d");
Результат = РегВыражение.Заменить("Договор №123 от 01.01.2023", "#");
// Вернет: "Договор №### от ##.##.####"
Более сложный пример — приведение дат в формате ДД.ММ.ГГГГ к формату ГГГГ-ММ-ДД:
РегВыражение = Новый РегулярноеВыражение("(\d{2})\.(\d{2})\.(\d{4})");
Результат = РегВыражение.Заменить("Срок до 31.12.2023", "$3-$2-$1");
// Вернет: "Срок до 2023-12-31"
Как включить поддержку регулярных выражений в 1С 8.2?
В платформе 8.2 нет встроенного объекта "РегулярноеВыражение". Для работы с регексами потребуется подключить внешнюю компоненту (например, RegExp для 1С) или использовать COM-объект VBScript.RegExp через OLEAutomation. Пример кода для 8.2:
Попытка
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Pattern = "\d";
RegExp.Global = Истина;
Результат = RegExp.Replace("Тест 123", "#");
Исключение
Сообщить("Ошибка подключения COM-объекта: " + ОписаниеОшибки());
КонецПопытки;
Обратите внимание, что этот метод работает только в Windows и требует прав на создание COM-объектов.
Регулярные выражения мощны, но ресурсоемки. Не используйте их для простых замен — лучше отдайте предпочтение СтрЗаменить().
4. Замена символов в табличных данных и массивах
Если вам нужно заменить символы не в одной строке, а во всем столбце таблицы значений или массиве строк, оптимально использовать цикл. Пример для таблицы значений:
Для Каждого Строка Из Таблица Цикл
Строка.Наименование = СтрЗаменить(Строка.Наименование, "ё", "е");
Строка.Артикул = СтрЗаменить(Строка.Артикул, " ", "_");
КонецЦикла;
Для больших таблиц (тысячи строк) такой подход может тормозить. В этом случае лучше:
- 🔄 Использовать пакетную обработку с помощью запроса (если замена простая).
- 🚀 Применять многопоточность (в 8.3.14+).
- 📊 Для сложных замен — выгружать данные во временную таблицу БД и обрабатывать SQL-запросом.
Пример оптимизированной замены через запрос:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Ссылка КАК Ссылка,
| ЗАМЕНИТЬ(ЗАМЕНИТЬ(Товары.Наименование, ""ё"", ""е""), "" "", ""_"") КАК Наименование
|ИЗ
| Справочник.Товары КАК Товары";
Результат = Запрос.Выполнить();
⚠️ Внимание: При работе с большими объемами данных в 1С:Предприятие 8.2 пакетная обработка через запросы может приводить к блокировкам базы. В этом случае разбейте задачу на порции по 1000 строк.
5. Особенности работы с Юникодом и многобайтовыми символами
В 1С строки хранятся в кодировке UTF-16, что означает: некоторые символы (например, смайлики или иероглифы) занимают 2 юникодные позиции. Это важно учитывать при замене по индексам или работе с функциями вроде Сред().
Пример проблемы: попытка заменить первый символ в строке с эмодзи:
Строка = "😊Привет";
ПервыйСимвол = Лев(Строка, 1); // Вернет ПУСТУЮ строку!
// Правильный способ:
ПервыйСимвол = Сред(Строка, 1, 1); // Вернет "😊"
Для корректной работы с многобайтовыми символами:
| Задача | Проблема | Решение |
|---|---|---|
| Замена по индексу | Лев()/Прав() могут обрезать символы |
Использовать Сред() с длиной 1 |
| Поиск длины строки | СтрДлина() считает юникодные позиции |
Для визуальной длины — писать собственную функцию |
| Регулярные выражения | Шаблоны вроде . не захватывают переносы строк |
Использовать флаг m (многострочный режим) |
В платформе 1С 8.3.20+ добавлена поддержка графемных кластеров (например, для символов с диакритическими знаками или эмодзи с модификаторами тона кожи), но для корректной работы с ними все равно требуется использовать Сред() вместо Лев()/Прав().
6. Замена символов в файлах (текстовых, XML, JSON)
При работе с файлами замена символов может потребоваться для:
- 📄 Очистки
CSV/TXTперед импортом. - 📥 Преобразования
XMLв нужную кодировку. - 📊 Форматирования
JSONдля API.
Пример чтения файла, замены символов и сохранения обратно:
// Чтение файла
Текст = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8);
Содержимое = Текст.Прочитать();
// Замена символов
Содержимое = СтрЗаменить(Содержимое, ";", "|");
Содержимое = СтрЗаменить(Содержимое, Чр(13) + Чр(10), Чр(10)); // Замена Windows-переводов строк
// Сохранение
Запись = Новый ЗаписьТекста(ПутьКФайлу);
Запись.ЗаписатьСтроку(Содержимое);
Запись.Закрыть();
Для XML и JSON лучше использовать специализированные парсеры (ЧтениеXML, ЗаписьJSON), так как ручная замена символов может нарушить структуру файла. Например:
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлу);
Данные = ПрочитатьXML(ЧтениеXML); // Используем штатные механизмы 1С
Текст = Новый ЧтениеТекста(ПутьКФайлу);
Пока Текст.ПрочитатьСтроку(Строка) Цикл
Строка = СтрЗаменить(Строка, "";"", ""|"");
// Обработка строки...
КонецЦикла;
-->
7. Оптимизация производительности при массовых заменах
Если вам нужно заменить символы в тысячах строк (например, при обработке большого справочника или документа), стандартные методы могут работать слишком медленно. Вот способы ускорить процесс:
- Использовать запросы вместо циклов по строкам.
- Выгружать данные во временные таблицы БД и обрабатывать SQL-запросами.
- Применять многопоточность (в 8.3.14+ с помощью
ФоновыеЗадания). - Кэшировать результаты повторяющихся замен.
Пример ускоренной обработки через временную таблицу:
// 1. Создаем временную таблицу
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ПОМЕСТИТЬ ВТНоменклатура
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
// 2. Обновляем данные пакетом
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВТНоменклатура.Ссылка КАК Ссылка,
| ЗАМЕНИТЬ(ВТНоменклатура.Наименование, ""ё"", ""е"") КАК Наименование
|ИЗ
| ВТНоменклатура КАК ВТНоменклатура";
Результат = Запрос.Выполнить();
// 3. Обновляем оригинальный справочник
Для Каждого Строка Из Результат Цикл
Объект = Строка.Ссылка.ПолучитьОбъект();
Объект.Наименование = Строка.Наименование;
Объект.Записать();
КонецЦикла;
⚠️ Внимание: При использовании фоновых заданий в 1С 8.3.14+ учитывайте, что они имеют ограничение по времени выполнения (по умолчанию — 60 секунд). Для длительных операций увеличивайте таймаут или разбивайте задачу на части.
Для массовых замен оптимально использовать комбинацию из временных таблиц БД и пакетного обновления через запросы. Это сокращает время обработки в 10-100 раз по сравнению с построчной заменой.
FAQ: Частые вопросы по замене символов в 1С
Как заменить перевод строки на другой символ?
В 1С перевод строки представлен комбинацией Чр(13) + Чр(10) (для Windows) или Чр(10) (для Unix). Пример замены:
Текст = "Строка1" + Символы.ПС + "Строка2";
Текст = СтрЗаменить(Текст, Символы.ПС, "; ");
// Или явно:
Текст = СтрЗаменить(Текст, Чр(13) + Чр(10), "; ");
Почему СтрЗаменить() не заменяет кириллические символы?
Проблема обычно связана с кодировкой файла или источника данных. Убедитесь, что:
- Текст читается в кодировке
UTF-8. - В настройках конфигуратора установлена правильная кодировка (параметр
/CodePageпри запуске). - Символы не являются визуально похожими (например, латинская "e" и кириллическая "е").
Для диагностики используйте КодСимвола():
Сообщить(КодСимвола("е")); // Должно вернуть 1077 (кириллица)
Как заменить символы в формате HTML?
Для работы с HTML-кодом (например, замены тегов или специальных символов) используйте комбинацию СтрЗаменить() и регулярных выражений. Пример удаления всех HTML-тегов:
РегВыражение = Новый РегулярноеВыражение("<[^>]+>");
Результат = РегВыражение.Заменить("Жирный текст", "");
Для замены специальных HTML-символов (например, на пробел) используйте:
Текст = СтрЗаменить(Текст, " ", " ");
Текст = СтрЗаменить(Текст, "&", "&");
Можно ли отменить замену символов?
В 1С нет встроенного механизма "отмены" операций со строками, так как строки являются неизменяемыми (каждая операция создает новую строку). Чтобы вернуть оригинальное значение:
- Сохраняйте исходную строку в отдельную переменную перед заменой.
- Используйте транзакции при работе с базой данных.
- Для сложных операций ведите журнал изменений.
Как заменить символы в динамическом списке?
Для замены символов в колонках динамического списка:
- Создайте вычисляемое поле в запросе, формирующем список.
- Используйте событие
ПриОтображенииСтрокидля модификации данных на лету.
Пример для события ПриОтображенииСтроки:
Процедура ДинамическийСписокПриОтображенииСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
ДанныеСтроки.Наименование = СтрЗаменить(ДанныеСтроки.Наименование, "ё", "е");
КонецПроцедуры