Мы пользуемся вот этой функцией (кто-то откуда-то принес). Мы прикинули, что в основном будут склоняться имена-фамилии и должности (например, в приказах). Для должностей грубо добавили таблицу в расчете на то, что склоняемых должностей будет не очень много (пока прогноз оправдывается). Для таблицы сделали диалог ведения и открыли ее в продуктиве, чтобы ответственный специалист по мере необходимости добавлял туда записи. Функция работает в системе 4.7 без Unicode, на Unicode не проверялась.
Code:
FUNCTION zhr_padej.
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*" IMPORTING
*" REFERENCE(GENDER) LIKE P0002-GESCH
*" VALUE(NACHN_IN) LIKE P0002-NACHN OPTIONAL
*" VALUE(VORNA_IN) LIKE P0002-VORNA OPTIONAL
*" VALUE(MIDNM_IN) LIKE P0002-MIDNM OPTIONAL
*" VALUE(OTHER_IN) OPTIONAL
*" VALUE(PADEJ) TYPE C
*" EXPORTING
*" VALUE(NACHN_OUT) LIKE P0002-NACHN
*" VALUE(VORNA_OUT) LIKE P0002-VORNA
*" VALUE(MIDNM_OUT) LIKE P0002-MIDNM
*" VALUE(OTHER_OUT)
*" EXCEPTIONS
*" NOT_FOUND
*"----------------------------------------------------------------------
DATA: word_case TYPE ztru_word_case,
l_length TYPE i,
l_length2 TYPE i,
l_ok TYPE i.
* data:
nachn_out = nachn_in.
vorna_out = vorna_in.
midnm_out = midnm_in.
other_out = other_in.
IF NOT other_out IS INITIAL
AND padej CA 'РВД'.
SELECT SINGLE * FROM ztru_word_case
INTO word_case
WHERE word = other_out.
IF sy-subrc = 0.
CASE padej.
WHEN 'Р'. other_out = word_case-genitive.
WHEN 'В'. other_out = word_case-accusative.
WHEN 'Д'. other_out = word_case-dative.
ENDCASE.
ELSE.
MESSAGE s083(zhr_pa)
WITH padej other_out 'ZTRU_WORD_CASE'
RAISING not_found.
ENDIF.
ENDIF.
CASE gender.
WHEN 2.
*фамилия
IF NOT nachn_out IS INITIAL.
l_length = STRLEN( nachn_out ) - 1.
l_length2 = STRLEN( nachn_out ) - 2.
DO 1 TIMES.
CHECK nachn_out+l_length2(2) NE 'их'
AND nachn_out+l_length2(2) NE 'ИХ'
AND nachn_out+l_length(1) NE 'о'
AND nachn_out+l_length(1) NE 'О'.
CASE padej.
WHEN 'Д'.
CASE nachn_out+l_length(1).
WHEN 'а'. nachn_out+l_length(2) = 'ой'.
WHEN 'А'. nachn_out+l_length(2) = 'ОЙ'.
ENDCASE.
WHEN 'Р'.
CASE nachn_out+l_length(1).
WHEN 'а'. nachn_out+l_length(2) = 'ой'.
WHEN 'А'. nachn_out+l_length(2) = 'ОЙ'.
ENDCASE.
ENDCASE.
ENDDO.
ENDIF.
*Имя
IF NOT vorna_out IS INITIAL.
l_length = STRLEN( vorna_out ) - 1.
CASE padej.
WHEN 'Д'.
CASE vorna_out+l_length(1).
WHEN 'а'. vorna_out+l_length(1) = 'е'.
WHEN 'я'. vorna_out+l_length(1) = 'и'.
WHEN 'А'. vorna_out+l_length(1) = 'Е'.
WHEN 'Я'. vorna_out+l_length(1) = 'И'.
ENDCASE.
WHEN 'Р'.
CASE vorna_out+l_length(1).
WHEN 'а'. vorna_out+l_length(1) = 'ы'.
WHEN 'А'. vorna_out+l_length(1) = 'Ы'.
WHEN 'я'. vorna_out+l_length(1) = 'и'.
WHEN 'Я'. vorna_out+l_length(1) = 'И'.
ENDCASE.
ENDCASE.
ENDIF.
*отчество
IF NOT midnm_out IS INITIAL.
l_length = STRLEN( midnm_out ) - 1.
CASE padej.
WHEN 'Д'.
CASE midnm_out+l_length(1).
WHEN 'а'. midnm_out+l_length(1) = 'е'.
WHEN 'А'. midnm_out+l_length(1) = 'Е'.
ENDCASE.
WHEN 'Р'.
CASE midnm_out+l_length(1).
WHEN 'а'. midnm_out+l_length(1) = 'ы'.
WHEN 'А'. midnm_out+l_length(1) = 'Ы'.
ENDCASE.
ENDCASE.
ENDIF.
WHEN 1.
*фамилия
IF NOT nachn_out IS INITIAL.
l_length = STRLEN( nachn_out ) - 1.
l_length2 = STRLEN( nachn_out ) - 2.
DO 1 TIMES.
CHECK nachn_out+l_length2(2) NE 'их'
AND nachn_out+l_length2(2) NE 'ИХ'
AND nachn_out+l_length(1) NE 'о'
AND nachn_out+l_length(1) NE 'О'.
CASE padej.
WHEN 'Д'.
CASE nachn_out+l_length2(2).
WHEN 'ий'. nachn_out+l_length2(3) = 'ому'. EXIT.
WHEN 'ИЙ'. nachn_out+l_length2(3) = 'ОМУ'. EXIT.
ENDCASE.
CASE nachn_out+l_length(1).
WHEN 'ь'. nachn_out+l_length(1) = 'ю'. EXIT.
WHEN 'Ь'. nachn_out+l_length(1) = 'Ю'. EXIT.
ENDCASE.
l_length = l_length + 1.
nachn_out+l_length(1) = 'у'.
WHEN 'Р'.
CASE nachn_out+l_length2(2).
WHEN 'ий'. nachn_out+l_length2(3) = 'ого'. EXIT.
WHEN 'ИЙ'. nachn_out+l_length2(3) = 'ОГО'. EXIT.
ENDCASE.
CASE nachn_out+l_length(1).
WHEN 'ь'. nachn_out+l_length(1) = 'я'. EXIT.
WHEN 'Ь'. nachn_out+l_length(1) = 'Я'. EXIT.
ENDCASE.
l_length = l_length + 1.
nachn_out+l_length(1) = 'а'.
ENDCASE.
ENDDO.
ENDIF.
*Имя
IF NOT vorna_out IS INITIAL.
l_length = STRLEN( vorna_out ) - 1.
CASE padej.
WHEN 'Д'.
CASE vorna_out+l_length(1).
WHEN 'й'. vorna_out+l_length(1) = 'ю'. l_ok = 1.
WHEN 'Й'. vorna_out+l_length(1) = 'Ю'. l_ok = 1.
WHEN 'ь'. vorna_out+l_length(1) = 'ю'. l_ok = 1.
WHEN 'Ь'. vorna_out+l_length(1) = 'Ю'. l_ok = 1.
ENDCASE.
IF l_ok NE 1.
l_length = l_length + 1.
vorna_out+l_length(1) = 'у'.
ENDIF.
WHEN 'Р'.
CASE vorna_out+l_length(1).
WHEN 'й'. vorna_out+l_length(1) = 'я'. l_ok = 1.
WHEN 'Й'. vorna_out+l_length(1) = 'Я'. l_ok = 1.
WHEN 'ь'. vorna_out+l_length(1) = 'я'. l_ok = 1.
WHEN 'Ь'. vorna_out+l_length(1) = 'Я'. l_ok = 1.
ENDCASE.
IF l_ok NE 1.
l_length = l_length + 1.
vorna_out+l_length(1) = 'а'.
ENDIF.
ENDCASE.
ENDIF.
*отчество
IF NOT midnm_out IS INITIAL.
l_length = STRLEN( midnm_out ) - 1.
CASE padej.
WHEN 'Д'.
CASE midnm_out+l_length(1).
WHEN 'ч'. midnm_out+l_length(2) = 'чу'.
WHEN 'Ч'. midnm_out+l_length(2) = 'ЧУ'.
ENDCASE.
WHEN 'Р'.
CASE midnm_out+l_length(1).
WHEN 'ч'. midnm_out+l_length(2) = 'ча'.
WHEN 'Ч'. midnm_out+l_length(2) = 'ЧА'.
ENDCASE.
ENDCASE.
ENDIF.
ENDCASE.
ENDFUNCTION.
Таблица ZTRU_WORD_CASE:
Code:
WORD CHAR 100 0 Слово в именительном падеже
GENITIVE CHAR 100 0 Слово в родительном падеже
ACCUSATIVE CHAR 100 0 Слово в винительном падеже
DATIVE CHAR 100 0 Слово в дательном падеже