Как в 1С заменить параметры в строке без учета регистра и почему ТекстовыйДокумент для этого не подходит

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

Каждый разработчик 1С рано или поздно сталкивается с задачей формирования динамических текстов. Это может быть отправка SMS-уведомлений, генерация писем для клиентов, автозаполнение договоров или формирование простых текстовых отчетов. Часто шаблоны таких текстов настраивают сами пользователи или заказчики. Естественно, они могут ошибаться в регистре букв, записывая один и тот же параметр как [Сумма], [сумма] или даже [СуМмА].

В этой статье мы подробно разберем, почему попытка использовать для этой задачи стандартный объект платформы ТекстовыйДокумент приведет к непредсказуемым ошибкам. Мы также рассмотрим три надежных альтернативных способа подстановки параметров без учета регистра букв: от классических алгоритмов до современных регулярных выражений.

Почему объект ТекстовыйДокумент разочарует вас при работе с параметрами

На первый взгляд кажется, что объект ТекстовыйДокумент идеально подходит для решения задачи. Ведь у него есть свойство Параметры, очень похожее на аналогичный механизм в привычном ТабличныйДокумент. Мы можем определить текстовую область, задать шаблон и попытаться вывести заполненные данные.

Давайте посмотрим на классический пример такой реализации:


Результат = Новый ТекстовыйДокумент;
ТекстДок = Новый ТекстовыйДокумент;

ТекстДок.УстановитьТекст(
    "#Область Область1" + Символы.ПС +
    "Ваша сумма к оплате: [Сумма] руб." + Символы.ПС +
    "#КонецОбласти"
);

Область1 = ТекстДок.ПолучитьОбласть("Область1");
Область1.Параметры.Сумма = 100;

Результат.Вывести(Область1);
Сообщить(Результат.ПолучитьТекст());

Проанализируем поведение платформы при выполнении этого кода. Вы обнаружите две критические проблемы, из-за которых этот механизм абсолютно непригоден для формирования произвольного текста:

  1. Дополнение пробелами (эффект фиксированной ширины): Имя параметра в шаблоне — [Сумма] — состоит из 7 символов. Если мы передаем число 100 (3 символа), платформа автоматически дополнит результат пробелами справа до исходной длины маски параметра. На выходе мы получим: "Ваша сумма к оплате: 100 руб.".
  2. Обрезание длинных строк: Если вместо короткого числа мы решим передать длинную строку (например, прописью: "Сто рублей", длина 10 символов), платформа жестко обрежет её по размеру маски шаблона (7 символов). Результат будет выглядеть так: "Ваша сумма к оплате: Сто руб руб.".

Выясним причину такого странного поведения. Данный механизм в 1С является устаревшим (legacy-кодом). Он создавался во времена платформы 1С 7.7 и ранних версий 8.0 для вывода текстовых документов на матричные принтеры. В тех условиях жесткое позиционирование каждого символа по колонкам (знакоместам) было критически важным для сохранения структуры таблиц в текстовом виде. Для современных задач динамического формирования текстов этот объект использовать категорически нельзя.

Простой, но опасный путь: метод СтрЗаменить и приведение к регистру

Самым очевидным решением кажется использование стандартной функции платформы СтрЗаменить. Однако этот метод чувствителен к регистру символов. Если в шаблоне написано [сумма], а мы пытаемся заменить [Сумма], замена не произойдет.

Некоторые разработчики пытаются обойти это ограничение, принудительно переводя весь шаблон в верхний регистр перед заменой. Давайте проанализируем, к чему это приводит:


Шаблон = "Уважаемый [Клиент], Ваша сумма к оплате составляет [Сумма] руб.";
// Переводим всё в верхний регистр для гарантированного поиска
ШаблонВВерхнемРегистре = Врег(Шаблон); 

// Выполняем замену
Результат = СтрЗаменить(ШаблонВВерхнемРегистре, "[КЛИЕНТ]", "Иван Иванович");
Результат = СтрЗаменить(Результат, "[СУММА]", "15 000");

// На выходе получаем:
// "УВАЖАЕМЫЙ Иван Иванович, ВАША СУММА К ОПЛАТЕ СОСТАВЛЯЕТ 15 000 РУБ."

Как мы видим, этот подход портит форматирование всего остального текста шаблона. Наш клиент получит некрасивое письмо, написанное «капслоком». Использовать принудительное приведение регистра ко всему тексту шаблона крайне непрофессионально.

Решение с использованием БСП (Библиотеки Стандартных Подсистем)

Если вы ведете разработку в любой современной типовой конфигурации 1С (например, 1С:ERP, 1С:КА, 1С:УТ, 1С:Бухгалтерия), в вашем распоряжении есть готовые инструменты БСП. Нам не нужно изобретать велосипед, достаточно обратиться к функциям общего модуля СтроковыеФункцииКлиентСервер.

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


ПараметрыШаблона = Новый Структура;
ПараметрыШаблона.Вставить("Клиент", "Иван Иванович");
ПараметрыШаблона.Вставить("Сумма", "15 000");

Шаблон = "Уважаемый [Клиент], Ваша сумма к оплате: [Сумма] руб.";
Результат = СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Шаблон, ПараметрыШаблона);

Обратите внимание на важный нюанс: данный метод БСП внутри себя использует все тот же платформенный метод СтрЗаменить. Это означает, что **функция БСП чувствительна к регистру**. Если пользователь напишет в шаблоне [клиент] (с маленькой буквы), а в структуре параметров вы передадите ключ "Клиент", замена не сработает. Этот вариант хорош, но требует от заказчика строгого соблюдения регистра при заполнении шаблонов.

Современное решение на платформе 1С 8.3.23+ (Регулярные выражения)

Если ваша база работает на платформе версии **8.3.23 и выше**, перед вами открывается самый элегантный и современный способ решения задачи. Начиная с этого релиза, в платформу встроен мощный механизм работы с регулярными выражениями.

Давайте воспользуемся новой функцией СтрЗаменитьПоРегулярномуВыражению(). Она содержит важнейший четвертый параметр — ИгнорироватьРегистр, который по умолчанию имеет значение Истина.

Разберем готовый пример реализации:


Шаблон = "Приветствуем Вас, [КлИеНт]! Ваша сумма к оплате: [сумма] руб. Проверьте правильность суммы [СУММА]!";

// Выполняем регистронезависимую замену параметра "клиент"
// Символы "[" и "]" в регулярных выражениях являются служебными, поэтому экранируем их обратным слэшем: "\[" и "\]"
Шаблон = СтрЗаменитьПоРегулярномуВыражению(Шаблон, "\[клиент\]", "Петр Петрович", Истина);

// Выполняем регистронезависимую замену всех вхождений параметра "сумма"
Шаблон = СтрЗаменитьПоРегулярномуВыражению(Шаблон, "\[сумма\]", "25 500", Истина);

// Результат:
// "Приветствуем Вас, Петр Петрович! Ваша сумма к оплате: 25 500 руб. Проверьте правильность суммы 25 500!"

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

Универсальный кроссплатформенный алгоритм (для старых версий 1С)

Что делать, если ваша рабочая база запущена на старой версии платформы (ниже 8.3.23), где встроенных регулярных выражений еще нет, а решение должно стабильно работать как на Windows, так и на Linux-серверах?

Для этого мы можем написать универсальную функцию. Её идея заключается в использовании платформенного метода СтрНайти, который по умолчанию **работает без учета регистра букв**. Мы будем находить позицию вхождения параметра, вырезать точное написание параметра из исходного текста (включая тот регистр, который написал пользователь), а затем точечно заменять именно это конкретное вхождение через СтрЗаменить.

Давайте детально разберем код такой функции:


Функция ЗаменитьПараметрБезУчетаРегистра(Знач ИсходныйТекст, Знач ИмяПараметра, Знач ЗначениеЗамены) Экспорт
    
    // Гарантируем наличие квадратных скобок у имени параметра
    Если Лев(ИмяПараметра, 1) <> "[" Тогда
        ИмяПараметра = "[" + ИмяПараметра + "]";
    КонецЕсли;
    
    ДлинаПараметра = СтрДлина(ИмяПараметра);
    
    Пока Истина Цикл
        // СтрНайти ищет без учета регистра символов
        Позиция = СтрНайти(ИсходныйТекст, ИмяПараметра);
        
        Если Позиция = 0 Тогда
            Прервать; // Больше таких параметров в тексте нет
        КонецЕсли;
        
        // Вырезаем точное написание параметра из текста (например, "[суММа]")
        ТочныйПараметрИзТекста = Сред(ИсходныйТекст, Позиция, ДлинаПараметра);
        
        // Заменяем конкретное точное вхождение
        ИсходныйТекст = СтрЗаменить(ИсходныйТекст, ТочныйПараметрИзТекста, Строка(ЗначениеЗамены));
    КонецЦикла;
    
    Возврат ИсходныйТекст;
    
КонецФункции

Теперь мы можем безопасно использовать эту функцию для обработки любых пользовательских шаблонов, не боясь ошибок с регистром:


Шаблон = "Уважаемый [клИеНТ], ваш баланс: [суММа] руб. Повторяем: [СУММА] руб.";

Шаблон = ЗаменитьПараметрБезУчетаРегистра(Шаблон, "клиент", "Сергей");
Шаблон = ЗаменитьПараметрБезУчетаРегистра(Шаблон, "сумма", 500);

// Результат:
// "Уважаемый Сергей, ваш баланс: 500 руб. Повторяем: 500 руб."

Использование COM-объекта RegExp (только для Windows-серверов)

Если ваша СУБД и сервер приложений 1С гарантированно работают под управлением операционной системы Windows, вы можете использовать системный COM-объект VBScript.RegExp. Это позволит применять регулярные выражения даже на старых платформах 1С.

Обратим внимание на пример реализации:


Шаблон = "Добрый день, [поЛьзоВатель]!";
ЗначениеПараметра = "Дмитрий";

RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина; // Включаем игнорирование регистра букв
RegExp.Global = Истина;     // Заменять все вхождения

RegExp.Pattern = "\[пользователь\]";
Результат = RegExp.Replace(Шаблон, ЗначениеПараметра);

// Результат: "Добрый день, Дмитрий!"

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

Мы подробно разобрали все подводные камни автоподстановки параметров в строки. Теперь вы можете выбрать наиболее подходящий способ решения этой задачи в зависимости от версии платформы вашей конфигурации и используемой операционной системы.

← На главную