Функция СтрШаблон с именованными маркерами

21.10.19

Разработка - Универсальные функции

Функция позволяет задавать именованные маркеры формата [Имя], в отличии от типовых нумерованных формата %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

СтрШаблон Шаблон Строки Строка

См. также

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

21.05.2024    22013    dimanich70    81    

147

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    4241    3    John_d    11    

57

Универсальные функции Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    20846    atdonya    25    

58

Универсальные функции Программист Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    5714    ke.92@mail.ru    17    

65

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    15471    YA_418728146    7    

169

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3768    59    progmaster    8    

4

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    18757    173    sapervodichka    112    

136
Отзывы
8. v77 160 22.10.19 10:29 Сейчас в теме
А что если так?

&НаКлиенте
Процедура Команда1(Команда)
	СуммаДолга = 100500;
	Имя = "Петр Петрович";
	ВВ = Вычислить(F("Приветонище, {Имя}. Ваш долг {СуммаДолга} руб."));
	Сообщить(ВВ);
КонецПроцедуры

&НаКлиенте
Функция F(Стр)
	Стр = СтрЗаменить(Стр,"{",Символы.ПС+"^");	
	Стр = СтрЗаменить(Стр,"}",Символы.ПС);
	Стр = СтрРазделить(Стр,Символы.ПС);
	Результат = """""";
	Для Каждого Ст Из Стр Цикл
		Если СтрНачинаетсяС(Ст,"^") Тогда
			Результат = Результат + "+" + Сред(Ст,2,СтрДлина(Ст));	
		Иначе
			Результат = Результат + "+""" + Ст + """";
		КонецЕсли;
	КонецЦикла;
	Возврат Результат;
КонецФункции
Показать
shaykhelov; +1 Ответить
Остальные комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. WalterMort 246 21.10.19 17:47 Сейчас в теме
Однако в коде своего шаблона, автор использует платформенный СтрШаблон, хотя мог использовать и свой.
TMV; kirinalex; tnaiko; +3 Ответить
7. kirinalex 16 21.10.19 21:03 Сейчас в теме
(1) возникает нехороший эффект из за удаления лишних маркеров
нужно будет экранирование квадратных скобок прикрутить
17. dhurricane 22.10.19 14:13 Сейчас в теме
(1) Кстати, действительно еще можно было бы сделать незамысловатую обертку для встроенной функции :)
Функция СтрШаблон_(Знач Шаблон, 
		п11="", п12="", п21="", п22="", п31="", п32="", п41="", п42="", п51="", п52="",
		п61="", п62="", п71="", п72="", п81="", п82="", п91="", п92="", п101="", п102="") экспорт
					
	Шаблон = СтрЗаменить(Шаблон, "["+п11+"]", "%1");
	Шаблон = СтрЗаменить(Шаблон, "["+п21+"]", "%2");
	Шаблон = СтрЗаменить(Шаблон, "["+п31+"]", "%3");
	Шаблон = СтрЗаменить(Шаблон, "["+п41+"]", "%4");
	Шаблон = СтрЗаменить(Шаблон, "["+п51+"]", "%5");
	Шаблон = СтрЗаменить(Шаблон, "["+п61+"]", "%6");
	Шаблон = СтрЗаменить(Шаблон, "["+п71+"]", "%7");
	Шаблон = СтрЗаменить(Шаблон, "["+п81+"]", "%8");
	Шаблон = СтрЗаменить(Шаблон, "["+п91+"]", "%9");
	Шаблон = СтрЗаменить(Шаблон, "["+п101+"]", "%10");
	
	Возврат СтрШаблон(Шаблон, п12, п22, п32, п42, п52, п62, п72, п82, п92, п102);
	
КонецФункции
Показать
18. kirinalex 16 22.10.19 15:10 Сейчас в теме
(17) интересное решение, если не учитывать что в таком виде оно не работает)
ну и если сделать его рабочим, что не трудно, то при несоответствии маркеров параметрам в результате получаем ошибку "Слишком много фактических параметров" - как говорится, разбирайся как хочешь)
20. dhurricane 22.10.19 15:20 Сейчас в теме
(18) Проклятье! Что-то много я сегодня невпопад пишу. Пожалуй, отойду на сегодня от клавиатуры подальше. :)
2. A.Sytchev 21.10.19 17:56 Сейчас в теме
А чем она лучше БСПшной СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку?

https://www.screenpresso.com/=RXKZc
Дмитрий74Чел; Созинов; chebser; litonchik; PLAstic; +5 Ответить
3. kirinalex 16 21.10.19 18:05 Сейчас в теме
(2) Читабельнее и не нужно создавать структуру.
Для сравнения:

СтрШаблон_(, "Имя","Вася", "Фамилия","Пупкин", "Город","Москва", "СемейноеПоложение","Все сложно")

Новый Структура("Имя, Фамилия, Город, СемейноеПоложение", "Вася", "Пупкин", "Москва", "Все сложно")
4. A.Sytchev 21.10.19 18:09 Сейчас в теме
(3) Насчет читабельности я бы поспорил.

Параметры = Новый Структура;
Параметры.Вставить("Имя", "Вася");
Параметры.Вставить("Фамилия",  "Пупкин");
Параметры.Вставить("Город",  "Москва");
Параметры.Вставить("СемейноеПоложение", "Все сложно");


А если мне надо 16 параметров?
5. kirinalex 16 21.10.19 18:18 Сейчас в теме
(4)
 СтрШаблон_(, 
   "Имя", "Вася", 
   "Фамилия", "Пупкин", 
   "Город", "Москва",
   "СемейноеПоложение", "Все сложно")


А если мне надо 16 параметров?

Сложный вопрос. У меня нет на него ответа.
Для справки - платформенный СтрШаблон допускает не больше 10ти параметров.

А в индустрии разработки программирования шагнули намного дальше: https://python-scripts.com/string-formatting
6. kirinalex 16 21.10.19 21:02 Сейчас в теме
немного оптимизировал
исправил ошибку в Тест_НеНайденМаркер
8. v77 160 22.10.19 10:29 Сейчас в теме
А что если так?

&НаКлиенте
Процедура Команда1(Команда)
	СуммаДолга = 100500;
	Имя = "Петр Петрович";
	ВВ = Вычислить(F("Приветонище, {Имя}. Ваш долг {СуммаДолга} руб."));
	Сообщить(ВВ);
КонецПроцедуры

&НаКлиенте
Функция F(Стр)
	Стр = СтрЗаменить(Стр,"{",Символы.ПС+"^");	
	Стр = СтрЗаменить(Стр,"}",Символы.ПС);
	Стр = СтрРазделить(Стр,Символы.ПС);
	Результат = """""";
	Для Каждого Ст Из Стр Цикл
		Если СтрНачинаетсяС(Ст,"^") Тогда
			Результат = Результат + "+" + Сред(Ст,2,СтрДлина(Ст));	
		Иначе
			Результат = Результат + "+""" + Ст + """";
		КонецЕсли;
	КонецЦикла;
	Возврат Результат;
КонецФункции
Показать
shaykhelov; +1 Ответить
11. v77 160 22.10.19 11:30 Сейчас в теме
Померил скорость велосипеда из (8). Работает в три раза быстрее и писанины в два раза меньше.

Текст = СтрШаблон_("Заказано товаров на сумму [Сумма] в количестве [Колво]",
  "Сумма", 2500, "Колво", 100);

Текст = Вычислить(F("Заказано товаров на сумму {Сумма} в количестве {Колво}"));
14. kirinalex 16 22.10.19 14:08 Сейчас в теме
(11)
писанины в два раза меньше.

где именно меньше?
15. kirinalex 16 22.10.19 14:10 Сейчас в теме
(8)
СуммаДолга = 100500;
Имя = "Петр Петрович";
ВВ = Вычислить(F("Приветонище, {Имя}. Ваш долг {СуммаДолга} руб."));

А если СуммаДолга лежит в Выборке то нужно будет сделать так?

СуммаДолга = Выборка.Сумма;
Имя = "Петр Петрович";
ВВ = Вычислить(F("Приветонище, {Имя}. Ваш долг {СуммаДолга} руб."));
16. kirinalex 16 22.10.19 14:11 Сейчас в теме
(8)
Функция F(Стр)

Вы считаете что имя функции "F" это нормально? Она будет глобальной?
19. v77 160 22.10.19 15:17 Сейчас в теме
(16) F или не F какая разница. Назовите как хотите.

А если СуммаДолга лежит в Выборке то нужно будет сделать так?

Ну так и писать {Выборка.Сумма}

ВВ = Вычислить(F("Приветонище, {Имя}. Ваш долг {Выборка.Сумма} руб."));
21. kirinalex 16 22.10.19 15:25 Сейчас в теме
(19) ну тогда удачи вам с такой замечательной функцией F

Хотя вашу идею я запомню на всякий пожарный. Мысля у народа работает)
22. v77 160 22.10.19 16:32 Сейчас в теме
(21)
Мысля у народа работает)
А ты типа не народ :)
9. dhurricane 22.10.19 10:40 Сейчас в теме
Мне кажется, что прерывать цикл при первой встрече пустого имени параметра неудачная идея. Это усложнит применение функции для различных шаблонов строк, зависящих от некоторого условия, но при этом с примерно одинаковым набором параметров. Во встроенной функции "СтрШаблон" это как раз порой и раздражает - строгое соответствие списка маркеров списку параметров функции.

Аналогично с удалением неиспользованных параметров. Разве не удобнее становится, когда забытый маркер бросается в глаза при выводе готовой строки?
10. kirinalex 16 22.10.19 11:18 Сейчас в теме
(9) Приведите пример кода когда прерывание при встрече пустого параметра будет неудобно.

Аналогично с удалением неиспользованных параметров. Разве не удобнее становится, когда забытый маркер бросается в глаза при выводе готовой строки?

Я исходил из предположения удобства, когда маркер оказался не нужен в конкретном случае. Так он удалится автоматически. И также работает платформенная СтрШаблон - просто удаляет маркер
12. dhurricane 22.10.19 12:45 Сейчас в теме
(10)
Приведите пример кода когда прерывание при встрече пустого параметра будет неудобно.
Не могу. :) Пока получше думал над примерами, пришел к выводу, что во всех случаях для Вашей функции любая универсальность будет врагом читаемости.

И также работает платформенная СтрШаблон - просто удаляет маркер
Да, конечно. Я нахожу это неудобным, но это дело вкуса, безусловно.

Я ошибся и на счет встроенной СтрШаблон. Поспешил, извините. Она не требует строго соответствия параметров маркерам. Только чтобы маркеров было не меньше, чем параметров функции. Аналогично и у Вас: лишние имена маркеров приведут к исключительной ситуации. Пару раз сталкивался с подобной особенностью, когда хотел написать что-то вроде такого:
Если ЗначениеЗаполнено(Выборка.Склад) Тогда
	ТекстСообщения = НСтр("ru = 'Не хватает товара %1 в количестве %2 на складе %3'");
Иначе
	ТекстСообщения = НСтр("ru = 'Не хватает товара %1 в количестве %2'");
КонецЕсли; 

ТекстСообщения = СтрШаблон(ТекстСообщения, 
	Выборка.Номенклатура, 
	Выборка.Количество, 
	Выборка.Склад);
Показать
И мне кажется такое поведения функции СтрШаблон также неудобным.
13. kirinalex 16 22.10.19 14:05 Сейчас в теме
(12)
И также работает платформенная СтрШаблон - просто удаляет маркер
Да, конечно. Я нахожу это неудобным, но это дело вкуса, безусловно.
Эту реализация я в полной мере еще сам не оценил на практике и сделал так, чтобы у программиста не было потребности самому вычищать эти маркеры или составлять шаблон динамически, а также потому что в платформенной СтрШаблон сделано также. Есть несколько вариантов как сделать - пока остановился на этом.

Если ЗначениеЗаполнено(Выборка.Склад) Тогда
ТекстСообщения = НСтр("ru = 'Не хватает товара %1 в количестве %2 на складе %3'");
Иначе
ТекстСообщения = НСтр("ru = 'Не хватает товара %1 в количестве %2'");
КонецЕсли;

ТекстСообщения = СтрШаблон(ТекстСообщения,
Выборка.Номенклатура,
Выборка.Количество,
Выборка.Склад);
Показать
Ну, лично я не пишу такие универсальные конструкции, не задаю параметры объектам если в них нет реальной потребности. В данном примере это Склад.
23. v77 160 22.10.19 17:01 Сейчас в теме
Кстати. Можно еще ускорить, если заранее шаблон заготовить

	Шаблон = F("Приветонище, {Выборка.Наименование}. Ваш долг {Выборка.СуммаДолга} руб.");
	Пока Выборка.Следующий() Цикл
		ВВ = Вычислить(Шаблон);
		Сообщить(ВВ);
	КонецЦикла;

24. kirinalex 16 22.10.19 17:13 Сейчас в теме
(23) Все таки, на написание функции меня сподвигла не оптимизация, а случаи нечитабельности больших шаблонов. Дискуссия получается полезная, но пока меня никто не убедил отказаться от своей реализации. Краткости кода я предпочитаю стабильность и читабельность.
25. v77 160 22.10.19 17:15 Сейчас в теме
(24) А моя то чем не читабельная. Очень даже читабельная. Да в добавок еще и быстрая. И кода меньше писать.
26. kirinalex 16 22.10.19 17:18 Сейчас в теме
(25) сама функция? Я бы не сказал что читабельная.
И реализация точно не стабильная, т.к. не проверяется синтаксическим контролем.
27. v77 160 22.10.19 17:20 Сейчас в теме
(26) Ну функцию можно написать какую угодно. Тем более сейчас уже не важно как быстро она будет парсить шаблон, т.к. её в цикле можно не использовать.
Оставьте свое сообщение