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

Опубликовал 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) 203 06.08.13 11:00 Сейчас в теме

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

Читерство:

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

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

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

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

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

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


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

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

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