Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Procedimiento Calculo RFC (https://www.clubdelphi.com/foros/showthread.php?t=75250)

amerika111 09-08-2011 00:57:55

Procedimiento Calculo RFC
 
Hola que tal, me pregunto si habra un procedimiento o si se pueda realizar un procedimiento en firebird para el calculo de un RFC...

oscarac 09-08-2011 02:16:03

sacame de mi ignorancia... que es un cálculo de RFC, sera el hermano de KFC y de Pizza Hut?

maeyanes 09-08-2011 02:24:28

Hola...

Si el compañero es Mexicano, se refiere al Registro Federal de Causantes, el cual te proporciona Hacienda para todo lo relacionado con el Fisco...


Saludos...

amerika111 09-08-2011 02:27:45

exactamente eso es el RFC (Registro Federal de Contribuyentes) que se obtiene de las siglas de los apellidos y nombre + la fecha de nacimiento y una homoclave...

amerika111 09-08-2011 02:33:56

En esta pagina se puede calcular...

https://www.recaudanet.gob.mx/recaudanet/rfc.jsp y quiero realizar algo como eso en un procedimiento...

ecfisa 09-08-2011 02:44:01

Hola amerika.

Confieso que quedé como oscarac cuando leí el título :)

Mirá, busqué un poco y encontre esta página donde está el código para calcularlo desde un stored procedure (Posts #13 y #14).
Como supondrás, no tengo idea si funciona, pero con probar no perdes nada... ;)

Un saludo y ojalá te sirva.

guillotmarc 09-08-2011 11:03:59

Ese código es en T-SQL de Microsoft SQL Server, por lo que no va a funcionar directamente en Firebird, pero es bastante sencillo traducirlo al Transact SQL estandarizado de Firebird.

Si tienes algún problema o duda sobre como tratar alguna sentencia concreta, no dudes en preguntar.

Saludos.

ecfisa 09-08-2011 19:30:39

Hola guillotmarc.

Me había dado cuenta que no era código de Firebird, aunque no sabía que era de SQL Sever.
Sin embargo no tengo idea si, una vez traducido, funcionará la lógica en sí del algorítmo.
Lamentablemente va a tener que hacer la traducción y prueba para verificarlo, espero que no le sea una tarea estéril...

Un saludo.

amerika111 09-08-2011 19:57:14

Cita:

Empezado por guillotmarc (Mensaje 408886)
Ese código es en T-SQL de Microsoft SQL Server, por lo que no va a funcionar directamente en Firebird, pero es bastante sencillo traducirlo al Transact SQL estandarizado de Firebird.

Si tienes algún problema o duda sobre como tratar alguna sentencia concreta, no dudes en preguntar.

Saludos.

Lo he probado en sql server y si funciona, ahora el puento es convertirlo ....


donde dice:
-INICIALZA VARIABLES
SET NOMBRES = LTRIM(RTRIM(:NOMBRES_AUX))
SET APATERNO = LTRIM(RTRIM(:APATERNO_AUX))
SET AMATERNO = LTRIM(RTRIM(:AMATERNO_AUX))
SET T_NOMTOT =APATERNO+' '+AMATERNO+' '+NOMBRES

esto si se puede asi en firebird, le e quitado los @

y hay otra palabra patindex no se a que se refiere..

SET NOMBRE1_LONGITUD = PATINDEX('% %',NOMBRES)

guillotmarc 09-08-2011 21:11:02

Cita:

Empezado por amerika111 (Mensaje 408927)
SET T_NOMTOT =APATERNO+' '+AMATERNO+' '+NOMBRES

Vaya, pensaba que en Firebird solo concatenaba el operador ||, y que por tanto esa línea había que traducirla como :

T_NOMTOT = APATERNO || ' ' || AMATERNO || ' ' || NOMBRES

Pero si dices que te funciona bien, entonces adelante.

Cita:

Empezado por amerika111 (Mensaje 408927)
y hay otra palabra patindex no se a que se refiere..

SET NOMBRE1_LONGITUD = PATINDEX('% %',NOMBRES)

Esta función retorna la primera aparición de una expresión en una cadena. En concreto te retorna la posición del primer espacio en blanco (y por tanto equivale a la longitud del nombre propio).

http://msdn.microsoft.com/en-us/library/ms188395.aspx

Deberías poder sustituirlo por :

NOMBRE1_LONGITUD = position(' ', NOMBRES)

