Fórum Código automático no produto (Delphi 2010) #501415

17/11/2014

0

Estou precisando de ajuda para deixar um campo colocando o codigo automaticamente quando eu clico em Gravar.
Estou usando o Delphi 2010; IBoConsole; FireBird 2,5.

No IBOConsole criei o seguinte script:


CREATE TABLE BAIRRO
(
BAIRROCODIGO INTEGER NOT NULL,
BAIRRONOME VARCHAR(35),

CONSTRAINT BAIRRO_PK PRIMARY KEY (BAIRROCODIGO)
);

(esse script estou querendo criar um formulário separado somente para cadastro de bairros, para eu depois usa um DBLookupComboBox, no meu formulário de clientes).

Estou usando um IBDatabase; IBTransaction; IBTable; DataSource (todos dentro de um data modulo).

Quando eu clico em SALVAR o novo cadastro ele me retorna uma mensagem:

Project xxxxxx.exe raised exception class EDatabaseError with nessage 'Field 'BAIRROCODIGO' must have a value'.

Me ajudem a resolver esse pepino.
Rubens Pena

Rubens Pena

Responder

Posts

17/11/2014

Joel Rodrigues

Você precisa criar um GENERATOR e um TRIGGER para preencher esse campo com valores automáticos. Pesquise sobre isso.
Responder

Gostei + 0

17/11/2014

Rubens Pena

Boa tarde Joel Rodrigues.

Pesquisei a respeito do assunto GENERATOR e um TRIGGER. utilizei o IBOConsole pra fazer isso, ate ai ta dando certo, ele ta gerando o cod automaticamente quando faço o processo utilizando o o sql >>>>> insert into .... values.... <<<<<<, ele coloca o cod ok, mais quando vou pra dentro do delphi apago as fild antiga insiro a nova fild, continua do mesmo jeito, ele nao gera o cod quando eu clico no botao inserir antes deu digitar o nome do BAIRRO, como no scrip acima. O comando que tem dentro do botão que criei é o seguinte:

try
PageControl1.TabIndex := 0;
DBEdit2.SetFocus;
dmDados.ibBairro.Append
except
showmessage ('Operação Invalida!');
end;

estou utilizando um action list (faco a ligação do insert do action list nesse botão, através do data source)

Então quando clico em salvar continua dando a mesma mensagem:
Project xxxxxx.exe raised exception class EDatabaseError with nessage 'Field 'BAIRROCODIGO' must have a value'.

Obs.: estou com esse problema em outros formulários de não ta gerando o cod, citei esse por ser um script pequeno.
Responder

Gostei + 0

17/11/2014

Rubens Pena

alguem ai me aajudaaa remotamente....
Responder

Gostei + 0

18/11/2014

Renato Rubinho

Buenas,

1. Cria o generator (Exemplo: GEN_BAIRRO_ID).

CREATE GENERATOR GEN_BAIRRO_ID;

2. Seta o valor inicial.
SET GENERATOR GEN_BAIRRO_ID TO 0;

3. No AfterInsert do seu dmDados.ibBairro:

3.1. Chama um objeto query para buscar o GEN_ID.

