Alberto Mota Postado Janeiro 21, 2010 Denunciar Share Postado Janeiro 21, 2010 Estou usando o sql server e o delphi 7.Devido a imprecisão do manual de boleto bancário da caixa.Depois de 6000 impressões, 2 clientes ligaram dizendo que não conseguiramefetuar o pagamento. A coincidência é que o dv geral do código de barras dos dois é 0.Liguei para lá e disseram que não pode ser 0 no dv geral. Agora é que dizem isso.Abaixo segue a função que uso para saber o dv geral do módulo 11.Se o resto for 0, 10 ou 1 o dv geral será 1.Como adequo essa função? Desde já agradeço.USE [secraso]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER FUNCTION [dbo].[Modulo11](@VALOR varchar(60))RETURNS CHAR(1)ASBEGIN DECLARE @SOMA INT, @CONTADOR INT, @PESO INT, @DIGITO INT, @RETORNO CHAR(1), @BASE INT, @RESTO BIT SET @SOMA = 0 SET @PESO = 2 SET @BASE = 9 SET @RESTO = 0 SET @CONTADOR = Len(@VALOR) LOOP: BEGIN SET @SOMA = @SOMA + (Convert(int, SubString(@VALOR, @CONTADOR, 1)) *@PESO) IF (@PESO < @BASE) SET @PESO = @PESO + 1 ELSE SET @PESO = 2 SET @CONTADOR = @CONTADOR-1 END IF @CONTADOR >= 1 GOTO LOOP IF (@RESTO = 1) BEGIN SET @RETORNO = (@SOMA % 11) END ELSE BEGIN SET @DIGITO = 11 - (@SOMA % 11) IF (@DIGITO > 9) SET @DIGITO = 0 SET @RETORNO = @DIGITO END RETURN @RETORNOEND Link para o comentário Compartilhar em outros sites More sharing options...
0 fulvio Postado Janeiro 21, 2010 Denunciar Share Postado Janeiro 21, 2010 Boa tade Alberto, Alterei a função. Dá uma olhada se está ok. Caso não seja isso que deseja, pode postar!! USE [secraso] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER FUNCTION [dbo].[Modulo11](@VALOR varchar(60)) RETURNS CHAR(1) AS BEGIN DECLARE @SOMA INT, @CONTADOR INT, @PESO INT, @DIGITO INT, @RETORNO CHAR(1), @BASE INT, @RESTO BIT SET @SOMA = 0 SET @PESO = 2 SET @BASE = 9 SET @RESTO = 0 SET @CONTADOR = Len(@VALOR) LOOP: BEGIN SET @SOMA = @SOMA + (Convert(int, SubString(@VALOR, @CONTADOR, 1)) * @PESO) IF (@PESO < @BASE) SET @PESO = @PESO + 1 ELSE SET @PESO = 2 SET @CONTADOR = @CONTADOR-1 END IF @CONTADOR >= 1 GOTO LOOP IF (@RESTO = 1) BEGIN SET @RETORNO = (@SOMA % 11) END ELSE BEGIN SET @DIGITO = 11 - (@SOMA % 11) IF (@DIGITO > 9) SET @DIGITO = 0 SET @RETORNO = @DIGITO END IF @RETORNO=0 or @RETORNO=10 SET @RETORNO = 1 RETURN @RETORNO END Link para o comentário Compartilhar em outros sites More sharing options...
0 Alberto Mota Postado Janeiro 21, 2010 Autor Denunciar Share Postado Janeiro 21, 2010 Resolveu.Fulvio, muito obrigado, voce não sabe a ajuda que deu.Muito, muito obrigado.Desejo todo o sucesso e paz para voce e sua familia.Um grande abraço. Link para o comentário Compartilhar em outros sites More sharing options...
0 fulvio Postado Janeiro 21, 2010 Denunciar Share Postado Janeiro 21, 2010 Boa tarde Alberto, Obrigado, pra você também. Precisando nós estamos aí!! Link para o comentário Compartilhar em outros sites More sharing options...
0 Alberto Mota Postado Janeiro 23, 2010 Autor Denunciar Share Postado Janeiro 23, 2010 Analisando a função do módulo 11 do sql server que o Fulvio corrigiu resolvi constatar minuciosamente se havia alguma falha de interpretação.O que está no manual da Caixa é o seguinte:Módulo "11", com peso de 2 a 9, utilizando o digito 1 para os restos 0, 10 ou 1 (regraexclusiva para cálculo do DV geral do código de barras);na função o que foi alterado foi a variavel @retorno e não a variavel @resto.Talvez esteja de fato resolvido, mas confesso que estou com dúvidas.Por isso gostaria de ter essa confirmação. Haviam 965 boletos cujos dv geral eram 0e com a função todos ficaram como 1. É isso mesmo?Desde já agradeço.Eis a função:USE [secraso]GO/****** Object: UserDefinedFunction [dbo].[Modulo11] Script Date: 01/23/2010 11:22:30 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER FUNCTION [dbo].[Modulo11](@VALOR varchar(60))RETURNS CHAR(1)ASBEGINDECLARE@SOMA INT,@CONTADOR INT,@PESO INT,@DIGITO INT,@RETORNO CHAR(1),@BASE INT,@RESTO BITSET @SOMA = 0SET @PESO = 2SET @BASE = 9SET @RESTO = 0SET @CONTADOR = Len(@VALOR)LOOP:BEGINSET @SOMA = @SOMA + (Convert(int, SubString(@VALOR, @CONTADOR, 1)) *@PESO)IF (@PESO < @BASE)SET @PESO = @PESO + 1ELSESET @PESO = 2SET @CONTADOR = @CONTADOR-1ENDIF @CONTADOR >= 1 GOTO LOOPIF (@RESTO = 1)BEGINSET @RETORNO = (@SOMA % 11)ENDELSEBEGINSET @DIGITO = 11 - (@SOMA % 11)IF (@DIGITO > 9) SET @DIGITO = 0SET @RETORNO = @DIGITOENDIF @RETORNO=0 or @RETORNO=10SET @RETORNO = 1RETURN @RETORNOEND Link para o comentário Compartilhar em outros sites More sharing options...
0 fulvio Postado Janeiro 25, 2010 Denunciar Share Postado Janeiro 25, 2010 Bom dia Alberto, A alteração que realizei foi realmente no @retorno, e não no @resto. Mas de acordo com o script que passou, vc "seta" a variável @RESTO = 0 no principio do script, não realiza nenhuma atribuição de valor a variável, e testa se @RESTO = 1. Pergunta: estes valores "setando" as variáveis é apenas um exemplo? Achei a explicação do manual da caixa que passou, um pouco ambiguo: - você altera o resto para 1 quando o mesmo for 0, 10 ou 1? - ou você retorna o digito 1 quando o resto for 0, 10 ou 1? Pesquisei na net e identifiquei que o digito é 1 quando o resto for 0, 10 ou 1. http://pt.wikipedia.org/wiki/D%C3%ADgito_v...#M.C3.B3dulo_11 Realizei a implementação novamente. Dê uma olhada se é isto mesmo. Testei também o peso, pois de acordo com a regra que passou, o peso deverá ser de 2 a 9. Comentei no código a alteração acrescentada. Qualquer dúvida, posta ai.USE [secraso] GO /****** Object: UserDefinedFunction [dbo].[Modulo11] Script Date: 01/23/2010 11:22:30 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER FUNCTION [dbo].[Modulo11](@VALOR varchar(60)) RETURNS CHAR(1) AS BEGIN DECLARE @SOMA INT, @CONTADOR INT, @PESO INT, @DIGITO INT, @RETORNO CHAR(1), @BASE INT, @RESTO BIT SET @SOMA = 0 SET @PESO = 2 SET @BASE = 9 SET @RESTO = 0 SET @CONTADOR = Len(@VALOR) LOOP: BEGIN SET @SOMA = @SOMA + (Convert(int, SubString(@VALOR, @CONTADOR, 1)) * @PESO) IF (@PESO < @BASE) SET @PESO = @PESO + 1 ELSE SET @PESO = 2 SET @CONTADOR = @CONTADOR-1 END IF @CONTADOR >= 1 GOTO LOOP -- codigo acrescentado IF (@PESO BETWEEN '2' AND '9') and (@RESTO in (0, 1, 10)) Begin Set @RETORNO = 1 RETURN @RETORNO End ------ IF (@RESTO = 1) BEGIN SET @RETORNO = (@SOMA % 11) END ELSE BEGIN SET @DIGITO = 11 - (@SOMA % 11) IF (@DIGITO > 9) SET @DIGITO = 0 SET @RETORNO = @DIGITO END RETURN @RETORNO END Link para o comentário Compartilhar em outros sites More sharing options...
0 Alberto Mota Postado Janeiro 25, 2010 Autor Denunciar Share Postado Janeiro 25, 2010 (editado) Fulvio, o certo é retorna o digito 1 quando o resto for 0, 10 ou 1.coloquei o Modulo 11 do Post Anterior sobre dv 0 quando deveria ser 1.Com esse boleto em mãos fui ao Banco hoje e paguei o boleto normalmente.10499.79808 08917.700109 04015.895438 1 44990000000000E os outros continuaram inalterados como esperava.Com seu ultimo post todos agora possuem dv = 1Isso quer dizer que o correto mesmo é o script anterior.Um abraço. Editado Janeiro 25, 2010 por Alberto Mota Link para o comentário Compartilhar em outros sites More sharing options...
0 fulvio Postado Janeiro 25, 2010 Denunciar Share Postado Janeiro 25, 2010 Boa tarde Alberto, Os dv´s serão iguais a 1 mesmo, pois está "sentando" o @RESTO = 0, e não há nenhuma manipulação deste dado até a cláusula IF (por isso que perguntei se os valores atribuidos às variáveis no começo do script eram exemplo). Perceba que o script possui "IF (@RESTO = 1)". Sendo assim, o script somente executa a parte do ELSE, onde tinha colocado o teste na variável "@Retorno" (post anterior). Caso tenha alguma dúvida, sempre estou on line no MSN (olhe no meu perfil). Podemos trocar algumas idéias a respeito. Qualquer dúvida, pode postar!! Link para o comentário Compartilhar em outros sites More sharing options...
Pergunta
Alberto Mota
Estou usando o sql server e o delphi 7.
Devido a imprecisão do manual de boleto bancário da caixa.
Depois de 6000 impressões, 2 clientes ligaram dizendo que não conseguiram
efetuar o pagamento.
A coincidência é que o dv geral do código de barras dos dois é 0.
Liguei para lá e disseram que não pode ser 0 no dv geral.
Agora é que dizem isso.
Abaixo segue a função que uso para saber o dv geral do módulo 11.
Se o resto for 0, 10 ou 1 o dv geral será 1.
Como adequo essa função?
Desde já agradeço.
USE [secraso]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[Modulo11](@VALOR varchar(60))
RETURNS CHAR(1)
AS
BEGIN
DECLARE
@SOMA INT,
@CONTADOR INT,
@PESO INT,
@DIGITO INT,
@RETORNO CHAR(1),
@BASE INT,
@RESTO BIT
SET @SOMA = 0
SET @PESO = 2
SET @BASE = 9
SET @RESTO = 0
SET @CONTADOR = Len(@VALOR)
LOOP:
BEGIN
SET @SOMA = @SOMA + (Convert(int, SubString(@VALOR, @CONTADOR, 1)) *
@PESO)
IF (@PESO < @BASE)
SET @PESO = @PESO + 1
ELSE
SET @PESO = 2
SET @CONTADOR = @CONTADOR-1
END
IF @CONTADOR >= 1 GOTO LOOP
IF (@RESTO = 1)
BEGIN
SET @RETORNO = (@SOMA % 11)
END
ELSE
BEGIN
SET @DIGITO = 11 - (@SOMA % 11)
IF (@DIGITO > 9) SET @DIGITO = 0
SET @RETORNO = @DIGITO
END
RETURN @RETORNO
END
Link para o comentário
Compartilhar em outros sites
7 respostass a esta questão
Posts Recomendados