La función POSITION se añadió en Firebird 2.1. Por lo tanto necesitas usar Firebird 2.1 o 2.5, para que esta línea funcione correctamente. Si usas una versión anterior de Firebird, entonces debes buscar una UDF que te brinde esta función (o similar), o bien, escribir un bucle recorriendo NOMBRES, para localizar donde está la primera cadena en blanco.

Saludos.

amerika111 09-08-2011 22:06:46

hola que tal he intentado convertir el codio pero no mas no, me vota muchos errores de sintaxis....

me he topado con esto, de un funcion pero me marca error

http://www.delphiaccess.com/forum/utilerias-22/udf-firebirdinterbase-(lazarus)/


error

invalid request BLR at offset 79 function GENRFC is not defined module name or entrypoint could not be found

amerika111 10-08-2011 00:41:25

Nomas no veo por donde...

Código SQL [-]
SET TERM ^^ ;
CREATE PROCEDURE P_CALCULO_RFC (
  NOMBRES_AUX VarChar(100), 
  APATERNO_AUX VarChar(100), 
  AMATERNO_AUX VarChar(100), 
  FECHANACIMIENTO Date)
 returns (
  RFC_OUT Char(16))
AS
/*
  You can change this template in the template editor:
  File | Preferences | Object Templates
  Procedure:
  Author   : , 
  Date     : 2010-06-14 10:47:01 a.m.
  Purpose  :
  Params
  ------
    : 
*/
DECLARE NOMBRES VARCHAR(100);
DECLARE APATERNO VARCHAR(100);
DECLARE AMATERNO VARCHAR(100);
DECLARE T_NOMTOT CHAR(52);
DECLARE NOMBRE1 VARCHAR(100); /*PRIMER NOMBRE */
DECLARE NOMBRE2 VARCHAR(100); /*DEMAS NOMBRES */
DECLARE NOMBRES_LONGITUD INT; /*LONGITUD DE TODOS @NOMBRES */
DECLARE NOMBRE1_LONGITUD INT ;/*LONGITUD DEL PRIMER NOMBRE(MAS UNO,EL QUE SOBRA ES UN ESPACIO EN BLANCO) */
DECLARE APATERNO1 VARCHAR(100); /*PRIMER NOMBRE */
DECLARE APATERNO2 VARCHAR(100); /*DEMAS NOMBRES */
DECLARE APATERNO_LONGITUD INT; /*LONGITUD DE TODOS @NOMBRES */
DECLARE APATERNO1_LONGITUD INT ;/*LONGITUD DEL PRIMER NOMBRE(MAS UNO,EL QUE SOBRA ES UN ESPACIO EN BLANCO) */
DECLARE AMATERNO1 VARCHAR(100); /*PRIMER NOMBRE */
DECLARE AMATERNO2 VARCHAR(100); /*DEMAS NOMBRES */
DECLARE AMATERNO_LONGITUD INT ;/*LONGITUD DE TODOS @NOMBRES */
DECLARE AMATERNO1_LONGITUD INT ;/*LONGITUD DEL PRIMER NOMBRE(MAS UNO,EL QUE SOBRA ES UN ESPACIO EN BLANCO) */
DECLARE VARLOOPS INT ;/*VARIABLE PARA LOS LOOPS, SE INICIALIZA AL INICIR UN LOOP */
DECLARE RFC CHAR(16);
DECLARE T_NOMNUM CHAR(102); /*Nombre numerico */
DECLARE T_SUMA INT ;
DECLARE T_DIVID INT; /* Dividendo */
DECLARE T_MOD INT; /* MOD de la division */
DECLARE T_HOMOCLV CHAR(3); /* Homoclave */
DECLARE T_NUMERO INT ;/* Numero ASC asignado a un caracter */
DECLARE T_PARCIAL INT ;/* Acumulado de la suma de los caracteres del RFC */
begin
/*INICIALZA VARIABLES */
NOMBRES = TRIM(NOMBRES_AUX);
APATERNO = TRIM(APATERNO_AUX);
AMATERNO = TRIM(AMATERNO_AUX);
T_NOMTOT =APATERNO||' '||AMATERNO||' '||NOMBRES;
/*PROCESAR NOMBRES DE PILA */
VARLOOPS = 0  ;
WHILE VARLOOPS <> 1  do
BEGIN
NOMBRES_LONGITUD = CHAR_LENGTH (NOMBRES);
NOMBRE1_LONGITUD = position('% %',NOMBRES);
IF (NOMBRE1_LONGITUD = 0)    then
NOMBRE1_LONGITUD = NOMBRES_LONGITUD;
NOMBRE1 = TRIM(LEFT(NOMBRES,NOMBRE1_LONGITUD));
NOMBRE2 = TRIM(RIGHT(NOMBRES,NOMBRES_LONGITUD - NOMBRE1_LONGITUD));
/*SE QUINTAN LOS NOMBRES DE JOSE, MARIA,MA,MA. */
IF (NOMBRE1 IN ('JOSE','MARIA','MA.','MA','DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND NOMBRE2 <> '') then
BEGIN
NOMBRES = NOMBRE2;
END 
ELSE
BEGIN
VARLOOPS = 1 ;
END
END
/*PROCESAMOS APELLIDOS, PATERNO EN UN LOOP */
VARLOOPS = 0;
WHILE VARLOOPS <> 1 do
BEGIN
APATERNO_LONGITUD = CHAR_LENGTH (APATERNO) ;
APATERNO1_LONGITUD =position('% %',APATERNO);
IF (APATERNO1_LONGITUD = 0 ) then
APATERNO1_LONGITUD = APATERNO_LONGITUD;
APATERNO1 = TRIM(LEFT(APATERNO,APATERNO1_LONGITUD))
APATERNO2 = TRIM(RIGHT(APATERNO,APATERNO_LONGITUD - APATERNO1_LONGITUD))
/*SE QUINTAN LOS SUFIJOS */
IF APATERNO1 IN ('DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND APATERNO2 <> ''
BEGIN
APATERNO = APATERNO2;
END 
ELSE
BEGIN
VARLOOPS = 1 ;
END
END
/*PROCESAMOS APELLIDOS, MATERNO EN UN LOOP */
VARLOOPS = 0;
WHILE VARLOOPS <> 1  do
BEGIN
AMATERNO_LONGITUD = LEN(AMATERNO);
AMATERNO1_LONGITUD = PATINDEX('% %',AMATERNO);
IF AMATERNO1_LONGITUD = 0
AMATERNO1_LONGITUD = AMATERNO_LONGITUD ;
AMATERNO1 = TRIM(LEFT(AMATERNO,AMATERNO1_LONGITUD));
AMATERNO2 = TRIM(RIGHT(AMATERNO,AMATERNO_LONGITUD - AMATERNO1_LONGITUD));
/*SE QUINTAN LOS SUFIJOS */
IF (AMATERNO1 IN ('DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND AMATERNO2 <> '')then
BEGIN
AMATERNO = AMATERNO2;
END 
ELSE
BEGIN
VARLOOPS = 1  ;
END
END
/*SE OBTIENE DEL PRIMER APELLIDO LA PRIMER LETRA Y LA PRIMER VOCAL INTERNA */
RFC = LEFT(APATERNO1,1);
APATERNO1_LONGITUD= LEN(APATERNO1) ;
VARLOOPS = 1 ;/*EMPIEZA EN UNO POR LA PRIMERA LETRA SE LA VA A SALTAR */
WHILE APATERNO1_LONGITUD > VARLOOPS  do
BEGIN
VARLOOPS = VARLOOPS + 1;
IF (SUBSTRING(APATERNO1,VARLOOPS,1) IN ('A','E','I','O','U')) then
BEGIN
RFC = RTRIM(RFC)+CONVERT(CHAR(1),SUBSTRING APATERNO1,@VARLOOPS,1));
VARLOOPS = APATERNO1_LONGITUD ;
END
END
/*SE OBTIENE LA PRIMER LETRA DEL APELLIDO MATERNO SI NO TIENE APELLIDO MATERNO SE PONE UNA X */
/*DICE QUE SI NO TIENE APELLIDO MATERNO LE PONGAS LA PRIMER LETRA DEL APELLIDO PATERNO EN EL RFX */
IF (IS NULL(AMATERNO1,'') = '') then
BEGIN
RFC = RTRIM(RFC)+CONVERT(CHAR(1),SUBSTRING(APATERNO1,1,1)) ;
END
ELSE
BEGIN
RFC = RTRIM(RFC)+CONVERT(CHAR(1),SUBSTRING(AMATERNO1,1,1));
END
/*SE LE AGREGA LA PRIMER LETRA DEL NOMBRE */
RFC = TRIM(RFC)+CONVERT(CHAR(1),SUBSTRING(NOMBRE1,1,1));
/*CHEAS QUE NO SEA UNA PALARA INCONVENIENTE */
/*
IF EXISTS ( SELECT INC_PALINC FROM NINCO WHERE INC_PALINC = @RFC )
BEGIN
SELECT @RFC = LTRIM(RTRIM (SUBSTRING (@RFC , 1 , 3))) + 'X'
END
*/
/*SE LE AGREGA LA FECHA DE NACIMIENTO */
RFC = RTRIM(RFC) + CONVERT(CHAR,FECHANACIMIENTO,12) ;
/*HOMOCLAVE */
T_NOMNUM = '0';
/*SACA NOMBRE NUMERICO */
VARLOOPS = 1 ;
WHILE VARLOOPS <= 52  do
BEGIN
T_NOMNUM = LTRIM(RTRIM (T_NOMNUM)) +
CASE
WHEN SUBSTRING (T_NOMTOT , VARLOOPS, 1) = 'A' THEN '11'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'B' THEN '12'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'C' THEN '13'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'D' THEN '14'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'E' THEN '15'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'F' THEN '16'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'G' THEN '17'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'H' THEN '18'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'I' THEN '19'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'J' THEN '21'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'K' THEN '22'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'L' THEN '23'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'M' THEN '24'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'N' THEN '25'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'O' THEN '26'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'P' THEN '27'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'Q' THEN '28'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'R' THEN '29'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'S' THEN '32'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'T' THEN '33'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'U' THEN '34'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'V' THEN '35'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'W' THEN '36'
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) = 'X' THEN '37'
SUBSTRING (T_NOMTOT , VARLOOPS , 1) <= '9' THEN CONVERT(VARCHAR,CONVERT(INT, SUBSTRING (T_NOMTOT , VARLOOPS , 1)) , 2)
WHEN SUBSTRING (T_NOMTOT , VARLOOPS , 1) IN ('&','Ñ') THEN '10'
ELSE '00'
END
VARLOOPS = VARLOOPS + 1;
END
VARLOOPS = 1 ;
T_SUMA = 0;
while VARLOOPS <= 99  do
T_SUMA = T_SUMA + ((CONVERT(INT,SUBSTRING (T_NOMNUM , VARLOOPS , 1))*10) + CONVERT(INT,SUBSTRING (T_NOMNUM , VARLOOPS+1 , 1))) * CONVERT(INT,SUBSTRING (T_NOMNUM , VARLOOPS+1 , 1));
VARLOOPS = VARLOOPS + 1 ;
end
/* Obtener HOMOCLAVE */
SELECT T_DIVID = T_SUMA%1000 /* Obtener residuo de los ultimos 3 digitos */
SELECT T_MOD = T_DIVID%34 /* Obtener el residuo de los ultimos 3 digitos-- entre 34 */
SELECT T_DIVID = (T_DIVID - T_MOD) / 34 /* Obtener el Cociente entero */
/*select @T_DIVID,@T_MOD */
/* Checar Cociente y residuo */
VARLOOPS = 0;
WHILE VARLOOPS <= 1  do
BEGIN
T_HOMOCLV =
CASE CASE VARLOOPS WHEN 0 THEN T_DIVID ELSE T_MOD END
WHEN 0 THEN '1' 
WHEN 1 THEN '2'
WHEN 2 THEN '3'
WHEN 3 THEN '4'
WHEN 4 THEN '5'
WHEN 5 THEN '6'
WHEN 6 THEN '7'
WHEN 7 THEN '8'
WHEN 8 THEN '9' 
WHEN 9 THEN 'A'
WHEN 10 THEN 'B'
WHEN 11 THEN 'C'
WHEN 12 THEN 'D'
WHEN 13 THEN 'E'
WHEN 14 THEN 'F'
WHEN 15 THEN 'G'
WHEN 16 THEN 'H'
WHEN 17 THEN 'I'
WHEN 18 THEN 'J'
WHEN 19 THEN 'K'
WHEN 20 THEN 'L'
WHEN 21 THEN 'M'
WHEN 22 THEN 'N'
WHEN 23 THEN 'P'
WHEN 24 THEN 'Q'
WHEN 25 THEN 'R'
WHEN 26 THEN 'S'
WHEN 27 THEN 'T'
WHEN 28 THEN 'U'
WHEN 29 THEN 'V'
WHEN 30 THEN 'W'
WHEN 31 THEN 'X'
WHEN 32 THEN 'Y'
ELSE 'Z'
END
VARLOOPS = VARLOOPS + 1;
/* Incluir la parte de la homoclave */
RFC = LTRIM(RTRIM (RFC)) + LTRIM(RTRIM (T_HOMOCLV));
END

/* --------------------------------------------- */
/* Obtener Digito Verificador */
/* --------------------------------------------- */
VARLOOPS = 0  ;
 T_PARCIAL = 0;
WHILE VARLOOPS < 12  do
BEGIN
SELECT VARLOOPS = VARLOOPS + 1
T_NUMERO =
CASE
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'A' THEN 10
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'B' THEN 11
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'C' THEN 12
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'D' THEN 13
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'E' THEN 14
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'F' THEN 15
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'G' THEN 16
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'H' THEN 17
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'I' THEN 18
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'J' THEN 19
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'K' THEN 20
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'L' THEN 21
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'M' THEN 22
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'N' THEN 23
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'O' THEN 25
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'P' THEN 26
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'Q' THEN 27
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'R' THEN 28
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'S' THEN 29
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'T' THEN 30
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'U' THEN 31
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'V' THEN 32
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'W' THEN 33
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'X' THEN 34
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'Y' THEN 35
WHEN SUBSTRING (RFC , VARLOOPS , 1) = 'Z' THEN 36
WHEN SUBSTRING (RFC , VARLOOPS , 1) >= '0' AND 
SUBSTRING (RFC , VARLOOPS , 1) <= '9'
THEN CONVERT(INT,SUBSTRING (RFC , VARLOOPS , 1))
WHEN SUBSTRING (RFC , VARLOOPS , 1) = ''
THEN 24
WHEN SUBSTRING (RFC , VARLOOPS , 1) = ' '
THEN 37
ELSE 0
END
/* Contabilizar el nuevo digito */
SELECT T_PARCIAL = T_PARCIAL + (T_NUMERO * (14 - VARLOOPS))
END 
T_MOD = ROUND(T_PARCIAL%11,1);
IF (T_MOD = 0 ) then
RFC = LTRIM(RTRIM (RFC)) + '0' ;
ELSE
BEGIN
T_PARCIAL = 11 - T_MOD ;
IF (T_PARCIAL = 10 ) then
SELECT RFC = LTRIM(RTRIM (RFC)) + 'A'
ELSE
SELECT RFC = LTRIM(RTRIM (RFC)) + CONVERT(VARCHAR ,T_PARCIAL)
END

/*SELECT T_NOMTOT,T_SUMA */
:RFC_OUT = :RFC;
SELECT :RFC AS 'RFC'

end ^^
SET TERM ; ^^

amerika111 10-08-2011 02:41:07

especificamente estos son los errores que arroja.

guillotmarc 10-08-2011 09:57:18

Bueno, el primer error es que no encuentra la función POSITION.

Como te dije en el mensaje anterior, esta función solo está disponible en Firebird 2.1 o 2.5. Si utlizas Firebird 1.5 o 2.0, tendrías que actualizarte a una versión más moderna, o bien, utilizar una UDF que haga la misma acción (o bien sustituirlo por un bucle para localizar esa posición del primer espacio en blanco).

Recuerda también que POSITION no es exactamente igual al PATINDEX de SQL Server, puesto que esta última función trabaja con expresiones regulares, y la función de Firebird no.

Por eso la forma correcta de utilizarla es POSISTION(' ', variable) y no POSITION('% %', variable).

Lo mejor es corregir los errores uno a uno (puesto que muchas veces algunos errores posteriores son causa del primero).

Arregla primero esto, y ya nos contarás.

guillotmarc 10-08-2011 10:01:27

Respecto al segundo error (los IF, BEGIN, ELSE) simplemente viene provocado porqué en esta sección (línea 91) te falta un THEN :

Cita:

/*SE QUINTAN LOS SUFIJOS */
IF APATERNO1 IN ('DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND APATERNO2 <> ''
BEGIN
debería ser :

Cita:

/*SE QUINTAN LOS SUFIJOS */
IF APATERNO1 IN ('DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND APATERNO2 <> '' then
BEGIN
Los otros mensajes ya no son errores. Solo son avisos, el sistema te está avisando de variables y parámetros que has declarado pero que nunca usas.

amerika111 10-08-2011 18:33:05

Cita:

Empezado por guillotmarc (Mensaje 408934)
Vaya, pensaba que en Firebird solo concatenaba el operador ||, y que por tanto esa línea había que traducirla como :

T_NOMTOT = APATERNO || ' ' || AMATERNO || ' ' || NOMBRES

Pero si dices que te funciona bien, entonces adelante.



Esta función retorna la primera aparición de una expresión en una cadena. En concreto te retorna la posición del primer espacio en blanco (y por tanto equivale a la longitud del nombre propio).

http://msdn.microsoft.com/en-us/library/ms188395.aspx

Deberías poder sustituirlo por :

NOMBRE1_LONGITUD = position(' ', NOMBRES)

La función POSITION se añadió en Firebird 2.1. Por lo tanto necesitas usar Firebird 2.1 o 2.5, para que esta línea funcione correctamente. Si usas una versión anterior de Firebird, entonces debes buscar una UDF que te brinde esta función (o similar), o bien, escribir un bucle recorriendo NOMBRES, para localizar donde está la primera cadena en blanco.

Saludos.

y encuanto a la udf sobre calcular el rfc... vi que comentaste algo sobre esto

yo la he probado pero no me funciona no se si tenga que realizar un paso o algo asi para que funcione, este es el dll de la funcion

DECLARE EXTERNAL FUNCTION GENRFC
CSTRING(30),
CSTRING(30),
CSTRING(30),
DATE
RETURNS CSTRING(15)
ENTRY_POINT 'GeneraRFC' MODULE_NAME 'Project1.dll';


y la libreria es project1.dll

esa la coloque en la carpeta de firebird
de udf..

guillotmarc 10-08-2011 20:38:43

Hola.

Cita:

Empezado por amerika111 (Mensaje 409064)
y encuanto a la udf sobre calcular el rfc... vi que comentaste algo sobre esto

yo la he probado pero no me funciona no se si tenga que realizar un paso o algo asi para que funcione, este es el dll de la funcion

DECLARE EXTERNAL FUNCTION GENRFC
CSTRING(30),
CSTRING(30),
CSTRING(30),
DATE
RETURNS CSTRING(15)
ENTRY_POINT 'GeneraRFC' MODULE_NAME 'Project1.dll';


y la libreria es project1.dll

esa la coloque en la carpeta de firebird
de udf..

En realidad no he comentado el que definas tu GENRFC en una UDF, sino que en el caso de que no quieras utilizar Firebird 2.1 o 2.5 (que son las que tienen la nueva función POSITION que en cierta manera equivale al PATINDEX de SQL Server), entonces deberás buscar esa función Pos() de alguna DLL (pero las UDF's que incorpora Firebird de serie, no incorporan dicha función). Aunque personalmente te recomiendo lo que ya también te comenté de que simplemente sustituyas el PATINDEX por un bucle para localizar la posición de la cadena en blanco.

Ejplo.

Esta sentencia :

NOMBRE1_LONGITUD = position(' ', NOMBRES);

Equivale a este bucle :

Código SQL [-]
NOMBRE1_LONGITUD = 1;
while substring(NOMBRES from :NOMBRE1_LONGITUD for 1) not in (' ', '') do begin
  NOMBRE1_LONGITUD = NOMBRE1_LONGITUD + 1;
end

if (substring(NOMBRES from :NOMBRE1_LONGITUD for 1) = '') then begin
  NOMBRE1_LONGITUD = 0;    /* No existe ningún espacio en blanco en NOMBRES */
end

Finalmente, respecto a generar toda la función RFC en Delphi y utilizarla en Firebird mediante una UDF, te dejo un ejemplo de como hacer la DLL en Delphi para que pueda ser utilizada en Firebird.

http://www.firebirdfaq.org/faq83/
Traducción automática de Google

Saludos.

Gallosuarez 11-08-2011 14:54:45

Ofrecimiento ...
 
Amerika111:

Ofrezco mi humilde ayuda para codificar dicho procedimiento almacenado, siempre y cuando me hagas llegar el proceso por escrito (lo mas explicito que se pueda, así como también algunos casos típicos para ver que todo funciona correctamente), no quiero estar viendo el código en otros lenguajes y hacer suposiciones que no siempre resultan ciertas, ¿me explico?. Espero tu respuesta.

Saludos,
Gerardo Suárez Trejo

roman 11-08-2011 22:03:23

Cita:

Empezado por Gallosuarez (Mensaje 409199)
siempre y cuando me hagas llegar el proceso por escrito (lo mas explicito que se pueda, así como también algunos casos típicos para ver que todo funciona correctamente)

¡Uf! El proceso es algo líoso. No sé si Amerika111 ya te lo hizo llegar, pero mientras tanto voy a intentar describirlo aquí.

El RFC es un identificador alfanumérico que se asigna en México a cada persona y se basa en los apellidos, nombre y fecha de nacimiento. Para fijar ideas, vamos a tomar esta persona ficticia:

Apellido paterno: Del Real
Apellido Materno: Anzures
Nombre: José Antonio
Fecha de nacimiento: 14 de abril de 1972

Su RFC será:

Código:

REAA 720414 N9 4
Las primeras cuatro letras se forman a partir de apellidos y nombre, sigue la fecha de nacimiento en formato aammdd, luego dos caracteres de homonimia y termina con un dígito verificador.

Veamos por partes, como se calcula cada una:

Letras

Esta parte se forma con:
  • Primera letra del apellido paterno
  • Primera vocal interna del apellido paterno
  • Primera letra del apellido materno
  • Primera letra del nombre

Ahora bien, deben tomarse en cuenta estas excepciones:
  1. En nombres compuestos se toma la primera palabra siempre y cuando no sea JOSE o MARIA (en el ejemplo se omitió JOSE y se toma ANTONIO)
  2. Se omiten artículos, preposiciones, conjunciones y contracciones de apellidos y nombres. La lista oficial es:

    Código:

    DE, LA, LAS, MC, VON, DEL, LOS, Y, MAC, VAN, MI
    (en el ejemplo se omitió DEL)
  3. Si el apellido paterno consta de una o dos letras (por ejemplo: DE LA O, una vez que se omiten los artículos), se toman la primera letra del apellido paterno, la primera del apellido materno y las dos primeras del nombre.
  4. Si sólo hay un apellido se toman las dos primeras letras del apellido y las dos primeras del nombre)
  5. Si las cuatro letras resultantes coinciden con una palabra "fea", debe sustituirse la última letra por una X. La lista oficial de palabras "feas" es:

    Código:

    BUEI, BUEY, CACA, CACO, CAGA, CAGO, CAKA, CAKO, COGE, COJA, COJE, COJI, COJO,
    CULO, FETO, GUEY, JOTO, KACA, KACO, KAGA, KAGO, KAKA, KOGE, KOJO, KULO, MAME,
    MAMO, MEAR, MEAS, MEON, MION, MOCO, MULA, PEDA, PEDO, PENE, PUTA, PUTO, QULO,
    RUIN, RATA,


Aquí hay que notar, que estas reglas no son absolutas ni completas (pero son las oficiales). Por ejemplo, no indican qué hacer en caso de que el apellido paterno no contenga vocales internas, como ALBY, BYRD, ORMSBY.

En alguna ocasión tuve la oportunidad de analizar los RFC de una base de datos relativamente amplia y observé que la excepción 4 en realidad es así:

Primera letra y primera vocal interna del apellido y primera y segunda letra del nombre.

En resumen, parece que en los casos de excepción, muchas veces depende del criterio del funcionario en turno que asigne el RFC oficial.

Fecha

En formato de seis diígitos: aammdd

Homonimia
  1. Se toma el nombre completo de la persona, comenzando por los apellidos:

    Código:

    DEL REAL ANZURES JOSE ANTONIO
    En este caso se toma todo el nombre incluyendo lo que se omite en el cálculo de las letras.

  2. A cada letra se le asocia un valor numérico de acuerdo a la siguiente tabla:

    Código:

    esp        00        |        I        19
    0        00        |        J        21
    1        01        |        K        22
    2        02        |        L        23
    3        03        |        M        24
    4        04        |        N        25
    5        05        |        O        26
    6        06        |        P        27
    7        07        |        Q        28
    8        08        |        R        29
    9        09        |        S        32
    &        10        |        T        33
    A        11        |        U        34
    B        12        |        V        35
    C        13        |        W        36
    D        14        |        X        37
    E        15        |        Y        38
    F        16        |        Z        39
    G        17        |        Ñ        40
    H        18        |

    Hay que observar que los valores no son consecutivos (hay un salto después de la I y despúés de la R). Cada valor debe incluir el cero inicial y al principio de toda la cadena de números se añade un cero solitario. En el ejemplo quedaría así:

    Código:

            D        E        L                R        E        A        L                A        N        Z        U        R        E        S                J        O        S        E                A        N        T        O        N        I        O
    0        14        15        23        00        29        15        11        23        00        11        25        39        34        29        15        32        00        21        26        32        15        00        11        25        33        26        25        19        26

    quedando la siguiente cadena de dígitos:

    Código:

    01415230029151123001125393429153200212632150011253326251926
  3. Esta cadena se recorre de izquierda a derecha desde el primero hasta el penúltimo caracter. En la iteración i-ésima se multiplican los dígitos i e i+1.

    Se suman todos los productos. En el ejemplo queda: 4756

  4. De este número se toman los tres últimos (el residuo al dividir por 1000), en este caso: 756

  5. Se toman el cociente y el residuo de este número al dividirse por 34:

    Cociente: 22
    Residuo: 8

  6. Se buscan los caracteres correspondientes en la siguiente tabla:

    Código:

    0        1        |        17        I
    1        2        |        18        J
    2        3        |        19        K
    3        4        |        20        L
    4        5        |        21        M
    5        6        |        22        N
    6        7        |        23        P
    7        8        |        24        Q
    8        9        |        25        R
    9        A        |        26        S
    10        B        |        27        T
    11        C        |        28        U
    12        D        |        29        V
    13        E        |        30        W
    14        F        |        31        X
    15        G        |        32        Y
    16        H        |        33        Z

    Obsérvese que no hay letra O. Al cociente (22) le corresponde N y al residuo (8) le corresponde 9.

  7. Estos dos caracteres forman la homonimia: N9

Dígito verificador
  • A cada caracter del RFC ya formado (cuatro letras, fecha y homonimia; 12 en total) se le asigna un valor numérico según la tabla:

    Código:

    0        0        |        K        20
    1        1        |        L        21
    2        2        |        M        22
    3        3        |        N        23
    4        4        |        &        24
    5        5        |        O        25
    6        6        |        P        26
    7        7        |        Q        27
    8        8        |        R        28
    9        9        |        S        29
    A        10        |        T        30
    B        11        |        U        31
    C        12        |        V        32
    D        13        |        W        33
    E        14        |        X        34
    F        15        |        Y        35
    G        16        |        Z        36
    H        17        |        ESP        37
    I        18        |        Ñ        38
    J        19        |

    Nótese que hay un espacio y un ampersand intercalados y que la Ñ está fuera de orden.

  • Cada valor se multiplica por la posición del caracter correspondiente en el RFC contada de derecha a izquierda empezando por 2:

    Código:

      R        E        A        A        7        2        0        4        1        4        N        9
      28        14        10        10        7        2        0        4        1        4        23        9
    x 13        12        11        10        9        8        7        6        5        4        3        2
    ------------------------------------------------------------------------------------------
     364        168        110        100        63        16        0        24        5        16        69        18

  • Se toma la suma de estos productos: Suma=953

  • De esta suma, se toma el residuo al dividirse por 11 y luego su complemento:

    DV = 11 - (Suma mod 11) (este número siempre está en el rango 1..11)

    Este es el dígito verificador, a menos que sea 11, en cuyo caso se toma 0 (cero).

    En el ejemplo, DV = 11 - (953 mod 11) = 11 - 7 = 4.

Algunas observaciones

Como dije antes, el algoritmo en la parte de las letras es confuso. Al implementar hay que decidir qué hacer en los casos especiales (por ejemplo, poner una X en caso de no haber vocal interna del apellido paterno).

Por otra parte, todas las letras de los nombres deben considerarse sin acentos de ningún tipo.

Este algoritmo es únicamente para personas físicas (seres humanos) y no para personas morales (empresas).

Desconozco si hay un documento oficial de Hacienda que describa el algoritmo, pero existe un documento oficial (en el cual yo me basé) en el IFAI (Instituto Federal de Acceso a la Información).

Este documento pueden localizarlo entrando al sitio de INFOMEX buscando el folio: 0610100135506, que corresponde a la solicitud que alguien hizo para obtener esta información. Ahí pueden ver el documento de respuesta. Este documento también describe el algoritmo del RFC para personas morales.

// Saludos

Gallosuarez 11-08-2011 22:30:07

Rfc ...
 
Román:

Excelente, es justamente lo que necesitaba... de hecho ya empece .... creo que ya llevo la primera parte ... tuve que parar un rato (hay que ganarse el pan de cada día, je, je, je).

Saludos,
Gerardo Suárez Trejo

P.D. Estoy indeciso en liberar la primera parte (de esta forma es más fácil hacer la depuración). ¿Hay alguien que se apunte para hacer las pruebas?


La franja horaria es GMT +2. Ahora son las 19:19:47.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi