Склонение в 1С

Источник: https://1c-programmer-blog.ru/programmirovanie/sklonenie-v-1s.html

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

Внешняя компонента

Начнем с самого, вероятно, популярно на сегодняшний день способа — внешняя компонента «Склонение ФИО». Эта компонента существует в двух вариантах: по технологии COM и по технологии Native API. Вариант выполненный по технологии Native API современнее и предпочтительнее.

При скачивании с сайта ИТС мы получаем архив который содержит файл «NAMEDECL.DLL» и файл «NameDecl.zip». Первый файл — это компонента по технологии COM, а второй файл — это архив содержащий компоненту по технологии Native API (он так и используется в архиве).

Компоненту выполненную по технологии COM сначала нужно зарегистрировать, командой «regsvr32» от имени администратора:

Регистрация внешней компоненты


Пример использования:

&НаКлиенте

Процедура КомпонентаCOM(Команда)

Компонента = "C:\NameDecl.dll";

Попытка

ЗагрузитьВнешнююКомпоненту(Компонента);

Объект = Новый("AddIn.NameDeclension");

Исключение

Сообщить("Не удалось загрузить внешнюю компоненту по причине: " + ОписаниеОшибки());

КонецПопытки;

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 2, 1)); //родительный, пол мужской

Сообщить(Объект.Просклонять("Иванова Анна Ивановна", 3, 2)); //дательный, пол женский

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 4)); //винительный, пол авто

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 5)); //творительный, пол авто

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 6)); //предложный, пол авто

КонецПроцедуры


&НаКлиенте

Процедура КомпонентаCOM(Команда)

Компонента = "C:\NameDecl.dll";

Попытка

ЗагрузитьВнешнююКомпоненту(Компонента);

Объект = Новый("AddIn.NameDeclension");

Исключение

Сообщить("Не удалось загрузить внешнюю компоненту по причине: " + ОписаниеОшибки());

КонецПопытки;

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 2, 1)); //родительный, пол мужской

Сообщить(Объект.Просклонять("Иванова Анна Ивановна", 3, 2)); //дательный, пол женский

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 4)); //винительный, пол авто

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 5)); //творительный, пол авто

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 6)); //предложный, пол авто

КонецПроцедуры

Компоненту выполненную по технологии Native API регистрировать не нужно, ее необходимо поместить в общий макет (тип макета — «Внешняя компонента») и использовать примерно таким кодом:

&НаКлиенте

Процедура КомпонентаNative(Команда)

УстановитьВнешнююКомпоненту("ОбщийМакет.КомпонентаСклонений");

Попытка

ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаСклонений", "NameDecl" , ТипВнешнейКомпоненты.Native);

Объект = Новый("AddIn.NameDecl.CNameDecl");

Исключение

Сообщить("Не удалось подключить внешнюю компоненту по причине: " + ОписаниеОшибки());

КонецПопытки;

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 2, 1)); //родительный, пол мужской

Сообщить(Объект.Просклонять("Иванова Анна Ивановна", 3, 2)); //дательный, пол женский

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 4)); //винительный, пол авто

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 5)); //творительный, пол авто

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 6)); //предложный, пол авто

КонецПроцедуры


&НаКлиенте

Процедура КомпонентаNative(Команда)

УстановитьВнешнююКомпоненту("ОбщийМакет.КомпонентаСклонений");

Попытка

ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаСклонений", "NameDecl" , ТипВнешнейКомпоненты.Native);

Объект = Новый("AddIn.NameDecl.CNameDecl");

Исключение

Сообщить("Не удалось подключить внешнюю компоненту по причине: " + ОписаниеОшибки());

КонецПопытки;

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 2, 1)); //родительный, пол мужской

Сообщить(Объект.Просклонять("Иванова Анна Ивановна", 3, 2)); //дательный, пол женский

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 4)); //винительный, пол авто

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 5)); //творительный, пол авто

Сообщить(Объект.Просклонять("Иванов Иван Иванович", 6)); //предложный, пол авто

КонецПроцедуры

Как уже говорилось выше, компонента выполненная по технологии Native API предпочтительнее, так как работает и в ОС Linux, в тоже время ее можно использовать и на клиенте и на сервере.

Вариант применения

// Функция склоняет переданую фразу

// Параметры:

// Фраза (обязательный), тип строка

// Параметр должен содержать фразу. Каждое слово фразы будет просклонено отдельно

//

// Падеж (обязательный), тип число

// Падеж, в который необходимо поставить ФИО.

// 1 - Именительный

// 2 - Родительный

// 3 - Дательный

// 4 - Винительный

// 5 - Творительный

// 6 - Предложный

//

//Функция Просклонять(Компонента, Знач Фраза = "", Падеж = 1, Пол = Неопределено, Результат) Экспорт

УниверсальныеМеханизмы.Просклонять(глЗначениеПеременной("глКомпонентаСклоненияФИО"), Слово, Падеж, Пол , СловоВПадеже);

Веб-сервис

Еще одним способом просклонять что-либо является использование веб-сервиса «Морфер». Сервис бесплатный, хотя имеет и платный вариант, кроме этого функционал «Морфера» доступен в виде платной внешней компоненты.

Основным недостатком данного метода является его негарантированная работоспособность — нет интернета или сервис не доступен.

Использование веб-сервиса выглядит так:


&НаКлиенте

Процедура СервисСклонения(Команда)

СклоняемыйТекст = "Пушкин Александр Сергеевич";

АдресСервера = "ws3.morpher.ru";

Соединение = Новый HTTPСоединение(АдресСервера,,,,,, Новый ЗащищенноеСоединениеOpenSSL());

ТекстЗапроса = "/russian/declension?s=" + СклоняемыйТекст;

Заголовки = Новый Соответствие;

Заголовки.Вставить("User-Agent", "1C Enterprise 8.3");

Заголовки.Вставить("Accept", "application/json");

Заголовки.Вставить("charset", "UTF-8");

Запрос = Новый HTTPЗапрос(ТекстЗапроса, Заголовки);

Ответ = Соединение.Получить(Запрос);

Если Ответ.КодСостояния = 200 Тогда

ЧтениеJSON = Новый ЧтениеJSON;

ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());

СтруктураОтвета = ПрочитатьJSON(ЧтениеJSON);

ЧтениеJSON.Закрыть();

Сообщить(СтруктураОтвета.Р);

Сообщить(СтруктураОтвета.Д);

Сообщить(СтруктураОтвета.В);

Сообщить(СтруктураОтвета.Т);

Сообщить(СтруктураОтвета.П);

КонецЕсли;

КонецПроцедуры


&НаКлиенте

Процедура СервисСклонения(Команда)

СклоняемыйТекст = "Пушкин Александр Сергеевич";

АдресСервера = "ws3.morpher.ru";

Соединение = Новый HTTPСоединение(АдресСервера,,,,,, Новый ЗащищенноеСоединениеOpenSSL());

ТекстЗапроса = "/russian/declension?s=" + СклоняемыйТекст;

Заголовки = Новый Соответствие;

Заголовки.Вставить("User-Agent", "1C Enterprise 8.3");

Заголовки.Вставить("Accept", "application/json");

Заголовки.Вставить("charset", "UTF-8");

Запрос = Новый HTTPЗапрос(ТекстЗапроса, Заголовки);

Ответ = Соединение.Получить(Запрос);

Если Ответ.КодСостояния = 200 Тогда

ЧтениеJSON = Новый ЧтениеJSON;

ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());

СтруктураОтвета = ПрочитатьJSON(ЧтениеJSON);

ЧтениеJSON.Закрыть();

Сообщить(СтруктураОтвета.Р);

Сообщить(СтруктураОтвета.Д);

Сообщить(СтруктураОтвета.В);

Сообщить(СтруктураОтвета.Т);

Сообщить(СтруктураОтвета.П);

КонецЕсли;

КонецПроцедуры

Отмечу, что приведен минимально необходимый код, для реального применения будет разумно добавить какие-то проверки и обработки возможных ошибок.

Средства платформы

И, наконец, рассмотрим недавно добавленную функцию «ПолучитьСклоненияСтроки». Данная функция не блещет функциональностью (вероятно, со временем это изменится), но свою основную задачу выполняет исправно и очень проста в использовании. Третий параметр функции указан как необязательный, но если его не указать, то склонение не будет выполнено. В следующей версии платформы — 8.3.14, была добавлена еще одна функция: ПолучитьСклоненияСтрокиПоЧислу()» . Она позволяет формировать фразы которые содержать какое-либо значение. Пример использования обеих функций:


&НаСервере

Функция СклонениеПлатформаНаСервере()

Результат = ПолучитьСклоненияСтроки("Пушкин Александр Сергеевич", "Л=ru_RU;ПЛ=Мужской", "ПД=Родительный");

//Результат[0] //Пушкина Александра Сергеевича

//эта функция доступна в версии платформы 8.3.14 и выше

Результат = ПолучитьСклоненияСтрокиПоЧислу("стул", 12, "", "ЧС=Порядковое", "ПД=Родительный; ПЧ=ЧислоСОкончанием");

//Результат[0] //12-го стула

Результат = ПолучитьСклоненияСтрокиПоЧислу("автомобиль", 5, "", "ЧС=Количественное", "ПД=Дательный; ПЧ=ЧислоПрописью");

//Результат[0] //пяти автомобилям

Результат = ПолучитьСклоненияСтрокиПоЧислу("медный купорос", 3.5, "килограмм, грамм, 2", "ЧС=Количественное", "ПД=Винительный; ПЧ=ЧислоПрописью");

//Результат[0] //три килограмма пятьдесят граммов медного купороса

КонецФункции


&НаСервере

Функция СклонениеПлатформаНаСервере()

Результат = ПолучитьСклоненияСтроки("Пушкин Александр Сергеевич", "Л=ru_RU;ПЛ=Мужской", "ПД=Родительный");

//Результат[0] //Пушкина Александра Сергеевича

//эта функция доступна в версии платформы 8.3.14 и выше

Результат = ПолучитьСклоненияСтрокиПоЧислу("стул", 12, "", "ЧС=Порядковое", "ПД=Родительный; ПЧ=ЧислоСОкончанием");

//Результат[0] //12-го стула

Результат = ПолучитьСклоненияСтрокиПоЧислу("автомобиль", 5, "", "ЧС=Количественное", "ПД=Дательный; ПЧ=ЧислоПрописью");

//Результат[0] //пяти автомобилям

Результат = ПолучитьСклоненияСтрокиПоЧислу("медный купорос", 3.5, "килограмм, грамм, 2", "ЧС=Количественное", "ПД=Винительный; ПЧ=ЧислоПрописью");

//Результат[0] //три килограмма пятьдесят граммов медного купороса

КонецФункции