gifts2017

6 новых функций, которые не следует использовать в режиме совместимости

Опубликовал Denis Michaylov (denis_aka_wolf) в раздел Программирование - Практика программирования

В релизе платформы 8.3.6.1977 были добавлены новые функции, но не стоит спешить их использовать, пока все не перейдут на новые платформы без режима совместимости с 8.3.5.
Новые функции удобны - бесспорно, но не у всех они будут работать. Ниже приведен список функций с возникающими ошибками и вариантами использования старых методов работы, которые будут действовать на всех платформах.
Использовать или нет новые функции, решать Вам, а мое субъективное мнение - пока не стоит.
Рассматриваемые функции: СтрНайти(), СтрШаблон(), СтрСравнить(), СтрНачинаетсяС(), СтрЗаканчиваетсяНа(), СтрРазделить(),СтрСоединить()

Реализовано в версии 8.3.6.1977.

"Мы расширили набор функций, предназначенных для работы со строками. Мы это сделали для того, чтобы дать вам более развитые инструменты для разбора строковых данных. Новые функции будут удобны и полезны в технологических задачах анализа текста. В задачах, связанных с разбором текста, который содержит данные в форматированном виде. Это может быть анализ каких-то файлов, полученных от оборудования, или, например, анализ технологического журнала.
Все действия, которые выполняют новые функции, вы могли выполнять и раньше. С помощью более или менее сложных алгоритмов, написанных на встроенном языке. Поэтому новые функции не дают вам каких-то принципиально новых возможностей. Однако они позволяют сократить количество кода, сделать код более простым и понятным. А кроме этого они позволяют ускорить выполнение действий. Потому что функции, реализованные в платформе, работают, конечно же, быстрее, чем аналогичный алгоритм, написанный на встроенном языке."

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

 

Когда пишете на "своих" конфигурациях, тогда можно делать что душе угодно, но когда разработка идет в "чужую" конфигурацию - стоит задуматься каким путем пойти:

  • Использовать новые функции и обязать заказчика перейти на свежую платформу
  • Сделать проверку текущей версии платформы и использовать новые функции и старые механизмы работы
  • Использовать только старые механизмы работы
По первому пункту - как повезет, не всегда заказчик будет гореть желанием перейти на новую платформу по своим причинам и отговоркам коих найдется не один десяток.

По второму - идеальный вариант, но не каждый разработчик будет перед каждым вызовом новой функции строить городульки чтобы узнать версию платформы. Хотя данный вариант имеет право на жизнь.
 
И по третьему - самый оптимальный (мое субъективное мнение) гораздо проще второго варианта, но уступает первому в том что не помогает продвижению новых платформ в массы Cool

 

Функция работы со строками СтрНайти(<Строка>, <ПодстрокаПоиска>, <НаправлениеПоиска>, <НачальнаяПозиция>, <НомерВхождения>)

 

Функция выполняет поиск подстроки в различных направлениях и не только с начала строки.

Сообщить(СтрНайти("2212","1")); //вернет 3

 

В режиме совместимости 8.3.5 и ниже возникает ошибка
{ВнешняяОбработка.ВнешняяОбработка1.МодульОбъекта(1,10)}: Процедура или функция с указанным именем не определена (СтрНайти)
Сообщить(<<?>>СтрНайти("1","2212"));

Остается довольствоваться тем, что имеем

Сообщить(Найти("2212","1")); //вернет 3

меньше возможностей, но не вылетает с ошибкой

Функция Найти() осталась только для совместимости с 8.3.5 и в дальнейшем ожидаем, что ее не станет.


Функция работы со строками СтрШаблон(<Шаблон>, <Значение1-Значение10>) 


Функция выполняет замену маркеров подстановки (вида %1) в шаблонной строке на реальные значения.

Сообщить(СтрШаблон("ПРИВЕТ %1 ","МИР!!!")); //вернет ПРИВЕТ МИР!!!


В режиме совместимости возникает ошибка
{ВнешняяОбработка.ВнешняяОбработка1.МодульОбъекта(3,10)}: Процедура или функция с указанным именем не определена (СтрШаблон)
Сообщить(<<?>>СтрШаблон("Ошибка в строке "" %1 ""","МояСтрока"));

 


Функция работы со строками СтрСравнить(<Строка1>, <Строка2>)

 

Функция выполняет лексикографическое сравнение строк без учета регистра.

Сообщить(СтрСравнить("Первая строка", "Вторая строка")); //вернет 1


 Возникающая ошибка
{ВнешняяОбработка.ВнешняяОбработка1.МодульОбъекта(5,10)}: Процедура или функция с указанным именем не определена (СтрСравнить)
Сообщить(<<?>>СтрСравнить("Первая строка", "Вторая строка"));

Но можно сделать по-другому

Сравнение = Новый СравнениеЗначений;
Сообщить(Сравнение.Сравнить("Первая строка", "Вторая строка"));

 

Функция работы со строками СтрНачинаетсяС(<Строка>,<СтрокаПоиска>)

 

Функция проверяет, что строка начинается на подстроку.

СтрокаПоиска = "http://";
ЭтоВеб = СтрНачинаетсяС("http://google.com", СтрокаПоиска);
Сообщить(ЭтоВеб);//вернет Истина

 

Возникает ошибка
{ВнешняяОбработка.ВнешняяОбработка1.МодульОбъекта(22,10)}: Процедура или функция с указанным именем не определена (СтрНачинаетсяС)
Сообщить(<<?>>СтрНачинаетсяС("http://google.com", "http://"));

Но можно сделать по-старому

СтрокаПоиска = "http://";
Сообщить(Лев("http://google.com",СтрДлина(СтрокаПоиска))=СтрокаПоиска); //вернет истина


Функция работы со строками СтрЗаканчиваетсяНа(<Строка>, <СтрокаПоиска>)

 

Функция проверяет, что строка оканчивается подстрокой.

СтрокаПоиска = "@mail.ru";
ЭтоМайлРу = СтрЗаканчиваетсяНа("vasya_pupkin@mail.ru", СтрокаПоиска);
Сообщить(ЭтоМайлРу);//вернет Истина


Возникает ошибка
{ВнешняяОбработка.ВнешняяОбработка1.МодульОбъекта(22,10)}: Процедура или функция с указанным именем не определена (СтрНачинаетсяС)
Сообщить(<<?>>СтрНачинаетсяС("http://google.com", "http://"));

Но можно сделать по-другому

СтрокаПоиска = "@mail.ru";
Сообщить(Прав("vasya_pupkin@mail.ru",СтрДлина(СтрокаПоиска))=СтрокаПоиска); //вернет истина


Функция работы со строками СтрРазделить(<Строка>,<Разделитель>,<ВключатьПустые>)
Функция работы со строками СтрСоединить(<Строки>, <Разделитель>)

 Функция СтрРазделить() разделяет строку на части по указанному разделителю.

 Функция СтрСоединить() соединяет строки из массива подстрок.

Массив = СтрРазделить("1,2,3,4,5,6,7,8,9,,10",",",Ложь);//вернет массив
Строка = СтрСоединить(Массив,",")//вернет 1,2,3,4,5,6,7,8,9,10

 

Удобные функции, но возникает ошибка

{(1,10)}: Процедура или функция с указанным именем не определена (СтрРазделить)
Массив = <<?>>СтрРазделить("1,2,3,4,5,6,7,8,9,,10",",",Ложь);//вернет массив
{(2,10)}: Процедура или функция с указанным именем не определена (СтрСоединить)
Строка = <<?>>СтрСоединить(Массив,",")//вернет 1,2,3,4,5,6,7,8,9,10


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

См. также

Вознаграждение за ответ
Сумма: 0 $m
Добавили:
Denis Michaylov (denis_aka_wolf) (5.00 $m)
Подписаться Добавить вознаграждение
Лучшие комментарии
11. Артем Целовальников (slazzy) 11.06.15 09:48
В статье не упомянуто, что для многих из функций есть прямые аналоги в БСП и сейчас любой адекватный человек использует именно их из модуля СтроковыеФункцииКлиентСервер, предполагаю, что все функции останутся для совместимости ещё какое-то время, просто вероятно они внутри себя со временем станут использовать новые платформенные функции, но интерфейс вызова останется старый.
На текущий момент весь модуль СтроковыеФункцииКлиентСервер в БСП 2.3 оставлен без изменений для совместимости.
Mr Roudyk; Rusel; Aleskey_K; CyberCerber; ivashchenko_tatyanka; denis_aka_wolf; Bazil; +7 Ответить 2
Остальные комментарии
1. Алексей (Alexey_) 10.06.15 16:34
2. Xer shi (Xershi) 10.06.15 17:27
Так это и так понятно. Платформу как раз и обновляют чтобы использовать новые функции...
3. Александр Топольский (AlexanderKai) 10.06.15 17:32
Что мешает использовать СистемнаяИнформация.ВерсияПриложения?
4. Denis Michaylov (denis_aka_wolf) 10.06.15 18:37
(2) Xershi, Только не всегда в организациях следят за обновлением платформы.
Когда пишешь для "чужих" тогда нужно либо обязать их перейти на новую платформу, либо использовать старые механизмы работы.
rimma_n; ivashchenko_tatyanka; +2 Ответить
5. Denis Michaylov (denis_aka_wolf) 10.06.15 18:53
(3) AlexanderKai,
Когда пишете на "своих" конфигурациях, тогда можно делать что душе угодно, но когда разработка идет в "чужую" конфигурацию - стоит задуматься каким путем пойти:


1) Использовать новые функции и обязать заказчика перейти на свежую платформу
2) Сделать проверку текущей версии платформы и использовать новые функции и старые механизмы работы
3) Использовать только старые механизмы работы

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

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

И по третьему - самый оптимальный (мое субъективное мнение) гораздо проще второго варианта, но уступает первому в том что не помогает продвижению новых платформ в массы
6. Иван Петров (dgolovanov) 10.06.15 18:55
Так много старания это всё написать и так мало пользы.
7. Denis Michaylov (denis_aka_wolf) 10.06.15 18:59
Выскажите свое мнение каким образом лучше поступить при работе со строками во время разработки.
8. Василий Коровин (vasyak319) 10.06.15 19:53
Я правильно понял смысл публикации - рассказать всему миру, что функции, появившиеся в новом релизе, не будут работать в старом релизе, потому что есть только в новом релизе?
Познавательная статья - теперь я знаю, что Капитана Очевидность зовут Денис.
cypherpunks01; philya; sergio199; Rusel; zShamaNz; JestN; BurningChrome; JIeHIH; sigmov; hulio; herfis; Frogger1971; _also; SerSh_Perm; sh_max; starik-2005; delete; Bassgood; Natalii; gr0m; sergelemon; CyberCerber; madonov; dgolovanov; gubanoff; Black Romeo; Dach; slazzy; Gravemaggot; Bazil; webester; NeviD; nihfalck; EliasShy; zqzq; Obscurus; karpik666; TMV; ojiojiowka; +39 Ответить
9. Анянов Михаил (insurgut) 10.06.15 20:00
Не забываем ставить плюсики... =)
10. Дмитрий Парамонов (mitya-paramonov) 11.06.15 06:12
Нам со стороны разрабатывали подсистему приема бюджетных обязательств по отыгранным тендерам и запросам котировок цен для БГУ 1.0 и нарукожопили с использованием новых функций.

(3) AlexanderKai, этот вариант не работает. Ругается на то что данной функции вообще нет.(7)

denis_aka_wolf, статью поправь, второй вариант не рабочий.
12. Kostya Zhurov (It-developer) 11.06.15 10:59
Самые интересные - СтрРазделить(), СтрСоединить()
ivashchenko_tatyanka; +1 Ответить
13. Александр Топольский (AlexanderKai) 11.06.15 11:42
(10) mitya-paramonov,
Если добавишь строчку
СистемнаяИнформация = Новый СистемнаяИнформация;
то заработает.
14. Denis Michaylov (denis_aka_wolf) 11.06.15 12:07
(13) AlexanderKai,

СистемнаяИнформация = Новый СистемнаяИнформация;
Если СистемнаяИнформация.ВерсияПриложения = "8.3.6.1977" тогда
	   Сообщить(СтрНайти("2212","1")); //вернет 3
Иначе
	   Сообщить(СтроковыеФункцииКлиентСервер.НайтиСимволСКонца("2212","1"));
КонецЕсли;
...Показать Скрыть


Такой код все равно работать не будет!
15. Denis Michaylov (denis_aka_wolf) 11.06.15 12:11
(11) slazzy, Спасибо, добавлю в статью сегодня вечером.

(10) mitya-paramonov, Спасибо, поправлю.
16. Сергей (seermak) 11.06.15 14:17
а где описания про другие новые функции? пример: ПолучитьИсполняемуюСхемуКомпоновкиДанных() и т.д.)))))
17. Denis Michaylov (denis_aka_wolf) 11.06.15 14:48
(16) seermak, Это метод а не функция
18. Сергей (seermak) 11.06.15 17:45
(16)исправлено: .....другие методы и функции......
19. Василий Коровин (vasyak319) 11.06.15 18:04
(17) denis_aka_wolf, это и то и другое. Сбоите, кэп.
20. Дмитрий Шерстобитов (DitriX) 12.06.15 14:02
(7) все очень просто - создаете глобальную функцию с такими же названиями и используете ее, если у человека новая платформа - то ему достаточно заккоментить эту функцию. Как бы проблем нет.
ojiojiowka; +1 Ответить 1
21. e chikurov (eech) 13.06.15 12:23
Небольшое уточнение:
"Сообщить(СтрСравнить("Первая строка", "Вторая строка")); //вернет Истина"
вернет не "Истина", а "1"
22. Denis Michaylov (denis_aka_wolf) 15.06.15 05:36
23. Yauhen Makei (mrDSide) 17.06.15 09:16
24. Никита Грызлов (nixel) 17.06.15 10:31
25. Gennady Gennady (mister_tula) 17.06.15 13:53
Кто-нибудь еще заметил, как работают табличные части с несколькими "этажами" (несколько реквизитов в группе) в 8.3.6 - полный косяк !!! Как живут с этим многомилионные пользователи 1С ?
26. Алексей Драчков (Bassgood) 17.06.15 16:21
(14) denis_aka_wolf, а если использовать Вычислить(), то все заработает
27. Алексей Драчков (Bassgood) 17.06.15 16:31
(0) Вообще статью можно было бы свести к одной фразе - при разработке чего-либо (конфигурации, подсистемы, отчета, обработки) для неопределенного заказчика/клиента/покупателя необходимо учитывать возможные варианты использования у них различных версий платформы, режимов совместимости с версиями и интерфейсом, использования модальности и синхронных вызовов. И это будет более полно, чем вся публикация.
28. Виктор Назаров (androgin) 17.06.15 17:55
глупая статья. все это написано в релизе 1С
и нужно быть совсем недалеким, чтобы это не осознавать
29. vad013 --- (vad013) 20.06.15 10:21
Проверил вчера на релизе 8.3.6.2041.
Эти новые функции есть в Синтакс-помощнике, но при попытке их использовать выдается ошибка "Процедура или функция с указанным именем не определена ...".
30. vad013 --- (vad013) 20.06.15 10:26
ошибка пропадет, если снять режим совместимости
31. Андрей Лещанов (Nuuq) 22.06.15 08:54
(0) denis_aka_wolf,
СтрРазделить
Массив = Новый Массив();
Строка = "1,2,3,4,5,6,7,8,9,,10";	
Разделитель = ",";
Символ = Найти(Строка, Разделитель);
Пока Символ > 0 Цикл
	Если СтрДлина(Лев(Строка, Символ - 1)) > 0 Тогда
		МассивЗначений.Добавить(Лев(Строка, Символ - 1));
	КонецЕсли;
	Строка = Прав(Строка, СтрДлина(Строка) - Символ);
	Символ = Найти(Строка, Разделитель);
