IE 2016

Склонение ФИО

Опубликовал Коган Эстер (e.kogan) в раздел Программирование - Универсальные функции

Склонение ФИО в виде небольшой процедуры. Писалось студентом-программистом и студентом-лингвистом.

В файле - процедуры для 7.7 и для 8.х. В процедуру передаётся строка в формате Фамилия Имя Отчество.

 

UPD 26.11.10: с благодарностью Александру Смоленскому  - новая версия функции. Я - не тестировала! Вопросы по работе этой версии - к нему, выкладывать сам почему-то не хочет :)


	 Функция ПадежФИО(Знач ФИО,Падеж=1,ТолькоИнициалы=Ложь, Знач пРазделитель=".") 
    Если ТипЗнч(ФИО)<>Тип("Строка") Тогда
        Сообщить("Неверная строка передана ""падежу ФИО!"""); Возврат ФИО;
    КонецЕсли;

    // уберем множественные пробелы
    Пока 1=1 Цикл
        ФИО=СокрЛП(СтрЗаменить(ФИО," "," "));
        Если Найти(ФИО," ")=0 Тогда Прервать КонецЕсли;
    КонецЦикла;

    Если ТипЗнч(Падеж)=Тип("Строка") Тогда
        пад=СокрЛП(НРег(Лев(Падеж,1)));
        Если Найти("ирдвтп",пад)=0 Тогда
            Сообщить("Неверный падеж передан ""падежу ФИО""!"); Возврат ФИО;
        КонецЕсли;
    ИначеЕсли ТипЗнч(Падеж)=Тип("Число") Тогда
        Если (Падеж<1) или (Падеж>6) Тогда
            Сообщить("Неверный падеж передан ""падежу ФИО""!"); Возврат ФИО;
        КонецЕсли;
        пад=Падеж-1;
    КонецЕсли;

    ФИО=СокрЛП(НРег(ФИО)); // так удобнее

    // свой анализатор состава
    Фамилия="";
    Для й=1 По СтрДлина(ФИО) Цикл
        символс=Сред(ФИО,й,1);
        Если символс=" " Тогда Прервать КонецЕсли;
        Фамилия=Фамилия+символс;
    КонецЦикла;
    ы=й+1; // перешли пробел
    Имя="";
    Для й=ы По СтрДлина(ФИО) Цикл
        символс=Сред(ФИО,й,1);
        Если символс=" " Тогда Прервать КонецЕсли;
        Имя=Имя+символс;
    КонецЦикла;
    ы=й+1; // перешли второй пробел
    Отчество="";
    Для й=ы По СтрДлина(ФИО) Цикл
        символс=Сред(ФИО,й,1);
        Если символс=" " Тогда Прервать КонецЕсли;
        Отчество=Отчество+символс;
    КонецЦикла;

    // теперь имеем раздельно Фамилию, Имя и Отчество.
    // начинается собственно блок анализа содержания и падежей

    // вернем, если сам именительный. Если установлен возврат ТолькоИнициалы, то преобразуем в инициалы
    Если (Лев(Падеж,1)="И") или (Падеж=1) Тогда
        Если НЕ ТолькоИнициалы или Найти(ФИО, ".") Тогда
            Возврат ФИО; // либо уже преобразованная строка, либо не нужно преобразовывать
        КонецЕсли;
        НовоеФИО = ТРег(Фамилия) + " " + Врег(Лев(Имя,1)) + пРазделитель + Врег(Лев(Отчество,1)) + пРазделитель;
        Возврат СокрЛП(НовоеФИО); // на тот случай, если разделитель пробел. Последний срежем
    КонецЕсли;


    // проанализируем пол М/Ж
    Если Прав(Отчество,1)="а" Тогда Пол="Ж" Иначе Пол="М" КонецЕсли;

    // создадим структуру таблицы, хранящей окончания слов
    ток=Новый ТаблицаЗначений;
    ТипСтроки=Новый ОписаниеТипов("Строка",Новый КвалификаторыСтроки(3));
    ТипЧисла=Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(1,0));
    ток.Колонки.Добавить("СтарОк",ТипСтроки); // старое окончание 2 символа
    // колонки, хранящие новые окончания слов
    ток.Колонки.Добавить("р"); // родительный
    ток.Колонки.Добавить("д"); // дательный
    ток.Колонки.Добавить("в"); // винительный
    ток.Колонки.Добавить("т"); // творительный
    ток.Колонки.Добавить("п"); // предложный
    // для указания, сколько букв с конца слова отсечь,
    ток.Колонки.Добавить("КолвоСрез",ТипЧисла); // кол-во срезаемых букв

    Гласные="аеэоуиыяюьъ"; // список гласных букв в виде строки

    // ======== обработаем фамилию ==========
    // заполним таблицу данными для фамилии

    Если пол="М" Тогда
        строток=ток.Добавить(); // иванов
        строток.СтарОк="*s";
        строток.р="а"; строток.д="у"; строток.в="а"; строток.т="ым"; строток.п="е";
        строток.КолвоСрез=0;

        строток=ток.Добавить(); // красинский
        строток.СтарОк="*й";
        строток.р="ого"; строток.д="ому"; строток.в="ого"; строток.т="им"; строток.п="ом";
        строток.КолвоСрез=2;

        строток=ток.Добавить(); // всемогущий
        строток.СтарОк="щий";
        строток.р="его"; строток.д="ему"; строток.в="его"; строток.т="им"; строток.п="ем";
        строток.КолвоСрез=2;

        строток=ток.Добавить(); // белый
        строток.СтарОк="ый";
        строток.р="ого"; строток.д="ому"; строток.в="ого"; строток.т="ым"; строток.п="ом";
        строток.КолвоСрез=2;

        строток=ток.Добавить(); // палей
        строток.СтарОк="*й";
        строток.р="я"; строток.д="ю"; строток.в="я"; строток.т="ем"; строток.п="е";
        строток.КолвоСрез=1;

        строток=ток.Добавить(); // рабинович
        строток.СтарОк="*ч";
        строток.р="а"; строток.д="у"; строток.в="а"; строток.т="ем"; строток.п="е";
        строток.КолвоСрез=0;

        строток=ток.Добавить(); // починок, зализняк
        строток.СтарОк="*к";
        строток.р="ка"; строток.д="ку"; строток.в="ка"; строток.т="ком"; строток.п="ке";
        строток.КолвоСрез=2;

        строток=ток.Добавить(); // шинкарь
        строток.СтарОк="*ь";
        строток.р="я"; строток.д="ю"; строток.в="я"; строток.т="ем"; строток.п="е";
        строток.КолвоСрез=1;

        строток=ток.Добавить(); // перельман, оганесян
        строток.СтарОк="*н";
        строток.р="а"; строток.д="у"; строток.в="а"; строток.т="ом"; строток.п="е";
        строток.КолвоСрез=0;

        строток=ток.Добавить(); // баранкин
        строток.СтарОк="ин";
        строток.р="а"; строток.д="у"; строток.в="а"; строток.т="ым"; строток.п="е";
        строток.КолвоСрез=0;

    ИначеЕсли Пол="Ж" Тогда
        строток=ток.Добавить(); // склодовская
        строток.СтарОк="ая";
        строток.р="ой"; строток.д="ой"; строток.в="ую"; строток.т="ой"; строток.п="ой";
        строток.КолвоСрез=2;

        строток=ток.Добавить(); // иванова
        строток.СтарОк="*а";
        строток.р="ой"; строток.д="ой"; строток.в="у"; строток.т="ой"; строток.п="ой";
        строток.КолвоСрез=1;
    КонецЕсли;

    // таблица заполнена. считаем 2 последних буквы и поищем их
    Если не ПустаяСтрока(Фамилия) Тогда
        пб=Прав(Фамилия,3); кол="СтарОк"; // ищем по ней
        новФамилия=Фамилия; // если ничего не изменится, так и будет
        стро=ток.Найти(пб,кол);
        Если стро<>Неопределено Тогда // нашли строгое сразу
            Основа=Лев(Фамилия,СтрДлина(Фамилия)-стро.КолвоСрез);
            новФамилия=Основа+СокрЛП(стро[пад]);
        Иначе
            // строго не нашли по трем последним символам, ищем по двум символам только по последней
            пб=Прав(Фамилия,2);
            стро=ток.Найти(пб,кол);
            Если стро<>Неопределено Тогда
                Основа=Лев(Фамилия,СтрДлина(Фамилия)-стро.КолвоСрез);
                новФамилия=Основа+СокрЛП(стро[пад]);
            Иначе // если по двум не нашли, ищем по одному
                пб="*"+Прав(пб,1);
                стро=ток.Найти(пб,кол);
                Если стро<>Неопределено Тогда // нашли по последней
                    Основа=Лев(Фамилия,СтрДлина(Фамилия)-стро.КолвоСрез);
                    новФамилия=Основа+СокрЛП(стро[пад]);
                Иначе // по последней не нашли, ищем по виду буквы
                    пб="*"+?(Найти(Гласные,Прав(пб,1))=0,"s","g");
                    стро=ток.Найти(пб,кол);
                    Если стро<>Неопределено Тогда // нашли по виду
                        Основа=Лев(Фамилия,СтрДлина(Фамилия)-стро.КолвоСрез);
                        новФамилия=Основа+СокрЛП(стро[пад]);
                    КонецЕсли;
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    Иначе
        новФамилия="";
    КонецЕсли;

    // ======== обработаем имя ==========
    // заполним таблицу данными для имени
    ток.Очистить();

    Если Пол="М" Тогда
        // обработаем исключения
        Если Имя="лев" Тогда Имя="льв" КонецЕсли;
        Если Имя="павел" Тогда Имя="павл" КонецЕсли;

        строток=ток.Добавить(); // сергей
        строток.старок="*й";
        строток.р="я"; строток.д="ю"; строток.в="я"; строток.т="ем"; строток.п="е";
        строток.колвосрез=1;

        строток=ток.Добавить(); // иван + лев + павел
        строток.старок="*s";
        строток.р="а"; строток.д="у"; строток.в="а"; строток.т="ом"; строток.п="е";
        строток.колвосрез=0;

        строток=ток.Добавить(); // никита
        строток.старок="*а";
        строток.р="ы"; строток.д="е"; строток.в="у"; строток.т="ой"; строток.п="е";
        строток.колвосрез=1;

        строток=ток.Добавить(); // лука
        строток.старок="ка";
        строток.р="и"; строток.д="е"; строток.в="у"; строток.т="ой"; строток.п="е";
        строток.колвосрез=1;

        строток=ток.Добавить(); // иеремия
        строток.старок="ия";
        строток.р="и"; строток.д="и"; строток.в="ю"; строток.т="ей"; строток.п="и";
        строток.колвосрез=1;

        строток=ток.Добавить(); // илья
        строток.старок="*я";
        строток.р="и"; строток.д="е"; строток.в="ю"; строток.т="ей"; строток.п="е";
        строток.колвосрез=1;

        строток=ток.Добавить(); // игорь
        строток.старок="*ь";
        строток.р="я"; строток.д="ю"; строток.в="я"; строток.т="ем"; строток.п="е";
        строток.колвосрез=1;

    ИначеЕсли Пол="Ж" Тогда
        // обработаем исключения
        //Если Имя="ольга" Тогда Имя="ольгь" КонецЕсли;

        строток=ток.Добавить(); // ирина
        строток.старок="*а";
        строток.р="ы"; строток.д="е"; строток.в="у"; строток.т="ой"; строток.п="е";
        строток.колвосрез=1;

        строток=ток.Добавить(); // инга, ольга
        строток.старок="га";
        строток.р="и"; строток.д="е"; строток.в="у"; строток.т="ой"; строток.п="е";
        строток.колвосрез=1;

        строток=ток.Добавить(); // эсфирь
        строток.старок="*ь";
        строток.р="и"; строток.д="и"; строток.в="ь"; строток.т="ью"; строток.п="и";
        строток.колвосрез=1;

        строток=ток.Добавить(); // мария
        строток.старок="ия";
        строток.р="и"; строток.д="и"; строток.в="ю"; строток.т="ей"; строток.п="и";
        строток.колвосрез=1;

        строток=ток.Добавить(); // софья
        строток.старок="*я";
        строток.р="и"; строток.д="е"; строток.в="ю"; строток.т="ей"; строток.п="е";
        строток.колвосрез=1;
    КонецЕсли;

    // таблица заполнена. считаем 2 последних буквы и поищем их
    Если не ПустаяСтрока(Имя) Тогда
        пб=Прав(Имя,2); кол="СтарОк"; // ищем по ней
        новИмя=Имя; // если ничего не изменится, так и будет
        стро=ток.Найти(пб,кол);
        Если стро<>Неопределено Тогда // нашли строгое сразу
            Основа=Лев(Имя,СтрДлина(Имя)-стро.КолвоСрез);
            новИмя=Основа+СокрЛП(стро[пад]);
        Иначе // строго не нашли, ищем только по последней
            пб="*"+Прав(пб,1);
            стро=ток.Найти(пб,кол);
            Если стро<>Неопределено Тогда // нашли по последней
                Основа=Лев(Имя,СтрДлина(Имя)-стро.КолвоСрез);
                новИмя=Основа+СокрЛП(стро[пад]);
            Иначе // по последней не нашли, ищем по виду буквы
                пб="*"+?(Найти(Гласные,Прав(пб,1))=0,"s","g");
                стро=ток.Найти(пб,кол);
                Если стро<>Неопределено=1 Тогда // нашли по виду
                    Основа=Лев(Имя,СтрДлина(Имя)-стро.КолвоСрез);
                    новИмя=Основа+СокрЛП(стро[пад]);
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    Иначе
        новИмя="";
    КонецЕсли;

    // ======== обработаем отчество, тут проще ==========
    ток.Очистить();

    Если Пол="М" Тогда
        строток=ток.Добавить();
        строток.р="а"; строток.д="у"; строток.в="а"; строток.т="ем"; строток.п="е";
        строток.колвосрез=0;
    ИначеЕсли Пол="Ж" Тогда
        строток=ток.Добавить();
        строток.р="ы"; строток.д="е"; строток.в="у"; строток.т="ой"; строток.п="е";
        строток.колвосрез=1;
    КонецЕсли;
    Если не ПустаяСтрока(Отчество) Тогда
        Основа=Лев(Отчество,СтрДлина(Отчество)-ток[0].КолвоСрез);
        новОтчество=Основа+СокрЛП(ток[0][пад]);
    Иначе
        новОтчество="";
    КонецЕсли;

    Если ТолькоИнициалы Тогда
        новИмя=Лев(новИмя,1); новОтчество=Лев(новОтчество,1);
    КонецЕсли;

    // установим первые буквы верхним регистром
    новФамилия=ВРег(Лев(новФамилия,1))+Сред(новФамилия,2);
    новИмя=ВРег(Лев(новИмя,1))+Сред(новИмя,2);
    новОтчество=ВРег(Лев(новОтчество,1))+Сред(новОтчество,2);

    // и теперь всё вместе
    Если ТолькоИнициалы Тогда // если задан формат инициалов
        новФИО=новФамилия+" "+новИмя+пРазделитель+новОтчество+пРазделитель;
    Иначе
        новФИО=новФамилия+" "+новИмя+" "+новОтчество;
    КонецЕсли;

    Если Найти(ФИО, ".") Тогда // На тот случай, если входной параметр Фамилию с инициалами. Инициалы не трогаем
        новФИО = новФамилия + " " + ТРег(Имя) + Трег(Отчество);
    КонецЕсли;

    Возврат СокрЛП(новФИО);
