Строковые функции для совместимости с платформой 8.3.5 и ниже

Программирование - Практика программирования

СтрЗаканчиваетсяНа СтрНачинаетсяС СтрРазделить СтрСоединить СтрНайти СтрШаблон

8
СтрНайти(), СтрНачинаетсяС(), СтрЗаканчиваетсяНа(), СтрРазделить(), СтрСоединить(), СтрШаблон() для платформы ниже 8.3.6

Приведенные ниже функции являются аналогами строковых методов, появившихся в платформе 8.3.6

Если у вас возникнет вопрос, ЗАЧЕМ нужно писать функции, которые и так есть в платформе, то просто закрывайте статью и не забивайте себе голову.

Думаю, что многие разработчики сталкивались с ситуацией, когда необходимо скопировать какой-нибудь кусок кода или модуль из, например, БСП или другой новой конфигурации в свою старенькую продуктовую конфигурацию, и при сохранении начинают сыпать ошибки, типа "Процедура или функция с указанным именем не определена (СтрНайти)".

Поэтому решил выложить эти методы сюда, чтобы были под рукой в нужную минуту.

 СтрНачинаетсяС()
Функция _СтрНачинаетсяС(Строка, СтрокаПоиска) Экспорт
	Возврат Найти(Строка, СтрокаПоиска) = 1;
КонецФункции

 

 СтрЗаканчиваетсяНа()
Функция _СтрЗаканчиваетсяНа(Строка, СтрокаПоиска) Экспорт
	Возврат Прав(Строка, СтрДлина(СтрокаПоиска)) = СтрокаПоиска;
КонецФункции

 

СтрРазделить()
Функция _СтрРазделить(знач Строка, Разделитель, ВключатьПустые = Истина) Экспорт
	Результат = Новый Массив;
	
	Если Строка = "" Тогда 
		Если ВключатьПустые Тогда
			Результат.Добавить(Строка);
		КонецЕсли;
		Возврат Результат;
	КонецЕсли;
	
	Позиция = Найти(Строка, Разделитель);
	Пока Позиция > 0 Цикл
		Подстрока = Лев(Строка, Позиция - 1);
		Если ВключатьПустые ИЛИ НЕ Подстрока = "" Тогда
			Результат.Добавить(Подстрока);
		КонецЕсли;
		Строка = Сред(Строка, Позиция + СтрДлина(Разделитель));
		Позиция = Найти(Строка, Разделитель);
	КонецЦикла;
	
	Если ВключатьПустые ИЛИ НЕ Строка = "" Тогда
		Результат.Добавить(Строка);
	КонецЕсли;
		
	Возврат Результат;
КонецФункции

 

СтрСоединить()
Функция _СтрСоединить(Строки, знач Разделитель = Неопределено) Экспорт
	Результат = "";
	
	Если Разделитель = Неопределено Тогда
		Разделитель = "";
	КонецЕсли;
	
	Если Строки.Количество() Тогда
		Результат = Строки[0];
	КонецЕсли;
	
	Для сч = 1 По Строки.ВГраница() Цикл
		Результат = Результат + Разделитель + Строки[сч];
	КонецЦикла;
	
	Возврат Результат;
КонецФункции

 

