No exemplo anterior postado, eu mostro como fazer um cálculo do dígito verificador módulo10 do banco do brasil, e neste, mostro como é feito o cálculo usando o módulo11. Essas duas funções, referente aos chamados DV(Dígito Verificador), podem serem executadas sem nenhuma alteração, pois, elas não fazem referência as tabelas do banco de dados, são funções das quais chamo de "Genéricas".
CREATE OR REPLACE FUNCTION "TS_ParcelaBloquetoBancoBrasilModulo11"(xdocumento character varying)
RETURNS character varying AS
$BODY$
declare
XNumero Varchar;
XNumeroOrg Varchar;
XCont Integer;
XParcial Integer;
XDivisorM11 Integer;
XResto Integer;
XDigVerM11 Integer;
XMultiplo Integer;
begin
/*
Função responsável por calcular o DV módulo 11
Esta informação vai impressa no bloqueto
*/
--Pegando somente os números do documentos
XNumeroOrg = regexp_replace(XDocumento, '[^[:digit:]]', '', 'g');
/*
*** Calculando Módulo "11" ***
*/
XDivisorM11 = 2;
XParcial = 0;
XNumero = trim(XNumeroOrg);
XCont = length(XNumero);
loop
--Pegando número a número e multiplicando por 2 a 9 e acumulando o resultado linha a linha
if XDivisorM11 > 9 then
XDivisorM11 = 2;
end if;
XParcial = XParcial + Cast(SubStr(trim(XNumero),XCont,1) as Integer) * XDivisorM11;
XDivisorM11 = XDivisorM11 + 1;
XCont = XCont - 1;
if XCont = 0 then
Exit;
end if;
end loop;
/*
Tratando o resultado da multiplicação
*/
XResto = Cast(((XParcial-(trunc(Cast(XParcial as Numeric(15,2))/11))*11)) as Integer);
XDigVerM11 = 11 - XResto;
if XDigVerM11 = 0 or XDigVerM11 = 10 or XDigVerM11 = 11 then
XDigVerM11 = 1;
end if;
Return XDigVerM11;
end;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION "TS_ParcelaBloquetoBancoBrasilModulo11"(character varying) OWNER TO postgres;
*** Para executar esta função digite: ***
Select "TS_ParcelaBloquetoBancoBrasilModulo11"('12345678')
Select "TS_ParcelaBloquetoBancoBrasilModulo11"('12345678')
Calcula certinho o digito, parabéns.
ResponderExcluirMuito bom! Fiz uma modificação para validar digitação:
ResponderExcluir--DROP FUNCTION Modulo11(XDocumento Varchar)
CREATE OR REPLACE FUNCTION public.modulo11(XDocumento Varchar)
RETURNS boolean AS
$BODY$
declare
XNumero Varchar;
XCont Integer;
XParcial Integer;
XDivisorM11 Integer;
XResto Integer;
XDigVerM11 Integer;
XMultiplo Integer;
--Digito digitado para ser confrontado
XDocDigito char(1);
begin
/*
Função responsável por validar o DV módulo 11
Pode ser utilizada para a maioria das contas bancarias, CPF, CNPJ e outros titulos que
utilizam o artificio.
*/
--Pegando somente a parte significativa para o calculo.
--O último digito de XDocumento é o DV, propriamente dito
XNumero = regexp_replace(SubStr(XDocumento, 1, length(XDocumento)-1), '[^[:digit:]]', '', 'g');
--Captura o DV digitado para ser confrontado
XDocDigito = SubStr(XDocumento, length(XDocumento),1);
/*
*** Calculando Módulo "11" ***
*/
XDivisorM11 = 2;
XParcial = 0;
XCont = length(XNumero);
loop
--Pegando número a número e multiplicando por 2 a 9 e acumulando o resultado linha a linha
if XDivisorM11 > 9 then
XDivisorM11 = 2;
end if;
XParcial = XParcial + Cast(SubStr(trim(XNumero),XCont,1) as Integer) * XDivisorM11;
XDivisorM11 = XDivisorM11 + 1;
XCont = XCont - 1;
if XCont = 0 then
Exit;
end if;
end loop;
/*
Tratando o resultado da multiplicação
*/
XResto = Cast(((XParcial-(trunc(Cast(XParcial as Numeric(15,2))/11))*11)) as Integer);
XDigVerM11 = 11 - XResto;
if XDigVerM11 = 0 or XDigVerM11 = 10 or XDigVerM11 = 11 then
/*
Para algumas entidades (Codigo de barras e alguns bancos) quando o resultado do calculo
for 0, 10 ou 11 utilizar o confronto com exDV que será o valor para o tratamento.
Por exemplo: Para calcular DV das contas do BB, quando o resultado for 10 ou 11, deve-se utilizar
o DV 'X' em exDV
*/
--XDigVerM11 = 1;
Return true;
else
Return cast(XDigVerM11 as char) = XDocDigito;
end if;
end;
$BODY$ LANGUAGE 'plpgsql' VOLATILE;
Show de bola. Obrigado
ResponderExcluirNão funcionou no padrão febraban.
ResponderExcluirPara o número 23 o dígito é 9 e não está ocorrendo isso.