в общем, так как
тот товарищ со мною так и не поделился, а на мою просьбу ему в ЛС я получила довольно грубый ответ - реализовывала сама.
склеивала в include из кода (если не ошибаюсь, т.к. дело было давно), найденного на
этой страничке. спасибо holocron!
сильно не ругайте, делалось в спешке, поэтому поправки и замечания также приветствуются
Code:
include zpadej_s.
FUNCTION ZHR_FIO_PADEJ.
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*" IMPORTING
*" REFERENCE(I_PERNR) TYPE PERNR-PERNR
*" REFERENCE(I_DAT) TYPE BEGDA DEFAULT SY-DATUM
*" REFERENCE(I_INDEX) TYPE INTEGER DEFAULT 5
*" REFERENCE(I_OBJECT) TYPE INTEGER DEFAULT 1
*" EXPORTING
*" REFERENCE(I_RESULT) TYPE STRING
*"----------------------------------------------------------------------
tables: p0002.
infotypes: 0002.
data: lv_fam type p0002-nachn,
lv_name type p0002-vorna,
lv_otch type p0002-midnm,
lv_gesch type p0002-gesch.
data: test type char1024,
result type char1024,
object type i,
gender,
fname type fieldname,
p1 type char128,
r1,
r2,
r3,
s1 like p0002-GESCH.
field-SYMBOLS <fs> type any.
* do 5 times.
* add 1 to sy-index.
*
* clear fname.
* fname+0(1) = 'P'.
* write sy-index to fname+1(1).
* ASSIGN (fname) to <fs>.
* check sy-subrc eq 0.
" получим ФИО
CALL FUNCTION 'HR_READ_INFOTYPE'
EXPORTING
pernr = I_PERNR
infty = '0002'
BEGDA = I_DAT
ENDDA = I_DAT
tables
infty_tab = p0002
EXCEPTIONS
INFTY_NOT_FOUND = 1
OTHERS = 2.
SELECT SINGLE
P1~NACHN P1~VORNA P1~MIDNM P1~GESCH
INTO (lv_fam, lv_name, lv_otch, lv_gesch)
FROM PA0002 AS P1
WHERE P1~PERNR = I_PERNR
AND P1~BEGDA <= I_DAT AND P1~ENDDA >= I_DAT.
* test = p0002-nachn. " иминит.падеж
r1 = 'X'.
if r1 ne space. " Что склоняем?!
object = 1. " Фамилия
test = lv_fam.
elseif r2 ne space.
object = 2. " Имя
test = lv_name.
else.
object = 3. " Отчество
test = lv_otch.
endif.
s1 = lv_gesch.
if s1 eq 1.
gender = 'ч'.
else.
gender = '2'.
endif.
PERFORM zpadej_s using test i_index gender object CHANGING result.
I_RESULT = result.
* <fs> = result.
* enddo.
ENDFUNCTION.
*&---------------------------------------------------------------------*
*& Include ZPADEJ_S
*&---------------------------------------------------------------------*
*DATA: I_FIO TYPE CHAR1024,
* I_GENDER TYPE P0002-GESCH,
* I_GBDAT TYPE P0002-GBDAT,
* I_INDEX TYPE INTEGER,
* I_OBJECT TYPE INTEGER,
* I_RESULT TYPE P0001-ENAME.
form zpadej_s using z1 type char1024
z2 type i
z3 type c
z4 type i
CHANGING xx type char1024.
*
* data: z1 like I_FIO,
* z2 like I_INDEX,
* z3 like I_GENDER,
* z4 like I_OBJECT,
* xx type char1024.
data: z5 type i,
z6 like z1,
z7(3),
z8(2),
z9(1),
za type i,
zb type i,
zc type i,
zd type i,
ze type i,
zf like z1,
t1 like z1,
t2(4),
t3 type i,
t4 like z1,
t5 type i,
t6,
t7 like z1,
t8 type i,
t9(2),
ta like z1,
tb type i,
dummy.
clear: z5, z6, z7, z8, z9, za, zb, zc, zd, ze, zf,
t1, t2 ,t3, t4, t5, t6, t7, t8, t9, ta, tb.
check strlen( z1 ) > 0.
* 1: z5=Найти(z1,"-");
find '-' in z1 match offset z5.
* 2: z6=?(z5=0,"","-"+ПадежС(Сред(z1,z5+1,СтрДлина(z1)-z5+1),z2,z3,z4));
if z5 = 0.
z6 = space.
else.
z5 = z5 + 1.
t1 = z1+z5.
perform zpadej_s using t1 z2 z3 z4
CHANGING z6.
z5 = z5 - 1.
endif.
* 3: z1=НРег(?(z5=0,z1,Лев(z1,z5-1)));
if z5 ne 0.
z1 = z1(z5).
endif.
TRANSLATE z1 to LOWER CASE.
* 4: z7=Прав(z1,3);z8=Прав(z7,2);z9=Прав(z8,1);
shift z1 RIGHT DELETING TRAILING space.
t2 = z1+1020(4).
z7 = z1+1021(3).
z8 = z1+1022(2).
z9 = z1+1023(1).
SHIFT z1 LEFT DELETING LEADING space.
* 5: z5=СтрДлина(z1);
z5 = strlen( z1 ).
* 6: za=Найти("ая ия ел ок яц ий па да ца ша ба та га ка",z8);
find z8 in 'ая ия ел ок яц ий па да ца ша ба та га ка' MATCH OFFSET za.
if sy-subrc eq 0. add 1 to za. endif.
* 7: zb=Найти("аеёийоуэюяжнгхкчшщ",Лев(z7,1));
find z7(1) in 'аеёийоуэюяжнгхкчшщ' MATCH OFFSET zb.
if sy-subrc eq 0. add 1 to zb. endif.
* 8: zc=Макс(z2,-z2);
zc = abs( z2 ).
* 9: zd=?(za=4,5,Найти("айяь",z9));
if za = 4.
zd = 5.
else.
find z9 in 'айяь' MATCH OFFSET zd.
if sy-subrc eq 0. add 1 to zd. endif.
endif.
* 10: zd=?((zc=1)или
* (z9=".")или
* ((z4=2)и(Найти("оиеу"+?(z3="ч"
* ,""
* ,"бвгджзклмнпрстфхцчшщъ"),z9)>0))или
* ((z4=1)и(Найти("мия мяэ лия кия жая лея",z7)>0))
* ,9
* ,?((zd=4)и(z3="ч")
* ,2
* ,?(z4=1
* ,?(Найти("оеиую",z9)+Найти("их ых аа еа ёа иа оа уа ыа эа юа яа",z8)>0
* ,9
* ,?(z3<>"ч"
* ,?(za=1
* ,7
* ,?(z9="а"
* ,?(za>18,1,6)
* ,9))
* ,?(((Найти("ой ый",z8)>0)и(z5>4)и(Прав(z1,4)<>"опой"))или((zb>10)и(za=16))
* ,8
* ,zd)))
* ,zd)));
if zc = 1 or
z9 = '.' or
( z4 = 2 and ( ( z3 = 'ч' and 'оиеу' cs z9 ) or
( z3 <> 'ч' and 'оиеубвгджзклмнпрстфхцчшщъ' cs z9 ) ) ) or
( z4 = 1 and 'мия мяэ лия кия жая лея' cs z7 ).
zd = 9.
else.
if zd = 4 and z3 = 'ч'.
zd = 2.
else.
if z4 = 1.
if 'оеиуюы' cs z9 or " фамилии на Ы вроде тоже не склоняются
'их ых аа еа ёа иа оа уа ыа эа юа яа' cs z8.
zd = 9.
else.
if z3 <> 'ч'.
if za = 1.
zd = 7.
else.
if z9 = 'а'.
if za > 18. zd = 1. else. zd = 6. endif.
else.
zd = 9.
endif.
endif.
else.
if ( 'ой ый' cs z8 and z5 > 4 and t2 ne 'опой' ) or
( zb > 10 and za = 16 ).
zd = 8.
endif.
endif.
endif.
endif.
endif.
endif.
* 11: ze=Найти("лец вей бей дец пец мец нец рец вец аец иец ыец бер",z7);
find z7 in 'лец вей бей дец пец мец нец рец вец аец иец ыец бер лий лия' MATCH OFFSET ze.
if sy-subrc eq 0. add 1 to ze. endif.
* 12: zf=?((zd=8)и(zc<>5)
* ,?((zb>15)или(Найти("жий ний",z7)>0)
* ,"е"
* ,"о")
* ,?(z1="лев"
* ,"ьв"
* ,?((Найти("аеёийоуэюя",Сред(z1,z5-3 ,1))=0)и((zb>11)или(zb=0))и(ze<>45)
* ,""
* ,?(za=7
* ,"л"
* ,?(za=10
* ,"к"
* ,?(za=13
* ,"йц"
* ,?(ze=0
* ,""
* ,?(ze<12
* ,"ь"+?(ze=1
* ,"ц"
* ,"")
* ,?(ze<37
* ,"ц"
* ,?(ze<49
* ,"йц"
* ,"р"))))))))));
if zd = 8 and zc <> 5.
if zb > 15 or 'жий ний' cs z7.
zf = 'е'.
else.
zf = 'о'.
endif.
else.
if z1 = 'лев'.
zf = 'ьв'.
else.
if z5 > 2.
t3 = z5 - 3.
if 'аеёийоуэюя' cs z1+t3(1) and ( zb > 11 or zb = 0 ) and ze <> 45.
zf = space.
else.
if za = 7.
zf = 'л'.
elseif za = 10.
zf = 'к'.
elseif za = 13.
zf = 'йц'.
else.
if ze = 0.
zf = space.
else.
if ze < 12.
if ze = 1.
zf = 'ьц'.
else.
zf = 'ь'.
endif.
else.
if ze < 37.
zf = 'ц'.
elseif ze < 49.
zf = 'йц'.
elseif ze < 53.
zf = 'р'.
endif.
endif.
endif.
endif.
endif.
endif.
endif.
endif.
* 13: zf=?((zd=9)или((z4=3)и(Прав(z1,1)="ы"))
" ,z1
" ,Лев(z1,z5-?((zd>6)или(zf<>"")
" ,2
" ,?(zd>0,1,0)))
" +zf
" +СокрП(
" Сред("а у а "
" +Сред("оыые",Найти("внч",z9)+1,1)
" +"ме "
" +?(Найти("гжкхш",Лев(z8,1))>0
" ,"и"
" ,"ы")
" +" е у ойе я ю я ем"
" +?(za=16
" ,"и"
" ,"е")
" +" и е ю ейе и и ь ьюи и и ю ейи ойойу ойойойойуюойойгомуго"
" +?((zf="е")или(za=16)или((zb>12)и(zb<16))
" ,"и"
" ,"ы")
" +"мм",10*zd+2*zc-3,2)));
if zd = 9 or
( z4 = 3 and z9 = 'ы' ).
ta = z1.
else.
if zd > 6 or
zf ne space .
tb = 2.
elseif zd > 0.
tb = 1.
else.
tb = 0.
endif.
tb = z5 - tb.
ta = z1(tb).
endif.
t4 = 'а у а'.
* слабая часть алгоритма {
find z9 in 'внч' MATCH OFFSET t5.
if sy-subrc eq 0. add 1 to t5. endif.
if 'ауюя' cs z8(1). t5 = 0. endif. " Колдун, Яцун, Цикун, Мкртчян
* }
t7 = 'оыые'. t6 = t7+t5(1).
CONCATENATE t4 t6 into t4 separated by space.
CONCATENATE t4 'ме' into t4.
if 'гжкхш' cs z8+0(1).
CONCATENATE t4 'и' into t4 SEPARATED BY space.
else.
CONCATENATE t4 'ы' into t4 SEPARATED BY space.
endif.
CONCATENATE t4 'е у ойе я ю я ем' into t4 SEPARATED BY space.
if za = 16.
CONCATENATE t4 'и' into t4.
else.
CONCATENATE t4 'е' into t4.
endif.
CONCATENATE t4 'и е ю ейе и и ь ьюи и и ю ейи ойойу ойойойойуюойойгомуго'
into t4 SEPARATED BY space.
if zf = 'е' or za = 16 or ( zb > 12 and zb < 16 ).
CONCATENATE t4 'и' into t4.
else.
CONCATENATE t4 'ы' into t4.
endif.
CONCATENATE t4 'мм' into t4.
t8 = 10 * zd + 2 * zc - 4.
t9 = t4+t8(2).
CONCATENATE ta zf t9 into zf.
* 14: Возврат ?(""=z1
* ,""
* ,?(z4>0
* ,ВРег(Лев(zf,1))+?((z2<0)и(z4>1)
* ,"."
* ,Сред(zf,2))
* ,zf)
* +z6);
clear xx.
if z1 = space.
xx = space.
else.
if z4 > 0.
xx = zf+0(1).
if z2 < 0 and z4 > 1.
CONCATENATE xx '.' into xx.
else.
CONCATENATE xx zf+1 into xx.
endif.
TRANSLATE xx+0(1) TO UPPER CASE.
else.
xx = zf.
endif.
endif.
if z6 ne space.
CONCATENATE xx z6 into xx SEPARATED BY '-'.
endif.
endform.
I_PERNR - табельный номер
I_DAT - на какую дату формируем
I_INDEX - в каком падеже склонять (1 - именит., 2 - родит., 3 - дат., и т.д.)
I_OBJECT - что склоняем (1 - фамилия, 2 - имя, 3 - отчество)
I_RESULT - отформатированное имя сотрудника или кандидата на должность
Если у кого есть более изящное исполнение - делитесь!