Este es el mi algoritmo definitivo para calcular el RUT de una persona, separado en distintos forms según se necesite (valida RUT, calcula DV y formatea RUT) e integrado en un solo programa validador.
REPORT valida_rut NO STANDARD PAGE HEADING.
PARAMETERS zzrut TYPE p0002-zzrut OBLIGATORY.
DATA return TYPE bapiret2.
START-OF-SELECTION.
PERFORM valida_rut CHANGING zzrut return.
MESSAGE return-message TYPE return-type.
*&---------------------------------------------------------------------*
*& Form VALIDA_RUT
*&---------------------------------------------------------------------*
FORM valida_rut CHANGING zzrut TYPE char12
e_return TYPE bapiret2.
DATA paso(12) TYPE c.
DATA largo TYPE i.
DATA ext TYPE i.
DATA valor1(10) TYPE c.
DATA valor2(10) TYPE c.
DATA dv TYPE c.
DATA dv2 TYPE c.
paso = zzrut.
TRANSLATE paso USING '. '.
TRANSLATE paso USING '- '.
CONDENSE paso NO-GAPS.
largo = STRLEN( paso ).
ext = largo - 1.
IF ext = 0.
e_return-type = 'E'.
e_return-message ='No se ha indicado DV'.
EXIT.
ENDIF.
valor1 = paso(ext).
dv = paso+ext(1).
* validar digito verificador
PERFORM calcula_dv USING valor1 CHANGING dv2.
IF dv <> dv2.
e_return-type = 'E'.
e_return-message = text-r02.
ELSE.
e_return-type = 'S'.
e_return-message = 'DV OK'.
PERFORM formatea_rut CHANGING zzrut.
ENDIF.
ENDFORM. " VALIDA_RUT
*&---------------------------------------------------------------------*
*& Form CALCULA_DV
*&---------------------------------------------------------------------*
FORM calcula_dv USING i_rut TYPE char10
CHANGING g_dv.
DATA g_rut TYPE char12.
DATA g_veces TYPE i.
DATA g_factor TYPE i.
DATA g_suma TYPE i.
DATA g_pos TYPE i.
TRANSLATE i_rut USING '. '.
TRANSLATE i_rut USING '- '.
CONDENSE i_rut NO-GAPS.
* Se verifica que esté compuesto sólo por números y una K
IF NOT i_rut CO '0123456789 '.
MESSAGE 'Debe ingresar un RUT valido' TYPE 'E'.
EXIT.
ENDIF.
g_rut = i_rut.
CONDENSE g_rut NO-GAPS.
g_veces = STRLEN( g_rut ).
IF g_veces <= 0.
MESSAGE 'RUT vacío' TYPE 'E'.
EXIT.
ENDIF.
g_factor = 2.
CLEAR g_suma.
g_pos = g_veces - 1.
DO g_veces TIMES.
g_suma = g_suma + g_rut+g_pos(1) * g_factor.
g_pos = g_pos - 1.
g_factor = g_factor + 1.
IF g_factor = 8.
g_factor = 2.
ENDIF.
ENDDO.
g_factor = g_suma MOD 11.
IF g_factor = 0.
g_dv = '0'.
ELSE.
g_factor = 11 - g_factor.
IF g_factor > 9.
g_dv = 'K'.
ELSE.
g_dv = g_factor.
ENDIF.
ENDIF.
ENDFORM. " CALCULA_DV
*&---------------------------------------------------------------------*
*& Form FORMATEA_RUT
*&---------------------------------------------------------------------*
FORM formatea_rut CHANGING i_rut TYPE char12.
DATA pos TYPE i.
DATA rut(12) TYPE c.
DATA salida(12) TYPE c.
DATA valor(8).
DATA dv.
DATA ext TYPE i.
TRANSLATE i_rut USING '. '.
TRANSLATE i_rut USING '- '.
CONDENSE i_rut NO-GAPS.
ext = STRLEN( i_rut ) - 1.
valor = i_rut(ext).
dv = i_rut+ext(1).
ext = ext - 1.
pos = 0.
DO.
IF pos < 3.
CONCATENATE valor+ext(1) rut INTO rut.
pos = pos + 1.
ext = ext - 1.
ELSE.
pos = 0.
CONCATENATE '.' rut INTO rut.
ENDIF.
IF ext < 0.
EXIT.
ENDIF.
ENDDO.
CONCATENATE rut '-' dv INTO rut.
i_rut = rut.
ENDFORM. " FORMATEA_RUT
PARAMETERS zzrut TYPE p0002-zzrut OBLIGATORY.
DATA return TYPE bapiret2.
START-OF-SELECTION.
PERFORM valida_rut CHANGING zzrut return.
MESSAGE return-message TYPE return-type.
*&---------------------------------------------------------------------*
*& Form VALIDA_RUT
*&---------------------------------------------------------------------*
FORM valida_rut CHANGING zzrut TYPE char12
e_return TYPE bapiret2.
DATA paso(12) TYPE c.
DATA largo TYPE i.
DATA ext TYPE i.
DATA valor1(10) TYPE c.
DATA valor2(10) TYPE c.
DATA dv TYPE c.
DATA dv2 TYPE c.
paso = zzrut.
TRANSLATE paso USING '. '.
TRANSLATE paso USING '- '.
CONDENSE paso NO-GAPS.
largo = STRLEN( paso ).
ext = largo - 1.
IF ext = 0.
e_return-type = 'E'.
e_return-message ='No se ha indicado DV'.
EXIT.
ENDIF.
valor1 = paso(ext).
dv = paso+ext(1).
* validar digito verificador
PERFORM calcula_dv USING valor1 CHANGING dv2.
IF dv <> dv2.
e_return-type = 'E'.
e_return-message = text-r02.
ELSE.
e_return-type = 'S'.
e_return-message = 'DV OK'.
PERFORM formatea_rut CHANGING zzrut.
ENDIF.
ENDFORM. " VALIDA_RUT
*&---------------------------------------------------------------------*
*& Form CALCULA_DV
*&---------------------------------------------------------------------*
FORM calcula_dv USING i_rut TYPE char10
CHANGING g_dv.
DATA g_rut TYPE char12.
DATA g_veces TYPE i.
DATA g_factor TYPE i.
DATA g_suma TYPE i.
DATA g_pos TYPE i.
TRANSLATE i_rut USING '. '.
TRANSLATE i_rut USING '- '.
CONDENSE i_rut NO-GAPS.
* Se verifica que esté compuesto sólo por números y una K
IF NOT i_rut CO '0123456789 '.
MESSAGE 'Debe ingresar un RUT valido' TYPE 'E'.
EXIT.
ENDIF.
g_rut = i_rut.
CONDENSE g_rut NO-GAPS.
g_veces = STRLEN( g_rut ).
IF g_veces <= 0.
MESSAGE 'RUT vacío' TYPE 'E'.
EXIT.
ENDIF.
g_factor = 2.
CLEAR g_suma.
g_pos = g_veces - 1.
DO g_veces TIMES.
g_suma = g_suma + g_rut+g_pos(1) * g_factor.
g_pos = g_pos - 1.
g_factor = g_factor + 1.
IF g_factor = 8.
g_factor = 2.
ENDIF.
ENDDO.
g_factor = g_suma MOD 11.
IF g_factor = 0.
g_dv = '0'.
ELSE.
g_factor = 11 - g_factor.
IF g_factor > 9.
g_dv = 'K'.
ELSE.
g_dv = g_factor.
ENDIF.
ENDIF.
ENDFORM. " CALCULA_DV
*&---------------------------------------------------------------------*
*& Form FORMATEA_RUT
*&---------------------------------------------------------------------*
FORM formatea_rut CHANGING i_rut TYPE char12.
DATA pos TYPE i.
DATA rut(12) TYPE c.
DATA salida(12) TYPE c.
DATA valor(8).
DATA dv.
DATA ext TYPE i.
TRANSLATE i_rut USING '. '.
TRANSLATE i_rut USING '- '.
CONDENSE i_rut NO-GAPS.
ext = STRLEN( i_rut ) - 1.
valor = i_rut(ext).
dv = i_rut+ext(1).
ext = ext - 1.
pos = 0.
DO.
IF pos < 3.
CONCATENATE valor+ext(1) rut INTO rut.
pos = pos + 1.
ext = ext - 1.
ELSE.
pos = 0.
CONCATENATE '.' rut INTO rut.
ENDIF.
IF ext < 0.
EXIT.
ENDIF.
ENDDO.
CONCATENATE rut '-' dv INTO rut.
i_rut = rut.
ENDFORM. " FORMATEA_RUT
No hay comentarios:
Publicar un comentario