КонецЦикла;
Если СтрДлина(Строка) > 0 Тогда
	МассивЗначений.Добавить(Строка);
КонецЕсли;
...Показать Скрыть

СтрСоединить
Строка = "";
Для каждого Элемент Из Массив Цикл
	Строка = Строка + СокрЛП(Элемент) + ",";
КонецЦикла;


P.S.: новые функции конечно гораздо удобнее. Спасибо за обзор - ведь сюда "лазишь" чаще чем в Зазеркалье ;)
32. Василий Коровин (vasyak319) 22.06.15 09:47
(31) Nuuq, ваша СтрСоединить выдаст лишнюю запятую в конце.
constantinevio; sergio199; +2 Ответить
33. Захарий Газизов (Zahary) 26.06.15 10:59
- сравнение производительности функции СтрШаблон по сравнению с СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку
В циклах лучше не использовать. Подозреваю, что остальные функции такие же быстрые :(
34. Василий Коровин (vasyak319) 26.06.15 11:32
(33) Zahary, по вашему замеру получается, что собрать строку простым сложением прямо на месте втрое дольше, чем вызвать функцию модуля с десятью параметрами и собрать в ней ту же самую строку (код функции я не смотрел, но он, очевидно, посложнее простой конкатенации строк).
Не верю.
В замере производительности есть флажок "Включать для функций время выполнения" - вы его ставили?
35. Владимир Чаклин (vec435) 14.09.15 14:32
(11) slazzy, аналога СтрНайти нет
36. Erne100 (Erne100) 27.10.15 14:19
(20) DitriX, Всё так кроме : СтрНайти(<Строка>, <ПодстрокаПоиска>, <НаправлениеПоиска>, <НачальнаяПозиция>, <НомерВхождения>)

Системное перечисление НаправлениеПоиска в режиме совместимости отсутствует.
susorov; denis_aka_wolf; +2 Ответить 1
37. Petr Bubnov (bubnov-pi) 02.11.15 09:29
Не являюсь программистом в 1С, занимаюсь в основном обеспечением работоспособности существующих систем, но временами приходится залезать в код клиентских конфигураций. И буквально на днях возникла необходимость добавить разбор массива, поступающего в web-сервис. Первая мысль - найти аналог explode (php)... в справке нашёл, но на клиентской конфигурации оно не работает (как я понял, из-за режима совместимости). Спасибо (31) - направил на решение. В итоге в обработке появилась функция:
Функция СтрРазделить(Строка, Разделитель, ВключатьПустые = Ложь)
	МассивЗначений = Новый Массив();
	Символ = Найти(Строка, Разделитель);
	Пока Символ > 0 Цикл
	    Если ВключатьПустые или (СтрДлина(Лев(Строка, Символ - 1)) > 0) Тогда
        	МассивЗначений.Добавить(Лев(Строка, Символ - 1));
    	КонецЕсли;
    	Строка = Прав(Строка, СтрДлина(Строка) - Символ);
    	Символ = Найти(Строка, Разделитель);
	КонецЦикла;
	Если (ВключатьПустые или СтрДлина(Строка) > 0) Тогда
	    МассивЗначений.Добавить(Строка);
	КонецЕсли;
	Возврат МассивЗначений;
КонецФункции
...Показать Скрыть

Вроде работает. Поправьте, если где накосячил.
white_sochi; sergio199; +2 Ответить
38. Петр Сусоров (susorov) 17.08.16 17:09
(36) Erne100, А может быть встречал кто функцию с такими же возможностями, как эта новая СтрНайти() ? Ведь порой надо искать именно с конца, и удобно было бы использовать в режимах совместимости аналогичную функцию, хотя бы с первыми тремя параметрами... Народ бы сказал за такую функцию Спасибо!
39. Константин Рыбаков (constantinevio) 06.10.16 14:31
Я тут на скорую руку накидал. Вроде все работает, но особо не тестил. Все параметры такие же как и в СтрНайти. Единственное, надо глобально заменить НаправлениеПоиска.СКонца НаправлениеПоиска.СНачала на "СКонца" и "СНачала" соответственно.

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