INFOSTART EVENT 2018 EDUCATION

Второй тур голосования за доклады.
Окончание 5 сентября.

Чичикин Арсен | Управляющий, собственник | 1С-Софт Райз

«Управление проектом в условиях неопределенности»

1. Требования Заказчика в тендерной документации и реальные требования к автоматизации диаметрально противовположны 2. Заказчик не готов к проекту автоматизации, а контракт уже подписан... 3. Заказчик "сам знает, как настроить автоматизированную систему"

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

Программирование - Универсальные функции

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

В файле - процедуры для 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);

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

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

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

 

197

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

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

См. также

Комментарии
Сортировка: Древо
0. e.kogan 1837 01.10.08 17:32 Сейчас в теме
Склонение ФИО в виде небольшой процедуры. Писалось студентом-программистом и студентом-лингвистом.

Перейти к публикации

1. Ёпрст 1027 01.10.08 17:32 Сейчас в теме
2. Ёпрст 1027 01.10.08 17:33 Сейчас в теме
Гораздо лаконичнее код..и написан задолго до 2003 года...
3. e.kogan 1837 01.10.08 17:56 Сейчас в теме
Лаконичнее. И сумбурнее.

Кому что нравится.
4. Ёпрст 1027 01.10.08 18:00 Сейчас в теме
Не вижу там никакого сумбура. Код гораздо приятнее. Даже у Рупора проще.
+ должности отрабатывает
+ специфические фамилии
+ каменты
+ примеры использования
5. Abadonna 3718 01.10.08 18:04 Сейчас в теме
(1,2) Слабенький ответик-то получился ;)
Сообщить(ПадежС("Кучер",3,1,1) ); // дательный, мужик, склонять фамилию
Возвращет: Кучер
А вот фигушки! КучерУ, ЛебедЮ, Кушниру, КоганУ если речь идет о мужике. А вот для женщины подобные не склоняются.
А вот у автора вернула в дательном:
Кучеру Аркадию Арнольдовичу - я
Кучер Антонине Алексеевне - моя мама
т.е. абсолютно правильно
6. e.kogan 1837 01.10.08 18:11 Сейчас в теме
(5) Спасибо, хотела сама потестировать предложенное, теперь тратить время не буду.
7. Abadonna 3718 01.10.08 18:22 Сейчас в теме
(6) Да просто уже забодали любители "простых" решений ;)
А уж если меряться, у кого раньше, то вот: http://1c.proclub.ru/modules/mydownloads/personal.php?cid=111&lid=254
Написана КучерОМ Аркадием Арнольдовием в 2000 году. Чуток коряво, ибо это было первое, что я написал на 1С ваще. Однако КацА МойшУ АбрамовичА склоняла вполне корректно ;)))
vladir; НеБиллГейтс; tikhon; Шёпот теней; +4 Ответить
8. e.kogan 1837 01.10.08 19:23 Сейчас в теме
(7) Ну, если уж говорить про Мойш, то правильно - МойшЕ. Или уж Моисей. Уменьшительно-ласкательные склонять задачи не ставилось, всё-таки официальные документы, ага )
9. Abadonna 3718 02.10.08 02:55 Сейчас в теме
(7) Здрасте! Склоняла КОГО? Мойше??? Я не про дательный, а про винительный в данном случае говорил. Что касается какие еврейские уменьшительные, а какие полные - то тут, сорри, я не спец :)))
17. e.kogan 1837 02.10.08 10:26 Сейчас в теме
(9) МойшА - это некорректно. Это уменьшительное, да к тому же и, скажем так, русифицированное.
(13) Доступ открыт. Промахнулась с переключателем.
18. Ёпрст 1027 02.10.08 10:30 Сейчас в теме
(17) И всё же потести предложенное, оно рабочее.
23. e.kogan 1837 03.10.08 11:26 Сейчас в теме
(18) Потестила. Хорошооо... Спасибо.
14. Ёпрст 1027 02.10.08 09:04 Сейчас в теме
(5) Не вопрос. Там есть второй вариант, от Рупора.. там правильнее. :)
15. Ёпрст 1027 02.10.08 09:13 Сейчас в теме
(5) И Самое Главное, ВАША неправда:

Сообщить(Падеж("Кучер" ,3,1,"1" )) = "Кучеру"
20. Abadonna 3718 02.10.08 10:34 Сейчас в теме
(15) И самое главное, что я тестил Сообщить(ПадежС("Кучер",3,1,1) );
Падеж и еще буковка "С", а не просто Падеж. Когда мне их там сортировать было ;)
21. Ёпрст 1027 02.10.08 10:37 Сейчас в теме
(20) Там же примеры есть в каментах! :)
10. halushka 02.10.08 04:39 Сейчас в теме
Хотел посмотреть, ан рейтингом не вышел. :( Жаль.
1108; sashocq; gutentag; coder1cv8; lomok; O-Planet; Abadonna; +7 Ответить
11. Abadonna 3718 02.10.08 05:05 Сейчас в теме
(10) Ну держи один плюсик ;) Щас гляну еще где твои комменты
12. O-Planet 6895 02.10.08 05:10 Сейчас в теме
(10) "Рейтингом не вышел" - это зачОООт! ))))))
13. lomok 02.10.08 08:49 Сейчас в теме
Доступ C рейтингом не меньше 3 - FAIL.
16. Ёпрст 1027 02.10.08 09:14 Сейчас в теме
Так что, решение правильное, хотя и простое, и не писано "на основании серьёзного лингвистического исследования"
:)
19. Abadonna 3718 02.10.08 10:33 Сейчас в теме
Честно признаюсь, что всегда думал что "Мойша" нормальное еврейское имя :))) Без уменьшительного, русифицированного и т.д.
22. Abadonna 3718 02.10.08 10:49 Сейчас в теме
2Ёпрст. Ты завязывай фладить, а давай начинай писать про Dialog Stream и Moxel :))))
24. e.kogan 1837 03.10.08 15:27 Сейчас в теме
О!

Меч в творительном - мечЕм, ага ) Нашли-таки мы не ловящееся )
25. Ёпрст 1027 03.10.08 16:23 Сейчас в теме
(24) А вот и фигушки :)

Падеж("Меч",5,1,"1") = "Мечем"

26. e.kogan 1837 03.10.08 16:26 Сейчас в теме
27. Ёпрст 1027 03.10.08 16:28 Сейчас в теме
(26) Угу, тепереча тестим ваше творение - МечЕм ...
28. Ёпрст 1027 03.10.08 16:29 Сейчас в теме
29. e.kogan 1837 03.10.08 16:31 Сейчас в теме
(28) Дык я и не спорю ;) Но предлагали потестить - я и потестила )
30. Ёпрст 1027 03.10.08 16:35 Сейчас в теме
Хотя...

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

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

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


Компонента есть на диске ИТС, расчитана под восьмёрку, но и в 7.7 нормально работает
45. Crush 08.10.08 12:00 Сейчас в теме
(44) Пропустил точку с запятой, простите :)
У метода "просклонять" есть еще и 30-ий параметр - пол
49. hame1e00n 493 13.07.09 22:53 Сейчас в теме
Процедура очень интересная, только скачать не могу - рейтинга маловато... плюсик поставил)
50. Diktis 12.08.09 02:09 Сейчас в теме
Для имени "Ольга" в родительном падеже получаем "Ольгы"
52. e.kogan 1837 12.08.09 10:19 Сейчас в теме
(50) Приведите ФИО полностью. На "Иванова Ольга Юрьевна" склоняет нормально.
(51) Дело не в том, что нравится или не нравится. Эта процедура была написана совершенно отдельно.
53. Diktis 13.08.09 01:08 Сейчас в теме
(52) ПадежФИО("Иванова Ольга Юрьевна", 2) = "Ивановой Ольгы Юрьевны"
Может я чего-то не понимаю, но откуда взяться другому результату?
"...
ИначеЕсли Пол="Ж" Тогда
строток=ток.Добавить(); // ирина
строток.старок="*а";
строток.р="ы";
..."
55. e.kogan 1837 17.08.09 11:48 Сейчас в теме
(53) Проверяла специально - получается "Ивановой Ольги Юрьевны". Чесслово. Если вводить без отчества - возможно.