КонецФункции

 

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
-
.1222867795 113,50Kb
31.08.14
1605
.1222867795 113,50Kb 1605 Скачать
Только для 8.1 (обновлено 17.08.09)
.1250495317 16,52Kb
31.08.14
247
.1250495317 16,52Kb 247 Бесплатно

См. также

Лучшие комментарии

10. halushka 02.10.2008 04:39
Хотел посмотреть, ан рейтингом не вышел. :( Жаль.
Ответили: (12) (11)
# Ответить
7. Abadonna 01.10.2008 18:22
(6) Да просто уже забодали любители "простых" решений ;)
А уж если меряться, у кого раньше, то вот: http://1c.proclub.ru/modules/mydownloads/personal.php?cid=111&lid=254
Написана КучерОМ Аркадием Арнольдовием в 2000 году. Чуток коряво, ибо это было первое, что я написал на 1С ваще. Однако КацА МойшУ АбрамовичА склоняла вполне корректно ;)))
Ответили: (9) (8)
# Ответить
43. Abadonna 08.10.2008 08:05
(42)>зря потратили время, в документах достаточно именительного падежа
Ну ежели тебе нравится "Доверенность выдана: Иванов Иван Иванович" - тогда достаточно
А мне нравится, когда "Доверенность выдана: ИвановУ ИванУ ИвановичУ" ;)
+ 2 [ RailMen; hame1e00n; ]
# Ответить

Комментарии

2. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 01.10.2008 17:33
Гораздо лаконичнее код..и написан задолго до 2003 года...
# Ответить
3. Коган Эстер (e.kogan) 01.10.2008 17:56
Лаконичнее. И сумбурнее.

Кому что нравится.
# Ответить
4. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 01.10.2008 18:00
Не вижу там никакого сумбура. Код гораздо приятнее. Даже у Рупора проще.
+ должности отрабатывает
+ специфические фамилии
+ каменты
+ примеры использования
+ 1 [ Fedos; ]
# Ответить
5. Кучер Аркадий (Abadonna) 01.10.2008 18:04
(1,2) Слабенький ответик-то получился ;)
Сообщить(ПадежС("Кучер",3,1,1) ); // дательный, мужик, склонять фамилию
Возвращет: Кучер
А вот фигушки! КучерУ, ЛебедЮ, Кушниру, КоганУ если речь идет о мужике. А вот для женщины подобные не склоняются.
А вот у автора вернула в дательном:
Кучеру Аркадию Арнольдовичу - я
Кучер Антонине Алексеевне - моя мама
т.е. абсолютно правильно
Ответили: (15) (14) (6)
# Ответить
6. Коган Эстер (e.kogan) 01.10.2008 18:11
(5) Спасибо, хотела сама потестировать предложенное, теперь тратить время не буду.
Ответили: (7)
# Ответить
7. Кучер Аркадий (Abadonna) 01.10.2008 18:22
(6) Да просто уже забодали любители "простых" решений ;)
А уж если меряться, у кого раньше, то вот: http://1c.proclub.ru/modules/mydownloads/personal.php?cid=111&lid=254
Написана КучерОМ Аркадием Арнольдовием в 2000 году. Чуток коряво, ибо это было первое, что я написал на 1С ваще. Однако КацА МойшУ АбрамовичА склоняла вполне корректно ;)))
Ответили: (9) (8)
# Ответить
8. Коган Эстер (e.kogan) 01.10.2008 19:23
(7) Ну, если уж говорить про Мойш, то правильно - МойшЕ. Или уж Моисей. Уменьшительно-ласкательные склонять задачи не ставилось, всё-таки официальные документы, ага )
# Ответить
9. Кучер Аркадий (Abadonna) 02.10.2008 02:55
(7) Здрасте! Склоняла КОГО? Мойше??? Я не про дательный, а про винительный в данном случае говорил. Что касается какие еврейские уменьшительные, а какие полные - то тут, сорри, я не спец :)))
Ответили: (17)
# Ответить
10. halushka (halushka) 02.10.2008 04:39
Хотел посмотреть, ан рейтингом не вышел. :( Жаль.
Ответили: (12) (11)
# Ответить
11. Кучер Аркадий (Abadonna) 02.10.2008 05:05
(10) Ну держи один плюсик ;) Щас гляну еще где твои комменты
# Ответить
12. Пономаренко Олег (O-Planet) 02.10.2008 05:10
(10) "Рейтингом не вышел" - это зачОООт! ))))))
# Ответить
13. 02.10.2008 08:49
Доступ C рейтингом не меньше 3 - FAIL.
Ответили: (17)
# Ответить
14. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 02.10.2008 09:04
(5) Не вопрос. Там есть второй вариант, от Рупора.. там правильнее. :)
# Ответить
15. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 02.10.2008 09:13
(5) И Самое Главное, ВАША неправда:

Сообщить(Падеж("Кучер" ,3,1,"1" )) = "Кучеру"
Ответили: (20)
# Ответить
16. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 02.10.2008 09:14
Так что, решение правильное, хотя и простое, и не писано "на основании серьёзного лингвистического исследования"
:)
# Ответить
17. Коган Эстер (e.kogan) 02.10.2008 10:26
(9) МойшА - это некорректно. Это уменьшительное, да к тому же и, скажем так, русифицированное.
(13) Доступ открыт. Промахнулась с переключателем.
Ответили: (18)
# Ответить
18. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 02.10.2008 10:30
(17) И всё же потести предложенное, оно рабочее.
Ответили: (23)
# Ответить
19. Кучер Аркадий (Abadonna) 02.10.2008 10:33
Честно признаюсь, что всегда думал что "Мойша" нормальное еврейское имя :))) Без уменьшительного, русифицированного и т.д.
# Ответить
20. Кучер Аркадий (Abadonna) 02.10.2008 10:34
(15) И самое главное, что я тестил Сообщить(ПадежС("Кучер",3,1,1) );
Падеж и еще буковка "С", а не просто Падеж. Когда мне их там сортировать было ;)
Ответили: (21)
# Ответить
21. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 02.10.2008 10:37
(20) Там же примеры есть в каментах! :)
# Ответить
22. Кучер Аркадий (Abadonna) 02.10.2008 10:49
2Ёпрст. Ты завязывай фладить, а давай начинай писать про Dialog Stream и Moxel :))))
# Ответить
23. Коган Эстер (e.kogan) 03.10.2008 11:26
(18) Потестила. Хорошооо... Спасибо.
# Ответить
24. Коган Эстер (e.kogan) 03.10.2008 15:27
О!

Меч в творительном - мечЕм, ага ) Нашли-таки мы не ловящееся )
Ответили: (25)
# Ответить
25. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 03.10.2008 16:23
(24) А вот и фигушки :)

