Fórum Emissaõ de Notas Fiscais (Só p/ Experientes) #149324
24/03/2003
0
Tenho um sistema que faz a rotina de Nota Fiscal e imprimi blz, o numero da Nota é gerado por trigger no before Insert, utilizo este numero gerado para referenciar os Itens com a Nota Fiscal, até ai blz.
Mas agora resolvi colocar meu sistema na rede e o problema é o seguinte:
Imagine que eu tenho duas máquinas na rede fazendo Notas Fiscais, então, a máquina 1 começa a fazer uma Nota e o trigger gera o numero 10 para ela, daí a máquina 2 tb começa a fazer uma nota e o trigger gera o numero 11 para ela.
Daí a máquina 2 grava primeiro que a máquina 1 e a máquina 1 cancela a operação de Nota Fiscal. Então eu perdi o numero 10 e isso não pode acontecer. Como devo fazer ? Será que alguém tem outra solução mais cabivel ?
Aguardo respostas....
camile_enhanced@ig.com.br
Beijos
Anonymous
Curtir tópico
+ 0Posts
24/03/2003
Belo
Prefiro o código na mão, estude este exemplo do proprio ClubDelphi:
procedure TDM.Incrementa(Nome_Tabela : String; Chave_Primaria : TField);
var Qry : TSQLQuery;
begin
if Chave_Primaria.DataSet.State <> dsInsert then
exit; //termina a execução caso não esteja em modo de inserção
Qry:=TSQLQuery.Create(nil); //cria uma instância do objeto
try
Qry.SQLConnection:=SQLConnect; //componente de conexão
Qry.SQL.Add(´SELECT MAX(´+Chave_Primaria.FieldName+´) FROM ´+Nome_Tabela);
Qry.Open;
if Qry.Fields[0].IsNull then //se a tabela está vazia retornará nulo
Chave_Primaria.AsInteger:=1 //então este será o primeiro registro
else Chave_Primaria.AsInteger:=Qry.Fields[0].AsInteger+1;
finally
FreeAndNil(Qry); //tira o objeto da memória
end;
end;
(**********************************************************************)
procedure TDM.SuaTabelaBeforePost(DataSet: TDataSet);
begin
Incrementa(´MARCAS´,SuaTabelaCOD_NOTA);
end;
Gostei + 0
25/03/2003
E_gama
Nos meus sistemas, quando preciso obter numeracao automatica, utilizo SQL para obter o ultimo numero cadastrado:
[color=blue:c72b93448a]
QryUltNota.SQL.Text := select max(NFI_NUMERO) as ULT_NF from NFISCAL;
[/color:c72b93448a]
Com a SQL acima, tenho a ultima nota fiscal gravada, assim, adiciono +1 ao resultado e atualizo meu campo de ´numero da nota fiscal´ no evento ´BeforePost´ com o codigo abaixo:
[color=blue:c72b93448a]
QryUltNota.Open;
QryNFiscal.FieldByName(´NFI_NUMERO´).AsInteger := QryUltNota.FieldByName(´ULT_NF´).AsInteger + 1;
QryUltNota.Close;
[/color:c72b93448a]
Gostei + 0
25/03/2003
Anonymous
Como faço para referenciar os Itens com esta Nota Fiscal ?
Beijos
Gostei + 0
25/03/2003
E_gama
1) Você tem uma tabela para ´Nota Fiscal´ e outra ´Para ítens da nota fiscal´ ?
2) Seu banco de dados está com os relacionamentos definidos, com integridade referencial e tudo mais?
2) Você está utilizando ´Master/Detail´ no seu formulário para relacionar as tabelas no seu formulário ?
Me responda essas perguntas para eu poder te ajudar...
Gostei + 0
25/03/2003
Anonymous
José
Gostei + 0
25/03/2003
Anonymous
Gostei + 0
25/03/2003
E_gama
Vou te passar uma apostila (talvez você até já tenha) que tem muitos conceitos em relação a esse assunto. Acredito ser uma boa idéia você dar uma lida nela (principalmente no capítulo sobre ´Master/Detail´).
Espero que lhe ajude...
[url]http://www.salesiano.com.br/egama/delphics.zip[/url]
Gostei + 0
25/03/2003
Aroldo Zanela
Camile,
Apesar de ser iniciante, estava verificando algumas informações sobre interbase e encontrei a seguinbte informação no site www.firebase.com.br - ´No InterBase existem dois tipos de Trigger (BEFORE e AFTER). Isto é, é disparado um gatilho antes do INSERT/UPDATE/DELETE e ou é disparado um gatilho após o INSERT/UPDATE/DELETE´.
Portanto, minha sugestão seria criar uma chave artificial (p.e: auto-incremento) que deveria ser obtida pelo disparo da trigger ´before insert´ para amarrar o relacionamento de mestre/detalhe e numa trigger ´after insert´ obteria o número da nota fiscal.
No site referenciado acima existem muitas informações úteis para quem usa Interbase.
Imagino uma série de outras formas para se resolver o seu problema, esta me parece a de menor esforço.
Gostei + 0
26/03/2003
Aroldo Zanela
Encontrei esse material aqui. Dá uma olhada, caso não tenha resolvido de forma satisfatória:
http://www.firebase.com.br/fb/
Como manter uma sequencia contínua de números
Como manter uma sequência ininterrupta de números
Extraído do Help do Interbase Objects (IBO)
Tradução e adaptação : Carlos Henrique Cantu - exclusivo para a Interbase-BR
Nota : O exemplo utiliza propriedades específicas do IBO, mas para aqueles que não utilizam os componentes IBO, creio que poderão adaptar a idéia sem muitas dificuldades.
Vamos usar um exemplo para manter o número de notas fiscais contínuo.
Primeiro passo, utilize como chave primária uma chave substituta, onde não seja importante o fato haver ´furos´ na sequência dos números, e ligue ela à um generator através da propriedade GeneratorLinks. Chame esse campo de IDNotas e um outro de Numero_Nota.
Depois, em uma transação subsequente separada (por exemplo, na hora de imprimir a nota) faça com que seja atribuído através de um generator o valor para Numero_Nota. Faça com que essa transação seja especial, configurada assim : ServerAutoCommit=true, Isolation=tiCommitted, RecVersion=false e LockWait=true. Também faça com que o comando SQL de atualização contenha uma clausula WHERE Numero_Nota IS NULL para que ele não use um registro que esteja sendo utilizado por uma outra operação rápida. Certifique-se que a edição foi realmente executada checando a propriedade RowsAffected. Essa é uma combinação especial que faz com que a operação seja 100¬ garantida em um ambiente multi-usuário.
Depois da nota ter sido impressa, de maneira semelhante, atualize o registro novamente para indicar que ela foi impressa.
A opção ServerAutoCommit garante que a atualização seja postada pelo servidor, independente de ter que se esperar que o cliente de a ordem de commit. Isso remove uma grande chance de falha.
A combinação da opção NoRecVersion e LockWait previne o aparecimento de um erro devido à um deadlock. Isso fará com que a atualização espere até o final de outras transações que possam estar trabalhando com o mesmo registro, antes de le-lo e atualiza-lo. Se isso não fosse feito, ela leria o registro, executaria o update, chamaria o evento BEFORE UPDATE, incrementaria o generator, encontraria um deadlock, cancelaria o update e causaria uma quebra na sequência de valores.
Espero que esse breve resumo ajude a resolver esse tipo de problema. É muito importante que voce faça essa operação 100¬ garantida em um ambiente multi-usuário e acredito que esse método seja o mais seguro. Duvido que outras variações se saiam bem um teste stressante.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)