Функция позволяет задавать именованные маркеры формата [Имя], в отличии от типовых нумерованных формата %n
Преимущества по сравнению с типовой функцией СтрШаблон:
— Код вызова функции проще для восприятия за счет именованных маркеров и параметров.
— Устойчива к перестановкам параметров, к вставкам между параметрами, т.к. сопоставление выполняется по именам, а не по порядку.
Пример использования:
Текст = СтрШаблон_("Заказано товаров на сумму [Сумма] в количестве [Колво]",
"Сумма", 2500, "Колво", 100);
Функция:
Функция СтрШаблон_(Шаблон,
п11="", п12="", п21="", п22="", п31="", п32="", п41="", п42="", п51="", п52="",
п61="", п62="", п71="", п72="", п81="", п82="", п91="", п92="", п101="", п102="",
п111="", п112="", п121="", п122="", п131="", п132="", п141="", п142="", п151="", п152="") экспорт
Результат = Шаблон;
Для сч = 1 по 15 Цикл
ИмяПараметра = Вычислить("п"+сч+"1");
Маркер = "["+ИмяПараметра+"]";
Если ИмяПараметра = "" Тогда
Прервать;
ИначеЕсли СтрНайти(Результат, Маркер) = 0 Тогда
ВызватьИсключение СтрШаблон("Не найден маркер %1 в шаблоне ""%2""", Маркер, Шаблон);
Иначе
Результат = СтрЗаменить(Результат, Маркер, Вычислить("п"+сч+"2"));
КонецЕсли;
КонецЦикла;
// Лишние маркеры удаляем
Пока Истина Цикл
Начало = СтрНайти(Результат, "[");
Конец = СтрНайти(Результат, "]");
Если Начало=0 ИЛИ Конец=0 ИЛИ Начало>Конец Тогда
Прервать;
КонецЕсли;
Результат = Лев(Результат,Начало-1) + Сред(Результат,Конец+1);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция на RegExp (не нашел сценариев, где RegExp дал бы здесь прирост по сравнению с кодом 1С)
Юнит-тесты под Vanessa-ADD 6.4.0
Однако в коде своего шаблона, автор использует платформенный СтрШаблон, хотя мог использовать и свой.
А чем она лучше БСПшной СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку?
(2) Читабельнее и не нужно создавать структуру.
Для сравнения:
(3) Насчет читабельности я бы поспорил.
А если мне надо 16 параметров?
(4)
Сложный вопрос. У меня нет на него ответа.
Для справки — платформенный СтрШаблон допускает не больше 10ти параметров.
А в индустрии разработки программирования шагнули намного дальше:https://python-scripts.com/string-formatting
немного оптимизировал
исправил ошибку в Тест_НеНайденМаркер
(1) возникает нехороший эффект из за удаления лишних маркеров
нужно будет экранирование квадратных скобок прикрутить
Мне кажется, что прерывать цикл при первой встрече пустого имени параметра неудачная идея. Это усложнит применение функции для различных шаблонов строк, зависящих от некоторого условия, но при этом с примерно одинаковым набором параметров. Во встроенной функции «СтрШаблон» это как раз порой и раздражает — строгое соответствие списка маркеров списку параметров функции.
Аналогично с удалением неиспользованных параметров. Разве не удобнее становится, когда забытый маркер бросается в глаза при выводе готовой строки?
(9) Приведите пример кода когда прерывание при встрече пустого параметра будет неудобно.
Я исходил из предположения удобства, когда маркер оказался не нужен в конкретном случае. Так он удалится автоматически. И также работает платформенная СтрШаблон — просто удаляет маркер
Померил скорость велосипеда из (8). Работает в три раза быстрее и писанины в два раза меньше.
(10)
Не могу. 🙂 Пока получше думал над примерами, пришел к выводу, что во всех случаях для Вашей функции любая универсальность будет врагом читаемости.
Да, конечно. Я нахожу это неудобным, но это дело вкуса, безусловно.
Я ошибся и на счет встроенной СтрШаблон. Поспешил, извините. Она не требует строго соответствия параметров маркерам. Только чтобы маркеров было не меньше, чем параметров функции. Аналогично и у Вас: лишние имена маркеров приведут к исключительной ситуации. Пару раз сталкивался с подобной особенностью, когда хотел написать что-то вроде такого:
Показать
И мне кажется такое поведения функции СтрШаблон также неудобным.
(12)
Да, конечно. Я нахожу это неудобным, но это дело вкуса, безусловно.
Эту реализация я в полной мере еще сам не оценил на практике и сделал так, чтобы у программиста не было потребности самому вычищать эти маркеры или составлять шаблон динамически, а также потому что в платформенной СтрШаблон сделано также. Есть несколько вариантов как сделать — пока остановился на этом.
ТекстСообщения = НСтр(«ru = ‘Не хватает товара %1 в количестве %2 на складе %3′»);
Иначе
ТекстСообщения = НСтр(«ru = ‘Не хватает товара %1 в количестве %2′»);
КонецЕсли;
ТекстСообщения = СтрШаблон(ТекстСообщения,
Выборка.Номенклатура,
Выборка.Количество,
Выборка.Склад);
Показать
Ну, лично я не пишу такие универсальные конструкции, не задаю параметры объектам если в них нет реальной потребности. В данном примере это Склад.
(11)
где именно меньше?
(8)
Имя = «Петр Петрович»;
ВВ = Вычислить(F(«Приветонище, {Имя}. Ваш долг {СуммаДолга} руб.»));
А если СуммаДолга лежит в Выборке то нужно будет сделать так?
СуммаДолга = Выборка.Сумма;
Имя = «Петр Петрович»;
ВВ = Вычислить(F(«Приветонище, {Имя}. Ваш долг {СуммаДолга} руб.»));
(8)
Вы считаете что имя функции «F» это нормально? Она будет глобальной?
(1) Кстати, действительно еще можно было бы сделать незамысловатую обертку для встроенной функции 🙂
Показать
(17) интересное решение, если не учитывать что в таком виде оно не работает)
ну и если сделать его рабочим, что не трудно, то при несоответствии маркеров параметрам в результате получаем ошибку «Слишком много фактических параметров» — как говорится, разбирайся как хочешь)
(16) F или не F какая разница. Назовите как хотите.
А если СуммаДолга лежит в Выборке то нужно будет сделать так?
Ну так и писать {Выборка.Сумма}
ВВ = Вычислить(F(«Приветонище, {Имя}. Ваш долг {Выборка.Сумма} руб.»));
(18) Проклятье! Что-то много я сегодня невпопад пишу. Пожалуй, отойду на сегодня от клавиатуры подальше. 🙂
(19) ну тогда удачи вам с такой замечательной функцией F
Хотя вашу идею я запомню на всякий пожарный. Мысля у народа работает)
(21)
А ты типа не народ 🙂
Кстати. Можно еще ускорить, если заранее шаблон заготовить
(23) Все таки, на написание функции меня сподвигла не оптимизация, а случаи нечитабельности больших шаблонов. Дискуссия получается полезная, но пока меня никто не убедил отказаться от своей реализации. Краткости кода я предпочитаю стабильность и читабельность.
(24) А моя то чем не читабельная. Очень даже читабельная. Да в добавок еще и быстрая. И кода меньше писать.
(25) сама функция? Я бы не сказал что читабельная.
И реализация точно не стабильная, т.к. не проверяется синтаксическим контролем.
(26) Ну функцию можно написать какую угодно. Тем более сейчас уже не важно как быстро она будет парсить шаблон, т.к. её в цикле можно не использовать.