Падеж("Меч",5,1,"1") = "Мечем"
Ответили: (26)
# Ответить
26. Коган Эстер (e.kogan) 03.10.2008 16:26
(25) А правильно-то - мечОм!
Ответили: (27)
# Ответить
27. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 03.10.2008 16:28
(26) Угу, тепереча тестим ваше творение - МечЕм ...
# Ответить
28. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 03.10.2008 16:29
+27 так что ничья... :)
Ответили: (29)
# Ответить
29. Коган Эстер (e.kogan) 03.10.2008 16:31
(28) Дык я и не спорю ;) Но предлагали потестить - я и потестила )
# Ответить
30. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 03.10.2008 16:35
Хотя...

Мечем Иваным Ивановичем альтернатива
Мечем Иваном Ивановичем ваш метод

тоже глюкаво... В общем, есть куда расти.
Даешь правильные алгоритмы!
Ответили: (31)
# Ответить
31. Коган Эстер (e.kogan) 03.10.2008 16:38
(30) Слуушайте... Так это он Ивана неправильно склоняет? Тц-тц-тц... А я-то уж губы раскатала, что хоть кто-то эту титаническую задачу решил на 99%...

Будем дорабатывать.
Ответили: (32)
+ 1 [ diteco; ]
# Ответить
32. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 03.10.2008 16:43
(31) Ну да...:)
Хотя, кому нужен творительный падеж в 1с-ине ? :)
Ответили: (34) (33)
# Ответить
33. Коган Эстер (e.kogan) 03.10.2008 16:48
(32) "Договор заключён с Мечом Иваном Ивановичем", например )
# Ответить
34. Коган Эстер (e.kogan) 03.10.2008 16:55
(32) Пофиксено: имена, оканчивающиеся на "ан", склоняет неправильно для творительного. Буду разбираться в этой перловке )))
Ответили: (35)
# Ответить
35. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 03.10.2008 17:44
(34) ...Эээ.. в какой обработке пофиксено ? В вашей ? Так там и так было правильно ...
Ответили: (36)
# Ответить
36. Коган Эстер (e.kogan) 03.10.2008 17:48
(35) Да нет, в предложенной как раз. Но так как собираюсь и её использовать, собираюсь и доводить её до полного блеска.
Ответили: (37)
# Ответить
37. Gjitk yf [eq? Ljh;b! Ёпрст (Ёпрст) 03.10.2008 17:54
(36) Не забудьте выложить потом для тестинга.
# Ответить
38. Коган Эстер (e.kogan) 05.10.2008 14:59
Слово "паяц" альтернатива склоняет совсем неправильно. В общем, есть куды ростить.
# Ответить
39. Кучер Аркадий (Abadonna) 05.10.2008 15:51
Как почему-то и думал, так и оказалось ;)
Сообщить(ПадежФИО("Черных Петр Петрович",2));
Сообщить(ПадежФИО("Берия Лаврентий Павлович",2));
Черныха Петра Петровича
// как раз случай, когда склонять не надо! А таких фамилий море - сибирские фамилии
Берия Лаврентия Павловича // а туточки надо БериЮ
Не надейся на универсальный алгоритм для фамилий, его нет!
Ответили: (41)
# Ответить
40. Кучер Аркадий (Abadonna) 05.10.2008 15:58
А вот как сделано у меня:
Код
   Если ДвеПоследних="УА" Тогда
      Винительный=Фамилия;//фамилии типа Стуруа
      Дательный=Фамилия;
   КонецЕсли;
   
   Если ДвеПоследних="ИА" Тогда
      Винительный=Фамилия;//фамилии типа Туташхиа
      Дательный=Фамилия;
   КонецЕсли;
   
   Если (ДвеПоследних="ЖА") И (Пол="Ж") Тогда
      Винительный=Фамилия;// женские фамилии типа Ганжа
      Дательный=Фамилия;
   КонецЕсли;
   
   Если ТриПоследних="ДЗЕ" Тогда
      Винительный=Фамилия;//грузинские фамилии типа Гогадзе
      Дательный=Фамилия;
      Перейти ~выход;
   КонецЕсли;
   
   Если ТриПоследних="ИЛИ" Тогда
      Винительный=Фамилия;//грузинские фамилии типа Габошвили
      Дательный=Фамилия;
   КонецЕсли;
          Если (ДвеПоследних="ИХ") ИЛИ  (ДвеПоследних="ЫХ") Тогда
      Винительный=Фамилия;//сибирские фамилии
      Дательный=Фамилия;
   КонецЕсли;
Показать полностью
Ответили: (46)
# Ответить
41. Кучер Аркадий (Abadonna) 05.10.2008 16:14
+(39) Так что лингвист - действительно студент :)))))
# Ответить
42. Катеринич Андрей (andrew87) 08.10.2008 07:52
зря потратили время, в документах достаточно именительного падежа
Ответили: (43)
# Ответить
43. Кучер Аркадий (Abadonna) 08.10.2008 08:05
(42)>зря потратили время, в документах достаточно именительного падежа
Ну ежели тебе нравится "Доверенность выдана: Иванов Иван Иванович" - тогда достаточно
А мне нравится, когда "Доверенность выдана: ИвановУ ИванУ ИвановичУ" ;)
+ 2 [ RailMen; hame1e00n; ]
# Ответить
44. 08.10.2008 11:52
ЗагрузитьВнешнююКомпоненту("NameDecl.dll");
КомпонентаСклоненияФамилий = СоздатьОбъект("AddIn.NameDeclension");
Слово = "Гадя Петрович Хренова"
НомерПадежа = 2; //Родительный
Сообщить(КомпонентаСклоненияФамилий.Просклонять(Слово,НомерПадежа));
//получаем ГадИ Петрович Хреновой


Компонента есть на диске ИТС, расчитана под восьмёрку, но и в 7.7 нормально работает
Ответили: (45)
# Ответить
45. 08.10.2008 12:00
(44) Пропустил точку с запятой, простите :)
У метода "просклонять" есть еще и 30-ий параметр - пол
# Ответить
46. Пономаренко Олег (O-Planet) 08.10.2008 12:05
(40) Мде... Про иначеесли в 2000-м ты похоже не знал ;) Оно ж даже если нашло ДвеПоследних="УА", то все остальные тоже станет проверять...
Ответили: (47)
# Ответить
47. Кучер Аркадий (Abadonna) 08.10.2008 12:26
(46) Планет слышал звон, да не знает, где он.
Не обратил внимание на строку, которую я в одном месте не удалил, а она стоит во ВСЕХ блоках:
Перейти ~выход;
И как раз спецом было сделано, чтобы эти блоки тупо копировать, вставлять и изменять, не добавляя ИначеЕсли.
Лично мне так больше нравится
# Ответить
49. Анатолий (hame1e00n) 13.07.2009 22:53
Процедура очень интересная, только скачать не могу - рейтинга маловато... плюсик поставил)
# Ответить
50. Александр (Diktis) 12.08.2009 02:09
Для имени "Ольга" в родительном падеже получаем "Ольгы"
Ответили: (52)
# Ответить
51. Коцюра Сергей (Che) (CheBurator) 12.08.2009 02:15
а чем Падеж "Крохотулька" с проклаба не нравится?
Ответили: (54) (52)
# Ответить
52. Коган Эстер (e.kogan) 12.08.2009 10:19
(50) Приведите ФИО полностью. На "Иванова Ольга Юрьевна" склоняет нормально.
(51) Дело не в том, что нравится или не нравится. Эта процедура была написана совершенно отдельно.
Ответили: (53)
# Ответить
53. Александр (Diktis) 13.08.2009 01:08
(52) ПадежФИО("Иванова Ольга Юрьевна", 2) = "Ивановой Ольгы Юрьевны"
Может я чего-то не понимаю, но откуда взяться другому результату?
"...
ИначеЕсли Пол="Ж" Тогда
строток=ток.Добавить(); // ирина
строток.старок="*а";
строток.р="ы";
..."
Ответили: (55)
# Ответить
54. Коган Яков (Yashazz) 17.08.2009 02:03
(51) Этой процедуре уж лет 8, не меньше...
Насчёт ОльгЫ посмотрим.
# Ответить
55. Коган Эстер (e.kogan) 17.08.2009 11:48
(53) Проверяла специально - получается "Ивановой Ольги Юрьевны". Чесслово. Если вводить без отчества - возможно.

Поправила, теперь Ольга, Инга и т.д. склоняются нормально.
# Ответить
56. Dream Nelli (nelli_dream) 17.08.2009 12:28
спасибо автору. мне очень помогла обработочка!
осталось решить вопрос со склонением профессий и цехов! ::)
Ответили: (57)
# Ответить
57. Коган Эстер (e.kogan) 17.08.2009 12:29
(56) Пользуйтесь процедурами Jurer'а. Они это вроде бы умеют.
# Ответить
58. Владимир (ARL) 13.08.2010 11:08
Авторам спасибо! Все реальные случаи функция отработала прекрасно. Добавил только точки к инициалам.
# Ответить
59. Попов Андрей (Andrew_flyer) 27.08.2010 12:34
Спасибо, молодцы!
+ 1 [ Alexander; ]
# Ответить
60. Ожерельев Сергей (Поручик) 01.09.2011 11:50
Раскрасить бы статью.
# Ответить
61. Kulikov Vyacheslav (ELInfinito) 23.09.2011 07:12
Спасибо за алгоритм!
Ответили: (62)
# Ответить
62. Коган Эстер (e.kogan) 23.09.2011 16:32
(61) Я передам мужу :)
# Ответить
63. Кирилл (kiros) 28.09.2011 12:04
Спасибо, небольшой тюнинг, если фамилия и.о. определение Ж рода по "а" и "я" в фамилии. Доработал и в работу.
Еще раз спасибо!
p.s. А косячки они у всех есть, как можно жить без косячков ;)
# Ответить
64. Эльвира (eli1984) 04.10.2011 06:56
Сейчас вроде нормально все работает. Спасибо за обработку. пользуюсь.
# Ответить
65. A Vadim (avavadim) 17.10.2011 02:41
Спасибо за текст обработки, все нормально работает...
# Ответить
66. Антон (Joker) 03.01.2012 10:55
Спасибо, вставил в конфу, все работает
# Ответить
67. Сергей Осипов (fixin) 04.04.2012 18:07
(0) А теперь проверьте ее моей тестилкой: http://infostart.ru/public/115909/, поищите ошибки.
А вообще нужно конечно писать склонение на технологии регистров правил, пусть и виртуальных, а не хранящихся в базе. Это будет прорыв. Но за попытку плюсую.
+ 1 [ ИНТЕГРА; ]
# Ответить
69. Иремадзе Леван (IRLes) 21.12.2012 10:28
Прокопчук Сергей Сергеевич - в родительном падеже получается Прокопчка Сергея Сергеевича
по идее должно быть Прокопчука Сергея Сергеевича!
# Ответить
70. Иремадзе Леван (IRLes) 21.12.2012 11:06
Удалено
# Ответить
71. muhaha muha (fr.myha) 10.07.2013 14:05
Делюсь функцией, возвращающая инициалы в дательном падеже:

// функция в зависимости от переданного параметра возвращает ФИО
//
// Параметры:
// ФИО - строка. Если Можно вводить только Фамилию или Фимилия Имя или полное ФИО,
// разделитель пробел.
// Пол - Перечисления.Пол
// ТипВывода - числа 1: полное ФИО
// 2: Фамилия И.О.
// 3: И.О. Фамилия
// Возвращаемое значение:
// строка - результат форматирования
Функция обДательныйПадежНаСервере(ФИО,Пол,ТипВывода=0) Экспорт

ФИО_Падеж="";
Фамилия="";
Имя="";
Отчество="";
ФамилияПадеж="";
ИмяПадеж="";
ОтчествоПадеж="";
ФИО=СокрЛП(ФИО);
Длина=0;

Если СтрЧислоВхождений(ФИО," ") = 0 Тогда
Фамилия = ФИО;
Длина = 1;
ИначеЕсли СтрЧислоВхождений(ФИО," ") = 1 Тогда
Фамилия = Лев(ФИО,Найти(ФИО," ")-1);
Имя = СтрЗаменить(ФИО,Фамилия+" ","");
Длина = 2;
ИначеЕсли СтрЧислоВхождений(ФИО," ") = 2 Тогда
Фамилия = Лев(ФИО,Найти(ФИО," ")-1);
Имя = Лев(СтрЗаменить(ФИО,Фамилия+" ",""),Найти(СтрЗаменить(ФИО,Фамилия+" ","")," ")-1);
Отчество = СтрЗаменить(СтрЗаменить(ФИО,Фамилия+" ",""),Имя+" ","");
Длина = 3;
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Предупреждение! Неправильно записано ФИО. Проверьте пробелы!" + Символы.ПС + "(обДательныйПадежНаСервере)";
Сообщение.Сообщить();
КонецЕсли;

Если (Нрег(Прав(Отчество,1))="ч") Тогда
ТекПол = Перечисления.Пол.Муж;
ИначеЕсли (Нрег(Прав(Отчество,1))="а") Тогда
ТекПол = Перечисления.Пол.Жен;
КонецЕсли;

Если ТекПол = Перечисления.Пол.Муж Тогда
КонецФамилии = Прав(Фамилия,1);
Если Нрег(КонецФамилии)="е"
ИЛИ Нрег(КонецФамилии) = "и"
ИЛИ Нрег(КонецФамилии) = "о"
ИЛИ Нрег(КонецФамилии) = "у"
ИЛИ Нрег(КонецФамилии) = "э"
ИЛИ Нрег(КонецФамилии) = "ю"
Тогда
ФамилияПадеж = Фамилия;
ИначеЕсли Нрег(КонецФамилии) = "я" Тогда
ФамилияПадеж = Лев(Фамилия,СтрДлина(Фамилия)-1) + "е";
ИначеЕсли Нрег(КонецФамилии) = "а" Тогда
ФамилияПадеж = Лев(Фамилия,СтрДлина(Фамилия)-1) + "е";
ИначеЕсли Нрег(КонецФамилии) = "й"
ИЛИ Нрег(КонецФамилии) = "ь"
Тогда
Если Нрег(Прав(Фамилия,2)) = "ий"
ИЛИ Нрег(Прав(Фамилия,2)) = "ый"
Тогда
ФамилияПадеж = Лев(Фамилия,СтрДлина(Фамилия)-2) + "ому";
Иначе
ФамилияПадеж = Лев(Фамилия,СтрДлина(Фамилия)-1) + "ю";
КонецЕсли
Иначе
Если Нрег(Прав(Фамилия,2)) = "ец" Тогда
ФамилияПадеж = Лев(Фамилия,СтрДлина(Фамилия)-2) + "цу";
Иначе
ФамилияПадеж = Фамилия + "у";
КонецЕсли
КонецЕсли;

Если Имя = "Лев" Тогда
ИмяПадеж = "Льву";
ИначеЕсли Имя="Павел" Тогда
ИмяПадеж = "Павлу";
ИначеЕсли Имя = "Пётр" Тогда
ИмяПадеж = "Петру";
ИначеЕсли Нрег(Прав(Имя,1)) = "й"
ИЛИ Нрег(Прав(Имя,1)) = "ь"
Тогда
ИмяПадеж = Лев(Имя,СтрДлина(Имя)-1) + "ю";
ИначеЕсли Нрег(Прав(Имя,1)) = "и" Тогда
ИмяПадеж = Имя;
ИначеЕсли Нрег(Прав(Имя,1)) = "а" Тогда
ИмяПадеж = Лев(Имя,СтрДлина(Имя)-1) + "е";
Иначе
ИмяПадеж = Имя + "у";
КонецЕсли;
ОтчествоПадеж = Отчество + "у";
ИначеЕсли ТекПол = Перечисления.Пол.Жен Тогда
КонецФамилии = Прав(Фамилия,1);

Если Нрег(КонецФамилии) = "а" Тогда
Если Нрег(Прав(Фамилия,3)) = "ова"
ИЛИ Нрег(Прав(Фамилия,3))="ева"
Тогда
ФамилияПадеж = Лев(Фамилия,СтрДлина(Фамилия)-1) + "ой";
Иначе
ФамилияПадеж = Лев(Фамилия,СтрДлина(Фамилия)-1) + "е";
КонецЕсли
ИначеЕсли Нрег(КонецФамилии) = "я" Тогда
Если Нрег(Прав(Фамилия,2)) = "ая" Тогда
ФамилияПадеж = Лев(Фамилия,СтрДлина(Фамилия)-2) + "ой";
Иначе
ФамилияПадеж = Лев(Фамилия,СтрДлина(Фамилия)-1) + "е";
КонецЕсли
Иначе
ФамилияПадеж = Фамилия;
КонецЕсли;

Если Нрег(Прав(Имя,1)) = "а" Тогда
ИмяПадеж = Лев(Имя,СтрДлина(Имя)-1) + "е";
ИначеЕсли Нрег(Прав(Имя,1)) = "я" Тогда
Если Нрег(Прав(Имя,2)) = "ия" Тогда
ИмяПадеж = Лев(Имя,СтрДлина(Имя)-1) + "и";
Иначе
ИмяПадеж = Лев(Имя,СтрДлина(Имя)-1) + "е";
КонецЕсли
Иначе
ИмяПадеж = Имя;
КонецЕсли;
ОтчествоПадеж = Лев(Отчество,СтрДлина(Отчество)-1) + "е";
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Предупреждение! Неправильно задан Пол. Проверьте!" + Символы.ПС + "(обДательныйПадежНаСервере)";
Сообщение.Сообщить();
КонецЕсли;

Если Длина = 1 Тогда
ФИО_Падеж = "" + ФамилияПадеж;
ИначеЕсли Длина = 2 Тогда
Если ТипВывода = 1 Тогда
ФИО_Падеж = "" + ИмяПадеж + " " + ФамилияПадеж;
ИначеЕсли ТипВывода = 2 Тогда
ФИО_Падеж = "" + ФамилияПадеж + " " + Лев(ИмяПадеж,1) + ".";
ИначеЕсли ТипВывода = 3 Тогда
ФИО_Падеж = "" + Лев(ИмяПадеж,1) + "." + " " + ФамилияПадеж;
Иначе
ФИО_Падеж = "" + ФамилияПадеж + " " + ИмяПадеж;
КонецЕсли
ИначеЕсли Длина = 3 Тогда
Если ТипВывода = 1 Тогда
ФИО_Падеж = "" + ИмяПадеж + " " + ОтчествоПадеж + " " + ФамилияПадеж;
ИначеЕсли ТипВывода = 2 Тогда
ФИО_Падеж = "" + ФамилияПадеж + " " + Лев(ИмяПадеж,1) + "." + " " + Лев(ОтчествоПадеж,1) + ".";
ИначеЕсли ТипВывода=3 Тогда
ФИО_Падеж = "" + Лев(ИмяПадеж,1) + "." + " " + Лев(ОтчествоПадеж,1) + "." + " " + ФамилияПадеж;
Иначе
ФИО_Падеж = "" + ФамилияПадеж + " " + ИмяПадеж + " " + ОтчествоПадеж;
КонецЕсли
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Предупреждение! Это не ФИО. Проверьте!" + Символы.ПС + "(обДательныйПадежНаСервере)";
Сообщение.Сообщить();
КонецЕсли;
Возврат ФИО_Падеж;
КонецФункции
# Ответить
72. Г Роман (Stradivari) 05.09.2013 16:04
Спасибо, огромное)
# Ответить
73. Роза Алексей (DoctorRoza) 17.10.2013 15:29
Спасибо, классная штука! :)
# Ответить
74. Fish249 (fish249) 26.11.2014 14:06
Больно уж громоздкий алгоритм. Склоняет всё без ошибок?
# Ответить
75. Конькова Ольга (Horsy) 16.12.2014 15:20
Огромное спасибо за обработку - это было просто спасением для меня!
# Ответить
76. Лунегов Петр (pvlunegov) 28.10.2015 10:43
не работает функция в данной статье - происходит зацикливание при попытке удалить множественные пробелы.
Автор тестировал собственное творение то?
# Ответить
77. Лунегов Петр (pvlunegov) 28.10.2015 10:46
Исправил в начале функции так:

// уберем множественные пробелы
Пока 1=1 Цикл
ФИО=СокрЛП(СтрЗаменить(ФИО," "," "));
Если Найти(ФИО," ")=0 Тогда Прервать КонецЕсли;
КонецЦикла;

После этого все стало работать. Спасибо!
# Ответить
78. Лунегов Петр (pvlunegov) 28.10.2015 10:48
При напечатке сообщения в инфостарт два пробела заменяются на один.
В итоге функция, скопированная из текста статьи, не работает!

Так что в предыдущем моем комментарии СтрЗаменить(ФИО," "," "). В первом " " следует видеть ДВА пробела!
Ответили: (79)
# Ответить
79. Коган Эстер (e.kogan) 28.10.2015 18:16
(78) pvlunegov, сами всё поняли :) потому отдельно и прикреплены были файлы.
# Ответить
80. Отр Александр (ИНТЕГРА) 28.10.2015 19:40
В начале сразу не понравилось:

Пока 1=1 Цикл
             ФИО=СокрЛП(СтрЗаменить(ФИО," "," "));
             Если Найти(ФИО," ")=0 Тогда Прервать КонецЕсли;
 КонецЦикла;


Заменить на:

Пока Найти(ФИО," ") Цикл
             ФИО=СокрЛП(СтрЗаменить(ФИО," "," "));
КонецЦикла;


А чем типовой вызов склонения из общего модуля не устраивает? :)
Ответили: (81)
# Ответить
81. Коган Эстер (e.kogan) 29.10.2015 02:04
(80) ИНТЕГРА, да, такой вариант даже был где-то реализован... Писалась эта штука тогда, когда никакого "типового" варианта ещё в помине не было, ну и почитайте комменты выше.
# Ответить
Внимание! За постинг в данном форуме $m не начисляются.
Внимание! Для написания сообщения необходимо авторизоваться
Текст сообщения*
Прикрепить файл