oQuery.Close;
oQuery.Clear;
oQuery.Sql.Add('SELECT GEN_ID(GEN_BAIRRO_ID, 1) AS GEN_ID FROM RDB$DATABASE);
oQuery.Open;

3.2. Seta o valor recebido do generator no campo do Bairro.
dmDados.ibBairroBAIRROCODIGO.AsInteger := oQuery.FieldByName('GEN_ID').AsInteger;

Abraççç,
Renato
Responder

Gostei + 0

22/11/2014

Rubens Pena

Buenas

rrubinho não consegui, tem como você da uma olhada remotamente pra ver qual o real problema?
A parte do generator esta ok, não to conseguindo solucionar os outros processos.

Meu Skype é: RPena. (Rubens Pena)

Recaptulando:

Estou utilizando um botao chamado SpeedButton (renomeei ele para SpeedButtonNOVObairro); Na orelha de evento desse botão na propriedade action estou ligando a um ActionList1; quando eu dou um duplo click no botao coloquei o seguinte comando:

try
PageControl1.TabIndex := 0; << estou usando uma PageControl1
DBEdit2.SetFocus;
dmDados.ibBairro.Append
except
showmessage ('Operação Invalida!');
end;

o que estou querendo é que quando eu clicar no SpeedButton ele coloque a numeração sucessora do ultimo código e já vá para o DBEDit2 (local onde vou colocar o nome do bairro), não sei se é esse o processo correto quando se utilizar PageControl1, e SpeedButton .

Queria que me ajudasse via remoto, vocês visualizarem minha tela remotamente pra tentar solucionar o problema, mas só posso da acesso remoto hoje durante a noite 22/11/14 e amanha 23/11/14 durante o dia todo, se não somente no próximo final de semana.


Segue umas imagens abaixo


[img:descricao=001 - Componetes do Formulario]http://arquivo.devmedia.com.br/forum/imagem/383412-20141122-231123.jpg[/img]
Nessa imagem a esquerda ta todos os componentes usados nesse forme

[img:descricao=002 - Componetes do Data Module]http://arquivo.devmedia.com.br/forum/imagem/383412-20141122-231209.jpg[/img]
Componentes do DataModule

[img:descricao=003 - comando dentro do botao novo]http://arquivo.devmedia.com.br/forum/imagem/383412-20141122-231236%20%281%29.jpg[/img]

[img:descricao=004 - projeto aberto]http://arquivo.devmedia.com.br/forum/imagem/383412-20141122-231254%20%281%29.jpg[/img]

[img:descricao=005 - mensagem que da quando clico em gravar]http://arquivo.devmedia.com.br/forum/imagem/383412-20141122-231325.jpg[/img]
Mensagem de erro quando clico em gravar, ele não ta gerando o código e não ta voltando o cursos para o DBEdite2.

[img:descricao=006 - mensagem que da quando clico em gravar 2]http://arquivo.devmedia.com.br/forum/imagem/383412-20141122-231347%20%281%29.jpg[/img]

[img:descricao=007 - IBOConsole]http://arquivo.devmedia.com.br/forum/imagem/383412-20141122-231751.jpg[/img]



Aguem se habilita .
Responder

Gostei + 0

23/11/2014

Rubens Pena

ainda nao consegui solucionar. Me ajudem...
Responder

Gostei + 0

23/11/2014

Marcos Saffran

Olá Rubens, a mensagem :

Project xxxxxx.exe raised exception class EDatabaseError with nessage 'Field 'BAIRROCODIGO' must have a value'.

Normalmente ocorre quando o campo está configurado como obrigatório (required).

Coloque essa propriedade (required) do campo BAIRROCODIGO como false em IBTableBAIRRO.
Responder

Gostei + 0

23/11/2014

Rubens Pena

Olá Rubens, a mensagem :

Project xxxxxx.exe raised exception class EDatabaseError with nessage 'Field 'BAIRROCODIGO' must have a value'.

Normalmente ocorre quando o campo está configurado como obrigatório (required).

Coloque essa propriedade (required) do campo BAIRROCODIGO como false em IBTableBAIRRO.


-----------------------------------------------------------------------------------------------------------------------------------------------------------

Boa noite Marcos Alfredo Saffran.

Fiz o procedimento acima citado, esta inserindo o código. Mais tem um probleminha como nas fotos abaixo:

[img:descricao=Imagem 1]http://arquivo.devmedia.com.br/forum/imagem/383412-20141124-011808.jpg[/img]

Como mostrado na imagem acima (imagem 1), quando clico no botão Novo, ele ta pulando pro DBEdit2 como configurado, mais não aparece o código (é pra ele assim que eu clicar em Novo já aparecer o prox código) /// Como não esta aparecendo a numeração do código, no DBGrid também não aparece. /// e o campo (DBEdit2) BAIRRONOME assim que eu clico em Gravar é pra limpar a área (DBEdit2).

[img:descricao=Imagem 2]http://arquivo.devmedia.com.br/forum/imagem/383412-20141124-012639.jpg[/img]

Como mostrado na imagem 2 aparece a numeração do código tanto no campo do código DBEdit1, com no campo código do DBGrid. Mas só aparece depois que eu fecho o sistema e entro novamente.

Agora estou querendo fazer essas correções. Conto novamente com a ajuda de vocês. Mais acima tem outras fotos.
Responder

Gostei + 0

24/11/2014

Marcos Saffran

Bom dia Rubens,

para aparecerem os valores depois de clicar no botão gravar, insira o applyupdates(-1) e o refresh no evento "after post" da tabela.

Quanto a aparecer o código quando você clica em novo, realmente não irá aparecer, pois o código só é gerado depois de gravar e como a tabela está em modo 'insert', todos os campos estarão limpos, para que você os insira.

O campo BAIRRONOME não é limpo quando você clica em gravar, pois ele busca o mesmo campo que está selecionado na tabela, nesse caso é o último inserido, para ficar 'limpo', deve-se substituir o dbedit por um edit e fazer as buscas e inserções via programação.
Responder

Gostei + 0

24/11/2014

Renato Rubinho

Rubens,

Não sei se compreende a teoria exata para perceber o erro. Vou detalhar, desculpe se estiver menosprezando seu conhecimento.

Você está com o objeto dmDados.ibBairro em memória carregado.
Ao dar o append, ainda não interagiu com o banco (não chamou a trigger).
Se você trabalhar com a trigger e o gennerator, irá gerar no banco após o post. Fechando o sistema e abrindo-o novamente você recarrega a query, trazendo as informações atualizadas. Se fechar a query e abrí-la novamente, tem o mesmo efeito.

O exemplo que te passei dispensaria a trigger e recarregar a query porque após o append você chamar o gennerator, pegar o valor do resultado e seta no dmDados.ibBairroBAIRROCODIGO antes do post. Ao dar o post, a informação já "estará no dmDados.ibBairroBAIRROCODIGO" e será a mesma que gravará no banco. São duas formas diferentes de trabalhar e fica a seu critério o que preferir.

Então:
1. Mantendo a trigger.
- Deixe a propriedade required como false no campo dmDados.ibBairro para não exigir informação ao gravar os dados
- Após o post, feche e abra a query novamente para atualizar os dados gravados no banco inclusive o número gerado pelo gennerator+trigger
- Lembrando de posicionar novamente no registro que estava após fechar e abrir a query, senão irá parar no primeiro registro da query

2. Fazendo "na mão"
- Desative a trigger, senão terá o preenchimento do dmDados.ibBairroBAIRROCODIGO duas vezes.
- No seu objeto dmDados.ibBairro vá no evento AfterInsert.
- Ao dar o Append esse precedimento será acionado.
- Nele você chama uma query para acessar o Gennerator do banco e pegar o valor gerado
- O valor que você receber, preencha no campo dmDados.ibBairroBAIRROCODIGO.
- Ao dar o post, o valor estará preenchido no campo em memória e será gravado o mesmo no banco.

procedure TdmDados.ibBairroAfterInsert(DataSet: TDataSet);
begin
  //Chama um objeto query para buscar o GEN_ID.
  IBQuery1.Close;
  IBQuery1.Clear;
  IBQuery1.Sql.Add('SELECT GEN_ID(GEN_BAIRRO_ID, 1) AS GEN_ID FROM RDB$DATABASE);
  IBQuery1.Open;

  //Seta o valor recebido do generator no campo do Bairro.
  dmDados.ibBairroBAIRROCODIGO.AsInteger := IBQuery1.FieldByName('GEN_ID').AsInteger;

  IBQuery1.Close;
  IBQuery1.Clear;
end;


Abraççç
Responder

Gostei + 0

24/11/2014

Rubens Pena

Bom dia Mestres [rrubinho] e [MARCOS ALFREDO SAFFRAN] , agradeço a ajuda que voês me passaram nas 2 ultimas respostas acima.
Do rrubinho utilizei:
("refresh no evento "after post" da tabela").

E do MArcos utilizei:
(''1. Mantendo a trigger.
- Deixe a propriedade required como false no campo dmDados.ibBairro para não exigir informação ao gravar os dados
- Após o post, feche e abra a query novamente para atualizar os dados gravados no banco inclusive o número gerado pelo gennerator+trigger
- Lembrando de posicionar novamente no registro que estava após fechar e abrir a query, senão irá parar no primeiro registro da query'')

Esta gerando os códigos como eu queria, mais ainda não esta 100% esta 99%, pois como mostrado na imagem abaixo, o campo BAIRROCODIGO não está memorizando o ultimo dado cadastrado. (Obs. ele aparece normalmente quando vou inserindo, mais quando encerro o programa e entro novamente ele esta ficando na posição 1, sendo que ate o presente momento tem 42 exemplos inseridos, entao é pra ficar aparecendo a numeração 42 no campo).

[img:descricao=imagem 3]http://arquivo.devmedia.com.br/forum/imagem/383412-20141124-104041.jpg[/img]

Na próxima imagem esta como eu fiz o comando atualmente depois das ajudas de vocês:

[img:descricao=Imagem 4]http://arquivo.devmedia.com.br/forum/imagem/383412-20141124-105107.jpg[/img]
ibAuxBairro.Close; // ibAuxBairro.Open; (coloquei pra auxiliar na pesquisa) não tinha nas imagens anteriores, foto abaixo com esse componente:

[img:descricao=imagem 5]http://arquivo.devmedia.com.br/forum/imagem/383412-20141124-105429.jpg[/img]

Então é isso mestres, só falta isso pra deixar minha duvida 100% respondida, conto com vocês, e já agradeço pela paciência que estão tendo em me ensinar.
Responder

Gostei + 0

24/11/2014

Renato Rubinho

Se entendi bem você apenas quer posicionar no último registro quando abrir a query.
Provavelmente está em ordem crescente pelo código do bairro e quando abre a query fica posicionado no primeiro registro.
Após a abertura do form posicione no último registro:

dmDados.ibBairro.Last;


Abraççç,
rrubinho
Responder

Gostei + 0

24/11/2014

Rubens Pena

rrubinho boa tarde.

Fiz o que me passou mais nao deu certo:

vou passar os comandos do botao NOVO (inserir) e do botao (GRAVAR)

Novo:

begin
try
PageControl1.TabIndex := 0;
DBEdit2.SetFocus;
dmDados.ibBairro.Append
except
showmessage ('Operação Invalida!');
end;
end;


Gravar:

begin
try
dmDados.ibBairro.Post; // Gravar
ibAuxBairro.Close; // Fechar a ibquery auxBairro (Forum Dev Media)
ibAuxBairro.Open; // Abri a ibquery auxBairro (Forum Dev Media)
dmDados.ibBairro.Last; // ir para o ultimo registro <<<<<<<<<<<<<<<<<<<<<<<<<<<< Processo passado acima.
DBEdit2.SetFocus; // Deixar o cursos no DBedit2

ShowMessage ('Registro Gravado com Sucesso');
except
showmessage ('Operação Invalida!');
end;
end;

se você achar melhor um acesso remoro meu skip é RPENA. (tem um ponto no final).
Responder

Gostei + 0

24/11/2014

Rubens Pena

rrubinho boa tarde.

Deu certo fiz da seguinte forma:

No evento OnShow do formulário, digitei o comando: dmDados.ibBairro.Last;
Responder

Gostei + 0

24/11/2014

Rubens Pena

Boa tarde.

Como eu faco pra zerar os dados dessa tabela, pra começar novamente o código do 0 (zero).
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar