1 de abril de 2007

Validando un número de RUC con Delphi 2006

Autor: José Castillo Reyes, También puedes leerlo en CodeGear Developer Network.

Introducción

Para propósitos de fiscalización, en el Perú, las empresas públicas y privadas son identificadas mediante un Número de Registro de Contribuyente-RUC. Por ésta razón es de mucho valor que las aplicaciones contables o financieras sean más seguras y confiables al registrar dichos números. En este contexto, he escrito un programa que obtiene el dígito verificador, que dependiendo del resultado devuelto se podrá determinar si el RUC es verdadero o falso.

Desarrollando la aplicación

El número de RUC consta de 11 dígitos, siendo el último dígito, el dígito verificador. Según la fórmula a usar se deben asignar a los 10 primeros dígitos del número de RUC unos valores constantes a los que llamaremos: Pesos.
Número:ABCDEFGHIJ
Pesos:5432765432

En el ejemplo usaremos el siguiente número de RUC: 10200517976, luego, como ya se mencionó anteriormente, asignaremos los valores constantes a los 10 primeros dígitos:

Número:1020051797
Pesos:5432765432

En Delphi, creamos un nuevo proyecto VCL Forms para win32. En el formulario por defecto agregamos: 2 TEdit(EdtRUC y EdtDVerificador), 3 TLabels(Label1, Label2 y Label3) y 1 TButton(btnValidar). Declaramos las variables: Valores, Pesos, ProductoValorXPeso, SumadeProductos, Cociente, ParteEntera, ResultadoOperacion, Diferencia y DigitoVerificador. Además, se deben de crear los siguientes métodos: AsignarDigitosArrayValores y SumarProductos.

varForm1: TForm1;
Valores: Array[0..9] of String;
Pesos: Array[0..9] of Integer;
ProductoValorXPeso: Array[0..9] of Integer;
SumadeProductos: Integer;
Cociente: Real;
ParteEntera: Integer;
ResultadoOperacion: Integer;
Diferencia: Integer;
DigitoVerificador: Integer;


En el evento Click del botón btnValidar escribiremos el código necesario para poner trabajar a nuestro programa.
procedure TForm1.btnValidarClick(Sender: TObject);
begin

//Asignar valores constantes al array de Pesos
Pesos[0] := 5; Pesos[1] := 4; Pesos[2] := 3; Pesos[3] := 2;
Pesos[4] := 7; Pesos[5] := 6; Pesos[6] := 5; Pesos[7] := 4;
Pesos[8] := 3; Pesos[9] := 2;

//Asignar los 10 primeros dígitos del RUC al array de Valores
AsignarDigitosArrayValores(edtRUC.Text);

Se requieren 6 pasos para obtener el dígito verificador.
1. Multiplicar cada valor con su peso correspondiente:
50600305282714

//Paso1: Multiplicar cada valor por su peso
ProductoValorXPeso[0] := StrToInt(Valores[0])*Pesos[0];
ProductoValorXPeso[1] := StrToInt(Valores[1])*Pesos[1];
ProductoValorXPeso[2] := StrToInt(Valores[2])*Pesos[2];
ProductoValorXPeso[3] := StrToInt(Valores[3])*Pesos[3];
ProductoValorXPeso[4] := StrToInt(Valores[4])*Pesos[4];
ProductoValorXPeso[5] := StrToInt(Valores[5])*Pesos[5];
ProductoValorXPeso[6] := StrToInt(Valores[6])*Pesos[6];
ProductoValorXPeso[7] := StrToInt(Valores[7])*Pesos[7];
ProductoValorXPeso[8] := StrToInt(Valores[8])*Pesos[8];
ProductoValorXPeso[9] := StrToInt(Valores[9])*Pesos[9]

2. Sumar los productos obtenidos. (A)
115 = 5 + 0 + 6 + 0 + 0 + 30 + 5 + 28 + 27 + 14
//Paso2: Sumar los NumerosSumadeProductos := SumarProductos;
3. Dividir la sumatoria entre 11 y tomar la parte entera (B)

A / 11 = B
115 / 11 = 10.4545 , entonces: Parte entera = 10

//Paso3: Dividir la sumatoria entre 11 y tomar la parte entera:
Cociente := Int(SumadeProductos / 11);
ParteEntera := Trunc(Cociente);


4. Realizar la siguiente operación.

A – ( B * 11 )
115 – ( 10 * 11 ) = 5

//Paso4: Realizar la siguiente operación:
ResultadoOperacion := SumadeProductos - (ParteEntera * 11);
5. Restar a 11 el resultado de la operación anterior para obtener el dígito verificador correspondiente:

11 – 5 = 6

//Paso5: Restar 11 menos el resultado de la operacion anteriorDiferencia := 11 - ResultadoOperacion;

6. El valor obtenido en el paso anterior debe ser comparado con el siguiente cuadro:
Si el valor obtenido es
Entonces, el dígito verificador es
10

0
11
1

Otro número

El dígito verificador será el mismo digito obtenido.

//Paso6: Obtener el resultado
case Diferencia of
10: DigitoVerificador := 0;
11: DigitoVerificador := 1;
else
DigitoVerificador := Diferencia;
end;


Al ejecutar la aplicación, y dependiendo del número de RUC ingresado, nuestra aplicación se verá así:

Resúmen

En el presente artículo, se ha demostrado lo fácil y sencillo que es crear aplicaciones en Delphi 2006 usando Object Pascal. La aplicación de ejemplo tiene un uso bastante requerido en el Perú, básicamente en el ámbito contable – financiero.

4 comentarios:

Anónimo dijo...

En tu código:

Cociente := Int(SumadeProductos / 11);
ParteEntera := Trunc(Cociente);

me parece que la segunda operación está demás, si ya estás casetando a INTEGER.

En todo caso más limpio es:
Cociente := SumadeProductos div 11;

Anónimo dijo...

Me sirvió de mucho...gracias

charlieman dijo...

Gracias por el algoritmo. Para que compares, aquí esta una función de validación en python (esos _ deberían ser espacios):

def check_ruc(ruc):
____ruc = str(ruc)
____control = str(5432765432)
____n = 0
____for i, j in enumerate(ruc[:-1]):
________n += int(control[i]) * int(j)
____n = (n * 10) % 11 % 10
____return n == int(ruc[-1])

Anónimo dijo...

Hola, me quedo una duda:

Cuando no sera un ruc valido?
Por que en tu codigo dices:

case Diferencia of
10: DigitoVerificador := 0;
11: DigitoVerificador := 1;
else
DigitoVerificador := Diferencia;
end;

Si me pueden aclarar ese punto gracias.