gifts2017

Функция Синоним для наименования

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

Аналог встроенной в платформу функции, преобразовывающей наименование в синоним. Пример: СуммаБезНДС -> Сумма без НДС

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

ТипДокументовРасчета -> Тип документов расчета
Сумма -> Сумма
ДокументыДляЕНВД -> Документы для ЕНВД
СуммаСНДС -> Сумма с НДС
СуммаБезНДС -> Сумма без НДС
ДляФНСЗаКвартал -> Для ФНС за квартал
ПФРДляОтчетности -> ПФР для отчетности

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

 

Код функции:

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

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Сергѣй Батанов (baton_pk) 06.08.13 11:00

Имя = СтрЗаменить(Имя, "СНДС", "_сНДС");

Читерство:

Передача ВПФР
Сумма СНДФЛ
2. nick-max nick-max (nick-max) 06.08.13 11:29
(1) ну да, читерство

но платформа сама не умеет отделять предлоги от аббревиатур (см. приложение)
поэтому логично написать это как исключения. Можно, конечно, анализировать первый символ аббревиатуры на предмет его принадлежности к какой-нибудь заранее определенной группе предлогов ("С", "В", "К" и др.), но ведь есть аббревиатуры, начинающиеся с этих букв ("СЗВ", к примеру). Тогда получится БланкСЗВ Бланк с ЗВ.
Полный перечень аббревиатур тоже не хочется заводить, потому что он в любом случае будет неполный.
Прикрепленные файлы:
3. Андрей Акулов (DrAku1a) 07.08.13 02:37
Все она умеет, просто подход знать надо (см. приложение).
Прикрепленные файлы:
Oleg_nsk; Diego_Iv; aet; +3 Ответить
4. Андрей Акулов (DrAku1a) 07.08.13 02:59
На правах рекламы: в обработке Отладчик запросов в главном модуле есть такая процедура:
// Преобразовывает имя переменной к более читабельному виду, аналогично внутренним алгоритмам 1С
// Например "ОбменСБазой" -> "Обмен с базой"
Функция глозПредставлениеПеременной(знач ИмяПеременной) Экспорт
	Перем МаленькиеБуквы, Цифры, Буква, Ответ, сч, ПредыдущаяБуква, СледующаяБуква;
	ИмяПеременной = СокрЛП(ИмяПеременной);
	МаленькиеБуквы = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя_";
	Цифры="0123456789.";
	Буква = Лев(ИмяПеременной, 1);
	Ответ = ""+Буква;
	Для сч=2 По СтрДлина(ИмяПеременной) Цикл
		ПредыдущаяБуква = Буква;
		Буква = Сред(ИмяПеременной, сч, 1);
		Если (Найти(МаленькиеБуквы, Буква)=0) и (Найти(МаленькиеБуквы, ПредыдущаяБуква)>0) Тогда
			СледующаяБуква = Сред(ИмяПеременной, сч+1, 1);
			Если (СледующаяБуква<>"") и (Найти(МаленькиеБуквы, СледующаяБуква)>0) Тогда
				Буква = НРег(Буква);
			КонецЕсли;
			Буква = " "+Буква;
		ИначеЕсли (Найти(Цифры, Буква)>0) и (Найти(Цифры, ПредыдущаяБуква)=0) Тогда
			Буква = " "+Буква;
		КонецЕсли;
		Ответ = Ответ + Буква;
	КонецЦикла;
	Ответ = СтрЗаменить(Ответ, "_", " ");

	//этого пока нет в релизе - убирает все задвоенные пробелы, типа "Сумма___С_НДС" --> "Сумма   с НДС"
	Пока Найти(Ответ, "  ")>0 Цикл Ответ = СтрЗаменить(Ответ, "  ", " ") КонецЦикла;
	
	Возврат Ответ;
КонецФункции
...Показать Скрыть
5. V. L. (Vladal) 07.08.13 12:06
(0)
так как полноценного качественного варианта предложено так и не было
некрасиво как-то. переформулируйте.
6. nick-max nick-max (nick-max) 08.08.13 17:49
(5) Ок.

Вот, сравнил результаты всех наших функций на деле:
Прикрепленные файлы:
7. V. L. (Vladal) 09.08.13 20:58
(6) Вы не поняли. Цитата а-ля "я д'Артаньян".
За проделанную работу плюс. Похвально.
8. Сергей (ildarovich) 09.08.13 22:28
(6) А почему моей функции из комментариев к той же публикации нет?? Она самая короткая! И работает "по платформе"
Функция Синонимайзер(Имя, Ответ = "", Стэйт = 7, б = "") Экспорт
	Для ё = 1 По СтрДлина(Имя) Цикл
		а = Сред(Имя, ё, 1);
		Стэйт = (НРег(а) <> а) * 4 + Цел(Стэйт / 2);
		Ответ = Ответ + ?(Стэйт = 2, НРег(б), ?(ё = 2, ВРег(б), б)) + ?(Стэйт = 4 ИЛИ Стэйт = 5, " ", "");
		б = а
	КонецЦикла;
	Возврат Ответ + б
КонецФункции
...Показать Скрыть

Добавьте к своей таблице число строк в записи функций.
И еще с цифрами должны быть обязательно тесты.
9. nick-max nick-max (nick-max) 12.08.13 12:21
(6) Хорошо, сейчас протестирую вашу функцию тоже
Но я считаю, что длина функции в данном случае не играет большой роли
10. nick-max nick-max (nick-max) 12.08.13 13:36
Чтобы преобразования с цифрами были тоже корректны, поменял строку
 Если Символ = НРег(Символ) Тогда 

На
 Если Символ = НРег(Символ) И Найти("1234567890", Символ) = 0 Тогда 


Вот новые результаты сравнения функций:
Прикрепленные файлы:
11. V. L. (Vladal) 13.08.13 06:24
У нас появился юный плагиатор, значит идея интересная.
http://infostart.ru/public/196029/
12. nick-max nick-max (nick-max) 13.08.13 16:23
(11) Ну, что делать)

Если у нас уже есть четыре функции, то почему бы не быть еще пятой)
13. nick-max nick-max (nick-max) 13.08.13 17:33
Кстати, функция от ildarovich из (8) судя по таблице и правда работает точно "по платформе". Разве что нижние подчеркивания не учитывает. Но встроенная платформенная функция тоже не идеал. Так уж повелось, что разработчики типовых решений (а за ними и все остальные) каждого новое слово в наименовании начинают с большой буквы, даже если это слово идет за аббревиатурой. Например,
РегламентированныйОтчетНДССправкаОДебиторскойЗадолженности
а не
РегламентированныйОтчетНДСсправкаОдебиторскойЗадолженности

А создатели платформы, наверное, думали, что в ходу будет именно второй вариант
Так что просто слепо следовать платформе тоже не стоит
14. Starik (Starik) 20.08.13 10:06
Функция для тех кому лень или некогда разбираться, но нужен результат - спасибо автору)
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа