Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Склонение фамилий
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 8.2 > Программирование обычных форм 1С 8.2 и не интерфейсной логики
Егор Динин
Необходимо просклонять фамилии в печатной форме в родительном падеже (укр. мовою). Например "В особі ФедоровоЇ ІринИ ІгорівнИ ". Гугл предлагает компоненту или "крохотульку". Кто подскажет наиболее корректный вариант, может кто сталкивался?
vadim007
Есть у меня в архивах такая функция, правда для русских имен.
Vofka
vadim007, ну так может выложите? Или вы просто похвастаться хотели? smile.gif
mister-x
Цитата
Есть у меня в архивах такая функция, правда для русских имен.
можливо ви маєте на увазі зовнішню компоненту необходимо зарегистрироваться для просмотра ссылки.
kivals
mister-x, зачем для этого ВК? Я тоже в свое время переписал с русской обработки 1С склонение ФИО, но к сожалению код безвозвратно оставлен у заказчика sad.gif

Идея склонения в следующем:
Есть ограниченный набор окончаний, которые транслируются в заданный падеж известным способом (они естественно разные для рус и укр - Google в помощь).
Есть тонкость: одинаковые окончания для М и Ж фамилий могут траслироваться по-разному.
В моей обработке если пол не был известен из справочника - то он вычислялся из отчества.

И все же, Егор Динин, ИМХО обработка нужна чтобы сгенерировать предлагаемый к рассмотрению вариант перевода, но компетентный (читай - грмматически грамотный) пользователь должен эти варианты проработать и потом их нужно где-то хранить в базе (я бы порекомендовал независимый периодический регистр сведений).
mister-x
Цитата
mister-x, зачем для этого ВК?
це як варіант, але це не означає, що свою процедуру/функцію можна написати, можливо, навіть кращу
cvitova
v7: Родительный падеж в 1с
необходимо зарегистрироваться для просмотра ссылки
vadim007
Наконец-то нашел.


Функция для склонения фамилии, имени, отчества



В документах предприятия часто употребляются фамилия, имя, отчество в родительном и дательном падежах. Например: выдать (кому?), назначить (кого?) и т.д. В типовой конфигурации не предусмотрена функция склонения ФИО.
Предлагаемая функция позволяет выполнить склонение фамилий имен и отчеств в соответствии с правилами русского языка. Напомню, что мужские фамилии в русском языке склоняются всегда, кроме тех случаев, когда их вообще невозможно просклонять (фамилии типа Тёмных, Джугашвили, Беранже, Приходько и т.д.). В прочих случаях "экзотическая" мужская фамилия склоняется, а женская - нет. Например: господина Ганжу, но госпожу Ганжа; господина Веббера, но госпожу Веббер и т.д.
Функция имеет три входных параметра: фамилия_имя_отчество полностью (или фамилия + инициалы), пол (М или Ж) и падеж (Р-родительный или Д-дательный).
Выход функции: склонение в заданном падеже.

P.S. Функция была проверена на около 100 различных сочетаний (правильно склоняет даже такую "экзотику" как Кац Мойша Абрамович), но возможно на каких-то сочетаниях имеются "блохи". В таком случае надо добавить соответствующее условие.
P.S.S. В тексте специально не употреблялись сложные конструкции "Если - Иначе" для удобства добавления новых условий.

Функция Склонять(ФИО, Пол, Падеж) экспорт
    ///Упорядочивание алфавита

    Перем L[32];

    L[1]="Б";
    L[2]="В";
    L[3]="Г";
    L[4]="Д";
    L[5]="Ж";
    L[6]="З";
    L[7]="К";
    L[8]="Л";
    L[9]="М";
    L[10]="Н";
    L[11]="П";
    L[12]="Р";
    L[13]="С";
    L[14]="Т";
    L[15]="Ф";
    L[16]="Х";
    L[17]="Ц";
    L[18]="Ч";
    L[19]="Ш";
    L[20]="Щ";
    //Гласные
    L[21]="А";
    L[22]="Е";
    L[23]="И";
    L[24]="Й";
    L[25]="О";
    L[26]="У";
    L[27]="Ы";
    L[28]="Э";
    L[29]="Ю";
    L[30]="Я";
    L[31]="Ь";
    L[32]="Ъ";
/////////Выделение Фамилия, Имя, Отчество
    Пол=СокрЛП(Строка(Пол));
    Пол=Врег(Пол);
    Если (Пол<>"М") И (Пол<>"Ж") Тогда
       Предупреждение ("Неверно задан пол: М или Ж");
       Возврат " ";
    КонецЕсли;
    Падеж=СокрЛП(Строка(Падеж));
    Падеж=Врег(Падеж);
    Если (Падеж<>"Р") И (Падеж<>"Д") Тогда
       Предупреждение ("Неверно задан падеж: Р или Д");
       Возврат " ";
    КонецЕсли;
    ПолноеИмя=Строка(ФИО);
    ПолноеИмя=СокрЛП(ПолноеИмя);
    ПозицияПервогоПробела = Найти(ПолноеИмя, " ");
    Фамилия = Лев(ПолноеИмя, ПозицияПервогоПробела);
      Фамилия=СокрЛП(Фамилия);
    ИмяОтчество = Сред(ПолноеИмя, ПозицияПервогоПробела+1);
    ИмяОтчество = СокрЛП(ИмяОтчество);
      ПозицияТочки=Найти(ИмяОтчество,".");
      Если ПозицияТочки>0 Тогда //если введены инициалы
          Имя=Сред(ИмяОтчество,1,ПозицияТочки);
          Отчество=Сред(ИмяОтчество,ПозицияТочки+1);
          Отчество=СокрЛ(Отчество);
      Иначе;
          ПозицияВторогоПробела = Найти(ИмяОтчество, " ");
        Имя = Сред(ИмяОтчество,1, ПозицияВторогоПробела-1);
          Имя=СокрЛП(Имя);
        Отчество = Сред(ИмяОтчество, ПозицияВторогоПробела+1);
        Отчество = СокрЛП(Отчество);
       КонецЕсли;
    //////////Склонение фамилии

       Фам1=ВРЕГ(Фамилия);

    Последняя=Прав(Фам1,1);
      ДвеПоследних=Прав(Фам1,2);
    ТриПоследних=Прав(Фам1,3);

    Флаг=0;
    Для i=1 По 32 Цикл
        Если L[i]=Последняя Тогда
            Прервать;
        КонецЕсли;
    КонецЦикла;
    Если i<=20 Тогда
        ТипБуквы=1;//согласная
    ИНАЧЕ;
        ТипБуквы=2;//гласная
    КонецЕсли;
//////////////// Исключения ////////////////////
      Если СтрДлина(Фамилия)<=2 Тогда
        Родительный=Фамилия;//фамилии типа Ге, Че
        Дательный=Фамилия;
        Перейти ~выход;
    КонецЕсли;

    Если (ДвеПоследних="ИХ") ИЛИ  (ДвеПоследних="ЫХ") Тогда
        Родительный=Фамилия;//сибирские фамилии
        Дательный=Фамилия;
        Перейти ~выход;
    КонецЕсли;
    Если Последняя="О" Тогда
        Родительный=Фамилия;//украинские фамилии
        Дательный=Фамилия;
        Перейти ~выход;
    КонецЕсли;

    Если ДвеПоследних="УА" Тогда
        Родительный=Фамилия;//фамилии типа Стуруа
        Дательный=Фамилия;
        Перейти ~выход;
    КонецЕсли;

    Если ДвеПоследних="ИА" Тогда
        Родительный=Фамилия;//фамилии типа Туташхиа
        Дательный=Фамилия;
        Перейти ~выход;
    КонецЕсли;

    Если (ДвеПоследних="ЖА") И (Пол="Ж") Тогда
        Родительный=Фамилия;// женские фамилии типа Ганжа
        Дательный=Фамилия;
        Перейти ~выход;
    КонецЕсли;

    Если ТриПоследних="ДЗЕ" Тогда
        Родительный=Фамилия;//грузинские фамилии типа Гогадзе
        Дательный=Фамилия;
        Перейти ~выход;
    КонецЕсли;

    Если ТриПоследних="ИЛИ" Тогда
        Родительный=Фамилия;//грузинские фамилии типа Габошвили
        Дательный=Фамилия;
        Перейти ~выход;
    КонецЕсли;

    Если (ДвеПоследних="ОЙ") И (Пол="М") И (СтрДлина(Фамилия)=3) Тогда
        Родительный=Сред(Фамилия,1,СтрДлина(Фамилия)-1)+"я";//фам. типа Цой
        Дательный=Сред(Фамилия,1,СтрДлина(Фамилия)-1)+"ю";
        Перейти ~выход;
    КонецЕсли;

    Если (ДвеПоследних="ОЙ") И (Пол="Ж") И (СтрДлина(Фамилия)=3) Тогда
        Родительный=Фамилия; //фам. типа Цой
        Дательный=Фамилия;
        Перейти ~выход;
    КонецЕсли;
///////////////////////////////////////////////////////////////////////
    Если (Пол="М") И (ТипБуквы=1) Тогда //мужскую склоняем
        Родительный=Фамилия+"а";
        Дательный=Фамилия+"у";
        Флаг=1;
    КонецЕсли;

    Если (Пол="М") И (ДвеПоследних="ДЬ") Тогда //специально для губернатора
        Родительный=Сред(Фамилия,1,СтрДлина(Фамилия)-1)+"я";//Лебедя
        Дательный=Сред(Фамилия,1,СтрДлина(Фамилия)-1)+"ю";
        Флаг=1;
    КонецЕсли;

    Если (Пол="Ж") И (ТипБуквы=1) Тогда //женскую не склоняем
        Родительный=Фамилия;
        Дательный=Фамилия;
        Флаг=1;
    КонецЕсли;



    Если (Пол="Ж") И (Последняя="А") Тогда
        Родительный=Сред(Фамилия,1,СтрДлина(Фамилия)-1)+"у";
        Дательный=  Сред(Фамилия,1,СтрДлина(Фамилия)-1)+"ой";
        Флаг=1;
    КонецЕсли;

    Если (Пол="М") И (Последняя="А") Тогда //фам. типа Соткилава
        Родительный=Сред(Фамилия,1,СтрДлина(Фамилия)-1)+"у";
        Дательный=  Сред(Фамилия,1,СтрДлина(Фамилия)-1)+"е";
        Флаг=1;
    КонецЕсли;
    Если (ДвеПоследних="ОЙ") И (Пол="М") И (СтрДлина(Фамилия)>3) Тогда
        Родительный=Сред(Фамилия,1,СтрДлина(Фамилия)-1)+"го";
        Дательный=Сред(Фамилия,1,СтрДлина(Фамилия)-1)+"му";
        Флаг=1;
    КонецЕсли;

    Если (ДвеПоследних="АЯ") И (Пол="Ж") И (СтрДлина(Фамилия)>3) Тогда
        Родительный=Сред(Фамилия,1,СтрДлина(Фамилия)-2)+"ую";
        Дательный=Сред(Фамилия,1,СтрДлина(Фамилия)-2)+"ой";
        Флаг=1;
    КонецЕсли;
    Если Флаг=0 Тогда  //если не сработало ни одно условие
        Родительный=Фамилия;
        Дательный=Фамилия;
    КонецЕсли;

~выход: //////////////склонение имени////////
      Если ПозицияТочки>0 Тогда
        РодительныйИмя=Имя;
        ДательныйИмя=Имя;
        РодительныйОтчество=Отчество;
        ДательныйОтчество=Отчество;
        Перейти ~выход1;
      КонецЕсли;
      Имя1=ВРЕГ(Имя);
    Последняя=Прав(Имя1,1);
    ДвеПоследних=Прав(Имя1,2);
    ТриПоследних=Прав(Имя1,3);
    Флаг=0;

    Для i=1 По 32 Цикл
        Если L[i]=Последняя Тогда
            Прервать;
        КонецЕсли;
    КонецЦикла;
    Если i<=20 Тогда
        ТипБуквы=1;//согласная
    ИНАЧЕ;
        ТипБуквы=2;//гласная
    КонецЕсли;
    Если (Пол="М") И (ТипБуквы=1) Тогда ///Иван, Петр и т.д.
        РодительныйИмя=Имя+"а";
        ДательныйИмя  =Имя+"у";
        Флаг=1;
    КонецЕсли;
    Если (Пол="М") И (Последняя="Й") Тогда ///Сергей, Дмитрий и т.д.
        РодительныйИмя=Сред(Имя,1,СтрДлина(Имя)-1)+"я";
        ДательныйИмя  =Сред(Имя,1,СтрДлина(Имя)-1)+"ю";
        Флаг=1;
    КонецЕсли;
    Если (Пол="М") И (Последняя="А") Тогда ///Фома
        РодительныйИмя=Сред(Имя,1,СтрДлина(Имя)-1)+"у";
        ДательныйИмя  =Сред(Имя,1,СтрДлина(Имя)-1)+"е";
        Флаг=1;
    КонецЕсли;
    

      Если (Пол="М") И (Последняя="Я") Тогда ///Илья
       РодительныйИмя=Сред(Имя,1,СтрДлина(Имя)-1)+"ю";
         ДательныйИмя  =Сред(Имя,1,СтрДлина(Имя)-1)+"е";
       Флаг=1;
    КонецЕсли;
    Если (Пол="М") И (Последняя="Ь") Тогда ///Игорь
        РодительныйИмя=Сред(Имя,1,СтрДлина(Имя)-1)+"я";
          ДательныйИмя  =Сред(Имя,1,СтрДлина(Имя)-1)+"ю";
        Флаг=1;
    КонецЕсли;
    Если (Пол="Ж") И (Последняя="А") Тогда ///Татьяна, Людмила и т.д.
        РодительныйИмя=Сред(Имя,1,СтрДлина(Имя)-1)+"у";
          ДательныйИмя  =Сред(Имя,1,СтрДлина(Имя)-1)+"е";
    КонецЕсли;
    Если (Пол="Ж") И (Последняя="Я") Тогда ///Зоя, Наталья и т.д.
        РодительныйИмя=Сред(Имя,1,СтрДлина(Имя)-1)+"ю";
          ДательныйИмя  =Сред(Имя,1,СтрДлина(Имя)-1)+"е";
        Флаг=1;
    КонецЕсли;
    Если (Пол="Ж") И (ДвеПоследних="ИЯ") Тогда ///Наталия,Виктория и т.д.
        РодительныйИмя=Сред(Имя,1,СтрДлина(Имя)-1)+"ю";
          ДательныйИмя  =Сред(Имя,1,СтрДлина(Имя)-1)+"и";
        Флаг=1;
    КонецЕсли;
    Если Флаг=0 Тогда
        РодительныйИмя=Имя;
          ДательныйИмя  =Имя;
    КонецЕсли;

/////////склонение отчества///////
    Если (Пол="М") Тогда
      РодительныйОтчество=Отчество+"а";
        ДательныйОтчество  =Отчество+"у";
    КонецЕсли;
    Если (Пол="Ж") Тогда
      РодительныйОтчество=Сред(Отчество,1,СтрДлина(Отчество)-1)+"у";
        ДательныйОтчество  =Сред(Отчество,1,СтрДлина(Отчество)-1)+"е";
    КонецЕсли;
~выход1: /////////////////////
    Если Падеж="Д" Тогда
      ФИОВозврат=Дательный+" "+ДательныйИмя+" "+ДательныйОтчество;
    Иначе;
      ФИОВозврат=Родительный+" "+РодительныйИмя+" "+РодительныйОтчество;
    КонецЕсли;
    Возврат ФИОВозврат;
КонецФункции
kivals
vadim007, ага, похоже от этой функции я и плясал в свое время.
vadim007
Цитата(kivals @ 18.10.11, 13:07) необходимо зарегистрироваться для просмотра ссылки
Я тоже в свое время переписал с русской обработки 1С склонение ФИО, но к сожалению код безвозвратно оставлен у заказчика sad.gif

Это не есть хорошо. У меня все, что делалось на заказ, оседает в архивах. Иногда вместе с базами. Был даже случай - сервак у одних накрылся, так приезжали ко мне домой за базой трехмесячной давности.
morpher
Цитата(vadim007 @ 19.10.11, 20:34) необходимо зарегистрироваться для просмотра ссылки
P.S. Функция была проверена на около 100 различных сочетаний [...] но возможно на каких-то сочетаниях имеются "блохи".

Как собственноручно составивший более 20 тысяч подобных тестов, могу вам сказать, что блох там гораздо больше, чем вы думаете. Я уже 8 лет работаю над проблемой автоматического склонения и в частности создал внешнюю компоненту, выполняющую склонение фамилий на русском и украинском языках, а также должностей и других названий (пока только на русском). Если интересно, милости прошу: [правила, п.19]
Егор Динин
Ого сколько здесь ответов.smile.gif Дано не заглядывал. Всем спасибо!
Покопавшись в инете нашел варианты , но только для русского языка. да и на диске ИТС есть соответствующая dll-ка , котороя вполне корректно работает, с но опять же с русским языком. Для украинского же нашел только необходимо зарегистрироваться для просмотра ссылки , да и та платная и сломалась при первой попытке: фамилию "Крутой" просклоняла как "Крутоя"
Пришлось, не мудрствуя лукаво, дейтвовать топорным методом добавив соответствующие реквизиты в спр физ. лица и контактные лица контрагентов. Должности не склонял.
MATEVI
А кто то знает "NameDecl" (необходимо зарегистрироваться для просмотра ссылки) вообще для украинского языка в природе есть?
А то на "необходимо зарегистрироваться для просмотра ссылки" товарищ(8) ляпнул, про какую то украинскую версию, но что то мне так кажется она с украинскими буквами вообще не дружит.
Vofka
MATEVI, могу предположить, что товарищ так сказал, потому что правила склонения в украинском и русском языках похожи. Я бы проверил smile.gif
MATEVI
Проверил smile.gif Например. "і, ї, є" не понимает и выдает - AddInNative : Ошибка : "ФИО". Недопустимый символ 'ї'..

Потому как бы и стал искать информацию. Наткнулся на сообщение о якобы украинской версии данной компоненты.
Но судя по всему это фейк smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.