Fórum Erro em rotina de auto incremento. #267895
09/02/2005
0
Tenho uma pequena aplicação onde controla um numero sequencial em um campo chave. Uso ACCESS com ADO e coloquei a procedure abaixo no evento ONNEWRECORD da tabela DESPESAS_DIARIAS do Data Module DATAMOD. Não sei porque mas no momento em que a rotina ´DataMod.ADOTable_Despesas_Diarias.Last;´ é processada o DELPHI emite a mensagem: ´iNDICE OU CHAVE PRIMARIA NAO PODE CONTER UM VALOR NULL´.
VOCES PODERIAM ME AJUDAR E DEFINIR O QUE ESTA ERRADO?
procedure TDataMod.ADOTable_Despesas_DiariasNewRecord(DataSet: TDataSet);
var MainKey: integer;
LancCod: string;
begin
{ Inicializando variáveis }
DataMod.ADOTable_Despesas_DiariasDES_DATA.Value := Date;
{ Determinando um novo código de Lançamento }
DataMod.ADOTable_Despesas_Diarias.Open;
DataMod.ADOTable_Despesas_Diarias.Last;
MainKey := DataMod.ADOTable_Despesas_DiariasDes_Cod.AsInteger;
Inc(MainKey);
{DataMod.ADOTable_Despesas_Diarias.Insert;}
LancCod := formatcurr(´0000000000´,MainKey);
DataMod.ADOTable_Despesas_DiariasDes_Cod.AsString := LancCod;
DataMod.ADOTable_Despesas_Diarias.Refresh;
end;
Muito Obrigado,
Alexsandro
Alexsandro
Curtir tópico
+ 0Posts
09/02/2005
Gandalf.nho
Gostei + 0
09/02/2005
Alexsandro
Entendo que coloquei esta rotina no evento ON NEW RECORD da tabela e este evento é chamado no momento de eu pressionar o botão ´+´ do navegador certo? O que você está me dizendo é que neste momento eu ja´estou com aquela famosa linha em aberto (com * indicando novo registro) e que não posso me mover para o ultimo por que ele valida a chave primaria vazia. LEGAL: Entendi tudo...Só não consigo entender por que muitas pessoas aqui do fórum colocam rotinas simples, sem a necessidade de usar QUERY, como a de baixo e dizem que ela funciona. O que preciso fazer para ela funcionar? Seria um outro evento? Sem usar o DBNAGIVATOR? Resumindo: Eu gostaria de fazer a rotina funcionar sem a necessidade de query. Agradeço mais comentários...
Veja o código abaixo que encontrei no Fórum:
´Caro amigo, esperimente fazer assim, no momento de adicionar um novo registro, sem a necessidade da query:
var cod:integer; //criar a variavel cod
begin
TBCandidatos.last; //ultimo registro da tabela
cod:=TBCandidatosCodCandidato.value; //pega o valor do último código
inc(cod); //incrementa 1
DBEdit1.text:=inttostr(cod); //define DBEdit1´
Onde coloco este evento? É possível usá-lo com o DBNAVIGATOR?
Muito Obrigado,
Alexsandro Áfio
Gostei + 0
09/02/2005
Gandalf.nho
Gostei + 0
09/02/2005
Alexsandro
Foi so tirar a inicialização da Data que funcionou...Agora o problema está com o evento .INSERT que está chamando a routina ONNEWRECORD novamente...tipo ficando em LOOP...Provavlemnete isso acontece porque o botão ´+´ do DBNAVIGATOR já chamou a rotina INSERT certo? Você teria alguma sugestão....????? POis sem o evento .INSERT, no momento que vou atribuir o novo código ao campo do Data Module ele dá um erro dizendo que a tabela não está em INSERT ou EDIT???
Alex
Gostei + 0
09/02/2005
Gandalf.nho
Gostei + 0
09/02/2005
Alexsandro
Sei que tô perto de resolver este mistério, mas ainda não foi dessa vez.
Estou em um ´Se correr o bicho pega, Se ficar o bicho come...´
Tanto no evento OnNewRecord como no BeforeInsert, quando o evento .INSERT abaixo processa ele recomeça a rotina e fica em LOOP.
Se eu não colocar o EVENTO .INSERT o Delphi dar a mensagem de erro no momento em que eu estou atribuíndo o novo código ao campo chave: ´dataset is not in edit or insert mode´...
E Agora? O que é que eu faço???
Muito Obrigado,
Alex
procedure TDataMod.ADOTable_Despesas_DiariasNewRecord(DataSet: TDataSet);
var MainKey: integer;
LancCod: string;
begin
{ Determinando um novo código de Lançamento }
DataMod.ADOTable_Despesas_Diarias.Open;
DataMod.ADOTable_Despesas_Diarias.Last;
MainKey := DataMod.ADOTable_Despesas_DiariasDes_Cod.AsInteger;
Inc(MainKey);
DataMod.ADOTable_Despesas_Diarias.Insert;
LancCod := formatcurr(´0000000000´,MainKey);
DataMod.ADOTable_Despesas_DiariasDes_Cod.AsString := LancCod;
DataMod.ADOTable_Despesas_Diarias.Refresh;
end;
Gostei + 0
09/02/2005
Gandalf.nho
Gostei + 0
10/02/2005
Alexsandro
Obrigado pelo seu empenho, mas acredito que sua solução não resolve meu problem por conta de um detalhe: Eu gostaria que o novo número aparecesse na tela no momento em que eu pressiono o botão de inclusão ´+´ do DBNAVIGATOR. Se eu colocar a atribuição do campo no evento BEFOREPOST, o novo número só vai ser visto depois.
Talvez tenha uma solução: Posso usar no form uma variável EDIT no lugar de uma DBEDIT vinculada à tabela, atualizo esta
variável e quando for salvar, no BEFOREPOST. O que você acha disso?
Mesmo assim gostaria de entender porque uma rotina que todos falam ser tão simples simples não funciona da forma que colocam.
Se alguém puder ajudar eu agradeço.
Alex
Gostei + 0
10/02/2005
Gandalf.nho
Gostei + 0
10/02/2005
Alexsandro
Matei a Xarada: O que acontece é que o evento .LAST coloca a tabela em status de BROWSE. Por isso no código sugerido pelo pessoal eles colocam o .INSERT novamente. Acontece que não posso colocar o evento .INSERT dentro do ONNEWRECORD ou BEFOREINSERT porque isso chama o evento novamente causando o LOOP. E, se não coloco o INSERT, ocorre um erro de exceção dizendo que a tabela não está em status de INSERT ou EDIT. LOGO, a lógica do pessoal está furada.
Quando deixei de executar o LAST e no lugar disso estou gravando o código do ultimo numero em uma outra tabela. com isso tudo se resolveu e agora entendi porque algumas pessoas sugeriram códigos usando outra tabela e a prórpia aplicação da Borland: MASTAPP usa outra tabela. Obrigado por suas explicações pois me ajudaram...
Alex
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)