СтрНайти()
Функция _СтрНайти(Строка, ПодстрокаПоиска, НаправлениеПоиска = Неопределено, НачальнаяПозиция = Неопределено, НомерВхождения = 1) Экспорт
	// НаправлениеПоиска: СКонца,СНачала. По умолчанию: СНачала
	
	Если Строка = "" и ПодстрокаПоиска = "" Тогда
		// чтобы отрабатывало как в платформе
		Если НаправлениеПоиска = "СКонца" Тогда
			Если НомерВхождения = 1 Тогда
				Возврат 1;
			Иначе
				Возврат 0;
			КонецЕсли;
		Иначе
			Возврат мин(НомерВхождения, ?(НачальнаяПозиция=Неопределено, 1, НачальнаяПозиция));
		КонецЕсли;
	КонецЕсли;
	
	Если НачальнаяПозиция = Неопределено Тогда
		Если НаправлениеПоиска = "СКонца" Тогда
			лНачальнаяПозиция = СтрДлина(Строка);
		Иначе
			лНачальнаяПозиция = 1;
		КонецЕсли;
	Иначе
		лНачальнаяПозиция = НачальнаяПозиция;
	КонецЕсли;
	
	Если НаправлениеПоиска = "СКонца" Тогда
		лСтрока = "";
		Для сч = 1 По СтрДлина(Строка) Цикл
			лСтрока = Сред(Строка, сч, 1) + лСтрока;
		КонецЦикла;
		лПодстрокаПоиска = "";
		Для сч = 1 По СтрДлина(ПодстрокаПоиска) Цикл
			лПодстрокаПоиска = Сред(ПодстрокаПоиска, сч, 1) + лПодстрокаПоиска;
		КонецЦикла;
		лНачальнаяПозиция = макс(1, СтрДлина(Строка)-лНачальнаяПозиция-СтрДлина(ПодстрокаПоиска)+2);
	Иначе
		лСтрока = Строка;
		лПодстрокаПоиска = ПодстрокаПоиска;
		лНачальнаяПозиция = лНачальнаяПозиция;
	КонецЕсли;
	
	лНомерВхождения = 0;
	Результат = Найти(Сред(лСтрока, лНачальнаяПозиция), лПодстрокаПоиска);
	Пока Результат Цикл
		лНачальнаяПозиция = Результат + лНачальнаяПозиция + СтрДлина(ПодстрокаПоиска)-1;
		лНомерВхождения = лНомерВхождения + 1;
		Если лНомерВхождения = НомерВхождения Тогда
			Прервать;
		КонецЕсли;
		Результат = Найти(Сред(лСтрока, лНачальнаяПозиция), лПодстрокаПоиска);
	КонецЦикла;
	
	Если лНомерВхождения = НомерВхождения Тогда
		Результат = лНачальнаяПозиция - СтрДлина(ПодстрокаПоиска);
	Иначе
		Результат = 0;
	КонецЕсли;
		
	Если НаправлениеПоиска = "СКонца" И Результат<>0 Тогда
		Результат = СтрДлина(Строка) - Результат - СтрДлина(ПодстрокаПоиска) + 2;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

 

СтрШаблон()
Функция _СтрШаблон(Шаблон, Параметр1=Неопределено, Параметр2=Неопределено, Параметр3=Неопределено,Параметр4=Неопределено,Параметр5=Неопределено,Параметр6=Неопределено,Параметр7=Неопределено,Параметр8=Неопределено,Параметр9=Неопределено,Параметр10=Неопределено) Экспорт
	Результат = Шаблон;
	
	Для сч = -10 По -1 Цикл
		Параметр = Вычислить("Параметр" + (-сч));
		Если Параметр = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		Если Найти(Результат, "%("+(-сч)+")") = 0 И Найти(Результат, "%"+(-сч))=0 Тогда
			ВызватьИсключение "Слишком много фактических параметров";
		КонецЕсли;
		Результат = СтрЗаменить(Результат, "%("+ (-сч) + ")", Параметр);
		Результат = СтрЗаменить(Результат, "%"+ (-сч), Параметр);
	КонецЦикла;
	
	Возврат Результат;
КонецФункции

 

И да - в интернете можно найти такие функции, НО я не нашел решения в виде отдельной публикации.

Есть аналоги в комментарии к статье 6 новых функций, которые не следует использовать в режиме совместимости, но все варианты СтрНайти82() отрабатывают не так, как в платформе

Если обнаружатся недочеты - пишите в комментариях, будем исправлять

p.s. Текст, расположенный ниже "Причины купить" и др. - добавляется автоматически и нет возможности его отключить. Рекомендую не обращать на него внимания

 

8

См. также

Комментарии
Избранное Подписка Сортировка: Древо
1. yurii_host 1823 03.06.18 09:33 Сейчас в теме
Юнит-тесты к функциям можно взять тут и при желании дополнить.
Тесты описаны в модуле объекта.
2. yelloo 4 03.06.18 10:14 Сейчас в теме
Думаю, что любой программист (даже "одынэсниг") вполне способен написать простенькую функцию по работе со строками уровня школьной программы.
3. yurii_host 1823 03.06.18 11:13 Сейчас в теме
(2) СтрНайти() с пятью параметрами - это "простенькая функция по работе со строками уровня школьной программы"?
4. strange2007 132 15.08.18 04:55 Сейчас в теме
Когда надо было очень быстро решить вопрос с универсальностью СтрНайти, родился вот такой, малооптимальный код


	ЛеваяЧастьНайти = ПолучениеФункцииСтрНайти();
	// Доподготовка
	РезультатРаботы = 0;
	ИскомаяПодстрока = "(точка маршрута)";
	ИсходнаяСтрока = Строка(ИсходныйТип);
	// Составление итоговой строки
	ИтоговаяСтрока = "РезультатРаботы=" + ЛеваяЧастьНайти + "(ИсходнаяСтрока, ИскомаяПодстрока);";
	// Поиск
	Выполнить(ИтоговаяСтрока);

// В зависимости от клиента может работать Найти или СтрНайти
Функция ПолучениеФункцииСтрНайти()
	Перем ВозврЗначение, ИспытуемаяЧасть, ПолнаяСтрока;
	Перем ВрСтрока, ПоисковыйСимвол;
	
	// Предподготовка
	ВозврЗначение = "";
	ВрСтрока = "097987897";
	ПоисковыйСимвол = "9";
	
	// Попытка "Найти"
	ИспытуемаяЧасть = "Найти";
	ПолнаяСтрока = ИспытуемаяЧасть + "(ВрСтрока, ПоисковыйСимвол);";
	Попытка
		Выполнить(ПолнаяСтрока);
		ВозврЗначение = ИспытуемаяЧасть;
	Исключение КонецПопытки;
	
	// Попытка "СтрНайти"
	ИспытуемаяЧасть = "СтрНайти";
	ПолнаяСтрока = ИспытуемаяЧасть + "(ВрСтрока, ПоисковыйСимвол);";
	Попытка
		Выполнить(ПолнаяСтрока);
		ВозврЗначение = ИспытуемаяЧасть;
	Исключение КонецПопытки;
	
	//// Анализ предыдщей манипуляции
	//Если ВозврЗначение="" Тогда
	//	ВозврЗначение = "СтрНайти";
	//КонецЕсли;
	
	Возврат(ВозврЗначение);
КонецФункции
Показать
5. DrBlack 18 16.08.18 08:28 Сейчас в теме
(4) Да вас по рукам бы набить
6. strange2007 132 16.08.18 09:23 Сейчас в теме
(5) Вызываю на дуэль! Оружием выбираю спички! Тяните первый! (с)
А если серьёзно, то данный кривой код (и ещё подобные куски) сэкономил уйму времени, позволил уволить кучу ит-отделов и ит-контор и до сих пор крутится во многих организациях. Вы просто не пробовали оптимизировать работу системы на всех 7 уровнях оптимизации. Попробуйте и с ужасом увидите, что кривой код всегда гораздо эффективней красивого.
Именно поэтому в своё время появилась Майкрософт и 1С
7. DrBlack 18 16.08.18 13:30 Сейчас в теме
(6) Поддерживаю дуэль, вот мой велосипед:

Функция СтрНайти_83_82(Строка, ПодстрокаПоиска) Экспорт
	
	ЗнВозврат = 0;
	
	Попытка
		ЗнВозврат = Вычислить("СтрНайти(Строка, ПодстрокаПоиска)");
	Исключение
		ЗнВозврат = Найти(Строка, ПодстрокаПоиска);
	КонецПопытки;
	
	Возврат ЗнВозврат;
	
КонецФункции
Показать
strange2007; +1 Ответить
10. strange2007 132 17.08.18 05:51 Сейчас в теме
(7) Сдаюсь. Моё кунг-фу слабее.
Хм, а как скомпилится Найти в конфе, где эта конструкция не поддерживается? Оно ж ошибку выдаст. После исключения надо же тоже в вычислить/выполнить.

(украл код себе)
11. DrBlack 18 17.08.18 08:12 Сейчас в теме
(10) Функция "Найти" существует с 8.0 (если я не ошибаюсь), зачем тут попытка? :)
14. strange2007 132 17.08.18 08:42 Сейчас в теме
(11) Не просто так ведь сделали СтрНайти. Скорее всего с очередного момента Найти не будет использоваться. Значит надо это предусмотреть.
15. yurii_host 1823 17.08.18 08:48 Сейчас в теме
(14)
а вы будущее предсказывать умеете?
Или есть какие-то конкретные тексты от разработчиков платформы, что уберут функцию Найти()?

Мне кажется, что СтрНайти() добавили, чтобы расширить функционал Найти(). Добавить различные варианты поиска. Ну и плюс они, возможно, заметили нелогичность, что все строковые функции начинаются с "Стр", а эта без префикса.
16. strange2007 132 17.08.18 09:01 Сейчас в теме
(15) Конечно умею. Предсказываю - сейчас пойду наливать чай))))))
А если серьёзно, то мы уже привыкли к тому, что 1С-вцы всегда стремятся вперёд и плохой прошлый опыт просто вычёркивают. Например, ЗначениеНеОпределено (или как оно там писалось) было жёстко исключено. Только вот цена исключения оказалась высокой.
Далее рекомендую обратить внимание на то, что "ктрл+пробел" не показывает ф-ю Найти. Что это? Начало отказа!
Поэтому, как мне кажется, Найти исчезнет. Хоть и позже, но это случится. И вот тут и возникает повод для "загордиться перед столбом" - а мой код не заметил вселенской катастрофы.
yurii_host; +1 Ответить
17. DrBlack 18 17.08.18 09:17 Сейчас в теме
(14) Тогда такой код:
Функция СтрНайти_83_82(Строка, ПодстрокаПоиска) Экспорт
    
    ЗнВозврат = 0;
    
    Попытка
        ЗнВозврат = Вычислить("СтрНайти(Строка, ПодстрокаПоиска)");
    Исключение
        ЗнВозврат = Вычислить("Найти(Строка, ПодстрокаПоиска)");
    КонецПопытки;
    
    Возврат ЗнВозврат;
    
КонецФункции
Показать


При компиляции ошибки не будет, наличие второй "Попытки" не потребуется :)
8. yurii_host 1823 16.08.18 14:28 Сейчас в теме
(4)
(7)
А в чем фишка?
Почему нельзя просто использовать Найти() ?
Я так понимаю, что если нет нужды искать с конца, или искать, скажем второе вхождение, или не с первого символа, то СтрНайти() - ни к чему (если мы хотим поддерживать совместимость с ранними версиями)
Зачем пытаетесь использовать СтрНайти() да еще в попытке?
9. strange2007 132 17.08.18 05:46 Сейчас в теме
(8) Я ж не крутой программер, поэтому как могу...
12. DrBlack 18 17.08.18 08:19 Сейчас в теме
(8) Тут скорее задумка просто использовать новые функции (по возможности), а я лишь раскритиковал выложенный код, который его автору "сэкономил уйму времени", а также привел пример более простой реализации его задумки.
13. yurii_host 1823 17.08.18 08:28 Сейчас в теме
(12) ясно.
А то я уж подумал что это серьезно.
Вдруг в новых релизах убрали Найти(), и поэтому приходится костылить.
Оставьте свое сообщение