Поправила, теперь Ольга, Инга и т.д. склоняются нормально.
51. CheBurator 3552 12.08.09 02:15 Сейчас в теме
а чем Падеж "Крохотулька" с проклаба не нравится?
54. Yashazz 2265 17.08.09 02:03 Сейчас в теме
(51) Этой процедуре уж лет 8, не меньше...
Насчёт ОльгЫ посмотрим.
56. nelli_dream 17.08.09 12:28 Сейчас в теме
спасибо автору. мне очень помогла обработочка!
осталось решить вопрос со склонением профессий и цехов! ::)
57. e.kogan 1837 17.08.09 12:29 Сейчас в теме
(56) Пользуйтесь процедурами Jurer'а. Они это вроде бы умеют.
58. ARL 275 13.08.10 11:08 Сейчас в теме
Авторам спасибо! Все реальные случаи функция отработала прекрасно. Добавил только точки к инициалам.
59. Andrew_flyer 81 27.08.10 12:34 Сейчас в теме
60. Поручик 4113 01.09.11 11:50 Сейчас в теме
61. ELInfinito 23.09.11 07:12 Сейчас в теме
62. e.kogan 1837 23.09.11 16:32 Сейчас в теме
63. kiros 51 28.09.11 12:04 Сейчас в теме
Спасибо, небольшой тюнинг, если фамилия и.о. определение Ж рода по "а" и "я" в фамилии. Доработал и в работу.
Еще раз спасибо!
p.s. А косячки они у всех есть, как можно жить без косячков ;)
64. eli1984 04.10.11 06:56 Сейчас в теме
Сейчас вроде нормально все работает. Спасибо за обработку. пользуюсь.
65. avavadim 17.10.11 02:41 Сейчас в теме
Спасибо за текст обработки, все нормально работает...
66. Joker 03.01.12 10:55 Сейчас в теме
Спасибо, вставил в конфу, все работает
67. fixin 3726 04.04.12 18:07 Сейчас в теме
(0) А теперь проверьте ее моей тестилкой: http://infostart.ru/public/115909/, поищите ошибки.
А вообще нужно конечно писать склонение на технологии регистров правил, пусть и виртуальных, а не хранящихся в базе. Это будет прорыв. Но за попытку плюсую.
ИНТЕГРА; +1 Ответить
69. IRLes 185 21.12.12 10:28 Сейчас в теме
Прокопчук Сергей Сергеевич - в родительном падеже получается Прокопчка Сергея Сергеевича
по идее должно быть Прокопчука Сергея Сергеевича!
70. IRLes 185 21.12.12 11:06 Сейчас в теме
71. fr.myha 10.07.13 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 140 05.09.13 16:04 Сейчас в теме
73. DoctorRoza 17.10.13 15:29 Сейчас в теме
Спасибо, классная штука! :)
74. fish249 26.11.14 14:06 Сейчас в теме
Больно уж громоздкий алгоритм. Склоняет всё без ошибок?
75. Horsy 16.12.14 15:20 Сейчас в теме
Огромное спасибо за обработку - это было просто спасением для меня!
76. pvlunegov 125 28.10.15 10:43 Сейчас в теме
не работает функция в данной статье - происходит зацикливание при попытке удалить множественные пробелы.
Автор тестировал собственное творение то?
77. pvlunegov 125 28.10.15 10:46 Сейчас в теме
Исправил в начале функции так:

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

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

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

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


Заменить на:

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


А чем типовой вызов склонения из общего модуля не устраивает? :)
81. e.kogan 1837 29.10.15 02:04 Сейчас в теме
(80) ИНТЕГРА, да, такой вариант даже был где-то реализован... Писалась эта штука тогда, когда никакого "типового" варианта ещё в помине не было, ну и почитайте комменты выше.
82. Артано 607 13.07.17 10:29 Сейчас в теме
Функция не умеет склонять существительные с суффиксом ец. Совсем не умеет, ни после закрытого слога, ни после открытого, впрочем как и типовая компонента (похоже что типовая компонента использует тот же алгоритм). Студентам надо было лучше учиться, а то недоучились, а всё туда же - в 1С кодить =)
83. e.kogan 1837 20.07.17 10:39 Сейчас в теме
(82) Плюс по сравнению с компонентой - довольно просто допилить :)
84. Артано 607 20.07.17 10:47 Сейчас в теме
Если когда-нибудь дойдут руки до такого, то не стал бы допиливать, а переписал на иных принципах. А сейчас проще компоненту доработать. Уже реализован механизм переопределения результатов компоненты склонения. Всех физлиц до которых смог дотянуться уже проверил - склоняет верно.
Оставьте свое сообщение