Tratamento de Erro de Botões Com Falha
Oi pessoal, espero que vcs possam me ajudar nisso, não to conseguindo achar o erro:
Tenho um formulário pra inserir um Grupo. os campos são Nome e Tipo. Os Tipos são pré-determinados (Nacionais, Importadas, Fumetti e Mangás). Então eu coloquei o TDbEdtTipo desabilitado e invisível na tela e coloquei um TDbComboBox listando esses 4 tipos. Quando um é selecionado, automáticamente o TDbEdtTipo recebe aquele nome.
Tenho também um procedimento que criei pra tratar os erros dos botões (Novo, Salvar, Editar, Cancelar e Apagar). Esses tratamentos ficaram assim:
Botões Novo e Editar:
Botões Salvar e Cancelar:
Certo. Botei também os seguintes códigos no ´OnChange´ dos TDbEdtNome, TDbEdtTipo e TDbComboBox, pra evitar que o botão Salvar fique habilitado quando algum dos campos for nulo. A idéia é o Botão só ficar habilitado quando tiver os dois campos com conteúdo.
OnChange TEdtDbNome:
OnChange TDbEdtTipoGrupo
OnChange TDbComboBox.
Eu até achei esse código meio exagerado pra isso, mas tinha funcionado em outro programa que fiz. Neste eu só adaptei.
O problema é, quando o formulario é ativado, os botões funcionam de acordo, mas quando navego pelos registros pela Grid, logo na primeira mudança o botão Salvar habilita e fica habilitado. Na verdade era pra ele ficar desabilitado até clicar em Novo ou Editar.
Alguém conhece uma solução mais simples pra isso? que não seja o DbNavigator, que eu simplesmente odeio.. hehehe.. abraços..
Allan Elias Ramos :wink:
Tenho um formulário pra inserir um Grupo. os campos são Nome e Tipo. Os Tipos são pré-determinados (Nacionais, Importadas, Fumetti e Mangás). Então eu coloquei o TDbEdtTipo desabilitado e invisível na tela e coloquei um TDbComboBox listando esses 4 tipos. Quando um é selecionado, automáticamente o TDbEdtTipo recebe aquele nome.
Tenho também um procedimento que criei pra tratar os erros dos botões (Novo, Salvar, Editar, Cancelar e Apagar). Esses tratamentos ficaram assim:
Botões Novo e Editar:
if DbEdtNomeGrupo.Text = ´´ then begin BtNovo.Enabled := False; BtSalvar.Enabled := False; BtEditar.Enabled := False; BtCancelar.Enabled := True; BtApagar.Enabled := False; BtSair.Enabled := False; DbEdtNomeGrupo.Enabled := True; DbCbTipoGrupo.Enabled := True; DbGridGrupos.Enabled := False; DbEdtNomeGrupo.SetFocus; end else begin BtNovo.Enabled := False; BtSalvar.Enabled := True; BtEditar.Enabled := False; BtCancelar.Enabled := True; BtApagar.Enabled := False; BtSair.Enabled := False; DbEdtNomeGrupo.Enabled := True; DbCbTipoGrupo.Enabled := True; DbGridGrupos.Enabled := False; DbEdtNomeGrupo.SetFocus; end;
Botões Salvar e Cancelar:
if DmDados.ClientGrupos.RecordCount = 0 then begin BtNovo.Enabled := True; BtSalvar.Enabled := False; BtEditar.Enabled := False; BtCancelar.Enabled := False; BtApagar.Enabled := False; BtSair.Enabled := True; DbEdtNomeGrupo.Enabled := False; DbCbTipoGrupo.Enabled := False; DbGridGrupos.Enabled := True; end else begin BtNovo.Enabled := True; BtSalvar.Enabled := False; BtEditar.Enabled := True; BtCancelar.Enabled := False; BtApagar.Enabled := True; BtSair.Enabled := True; DbEdtNomeGrupo.Enabled := False; DbCbTipoGrupo.Enabled := False; DbGridGrupos.Enabled := True; end;
Certo. Botei também os seguintes códigos no ´OnChange´ dos TDbEdtNome, TDbEdtTipo e TDbComboBox, pra evitar que o botão Salvar fique habilitado quando algum dos campos for nulo. A idéia é o Botão só ficar habilitado quando tiver os dois campos com conteúdo.
OnChange TEdtDbNome:
if DbEdtNomeGrupo.Enabled = True then begin if (DbEdtNomeGrupo.Text = ´´) and (DbEdtTipoGrupo.Text = ´´) then begin BtSalvar.Enabled := False; end else if (DbEdtNomeGrupo.Text <> ´´) and (DbEdtTipoGrupo.Text = ´´) then begin BtSalvar.Enabled := False; end else if (DbEdtNomeGrupo.Text = ´´) and (DbEdtTipoGrupo.Text <> ´´) then begin BtSalvar.Enabled := False; end else begin BtSalvar.Enabled := True; end; end; end;
OnChange TDbEdtTipoGrupo
if (DbEdtTipoGrupo.Text = ´´) and (DbEdtNomeGrupo.Text = ´´) then begin BtSalvar.Enabled := False; end else if (DbEdtTipoGrupo.Text = ´´) and (DbEdtNomeGrupo.Text <> ´´) then begin BtSalvar.Enabled := False; end else if (DbEdtTipoGrupo.Text <> ´´) and (DbEdtNomeGrupo.Text = ´´) then begin BtSalvar.Enabled := False; end else begin BtSalvar.Enabled := True; end; end;
OnChange TDbComboBox.
if DbCbTipoGrupo.Enabled = True then begin if (DbCbTipoGrupo.Text = ´´) and (DbEdtNomeGrupo.Text = ´´) then begin BtSalvar.Enabled := False; end else if (DbCbTipoGrupo.Text = ´´) and (DbEdtNomeGrupo.Text <> ´´) then begin BtSalvar.Enabled := False; end else if (DbCbTipoGrupo.Text <> ´´) and (DbEdtNomeGrupo.Text = ´´) then begin BtSalvar.Enabled := False; end else begin BtSalvar.Enabled := True; end; end; end;
Eu até achei esse código meio exagerado pra isso, mas tinha funcionado em outro programa que fiz. Neste eu só adaptei.
O problema é, quando o formulario é ativado, os botões funcionam de acordo, mas quando navego pelos registros pela Grid, logo na primeira mudança o botão Salvar habilita e fica habilitado. Na verdade era pra ele ficar desabilitado até clicar em Novo ou Editar.
Alguém conhece uma solução mais simples pra isso? que não seja o DbNavigator, que eu simplesmente odeio.. hehehe.. abraços..
Allan Elias Ramos :wink:
Aersoftware
Curtidas 0
Respostas
Emerson Nascimento
22/08/2005
no OnStateChange do Datasource:
Botões Novo e Editar:
Botões Salvar e Cancelar:
OnChange TEdtDbNome:
OnChange TDbEdtTipoGrupo
OnChange TDbComboBox.
BtNovo.Enabled := Datasource.Dataset.Active and not (Datasource.Dataset.State in [dsEdit, dsInsert]); BtSalvar.Enabled := Datasource.Dataset.State in [dsEdit, dsInsert]; BtEditar.Enabled := BtNovo.Enabled and not Datasource.Dataset.IsEmpty; BtCancelar.Enabled := BtSalvar.Enabled; BtApagar.Enabled := BtEditar.Enabled; BtSair.Enabled := BtNovo.Enabled;
Botões Novo e Editar:
DbEdtNomeGrupo.Enabled := True; DbCbTipoGrupo.Enabled := True; DbGridGrupos.Enabled := False; DbEdtNomeGrupo.SetFocus;
Botões Salvar e Cancelar:
DbEdtNomeGrupo.Enabled := False; DbCbTipoGrupo.Enabled := False; DbGridGrupos.Enabled := True;
OnChange TEdtDbNome:
BtSalvar.Enabled := DbEdtNomeGrupo.Enabled and (DbEdtNomeGrupo.Text <> ´´) and (DbEdtTipoGrupo.Text <> ´´);
OnChange TDbEdtTipoGrupo
BtSalvar.Enabled := (DbEdtTipoGrupo.Text <> ´´) and (DbEdtNomeGrupo.Text <> ´´);
OnChange TDbComboBox.
BtSalvar.Enabled := DbCbTipoGrupo.Enabled and (DbCbTipoGrupo.Text <> ´´) and (DbEdtNomeGrupo.Text <> ´´);
GOSTEI 0
Aersoftware
22/08/2005
Emerson, eu colocaria esses códigos no lugar dos que postei acima? Se for isso mesmo, realmente irá diminuir consideravelmente as linhas do código fonte..
Allan Elias Ramos :wink:
Allan Elias Ramos :wink:
GOSTEI 0
Aersoftware
22/08/2005
Amigo, fiz exatamente assim como vc indicou. A única diferença é que meu DataSource ta num DataModule, então tive que colocar antes do nome dos botões o nome do formulário.. ficou assim:
StateChange do DataSource:
Procedure NovoEditar:
Procedure SalvarCancelar:
NomeGrupoOnChange:
TipoGrupoOnChange
ComboTipoGrupoOnChange
Aí quando vou rodar ele, da o seguinte erro:
O que pode ser isso? Eu só fiz essas mudanças que vc indicou.
Abraços.
Allan Elias Ramos :wink:
StateChange do DataSource:
FrmGrupos.BtNovo.Enabled := DsGrupos.DataSet.Active and not (DsGrupos.DataSet.State in [dsEdit, dsInsert]); FrmGrupos.BtSalvar.Enabled := DsGrupos.DataSet.State in [dsEdit, dsInsert]; FrmGrupos.BtEditar.Enabled := FrmGrupos.BtNovo.Enabled and not DsGrupos.DataSet.IsEmpty; FrmGrupos.BtApagar.Enabled := FrmGrupos.BtEditar.Enabled; FrmGrupos.BtSair.Enabled := FrmGrupos.BtNovo.Enabled;
Procedure NovoEditar:
DbEdtNomeGrupo.Enabled := True; DbCbTipoGrupo.Enabled := True; DbGridGrupos.Enabled := False; DbEdtNomeGrupo.SetFocus;
Procedure SalvarCancelar:
DbEdtNomeGrupo.Enabled := False; DbCbTipoGrupo.Enabled := False; DbGridGrupos.Enabled := True;
NomeGrupoOnChange:
BtSalvar.Enabled := DbEdtNomeGrupo.Enabled and (DbEdtNomeGrupo.Text <> ´´) and (DbEdtTipoGrupo.Text <> ´´);
TipoGrupoOnChange
BtSalvar.Enabled := (DbEdtTipoGrupo.Text <> ´´) and (DbEdtNomeGrupo.Text <> ´´);
ComboTipoGrupoOnChange
BtSalvar.Enabled := DbCbTipoGrupo.Enabled and (DbCbTipoGrupo.Text <> ´´) and (DbEdtNomeGrupo.Text <> ´´);
Aí quando vou rodar ele, da o seguinte erro:
Project Projeto.exe raised exception class EAccessViolation with message ´Access violation at address 004D65B0 in module ´Projeto.exe´. Read of address 00000330´.
O que pode ser isso? Eu só fiz essas mudanças que vc indicou.
Abraços.
Allan Elias Ramos :wink:
GOSTEI 0
Emerson Nascimento
22/08/2005
deve estar acontecendo por conta do datasource estar num datamodule.
faça firerente:
recorte a procedure do OnStateChange do datamodule e cole no seu form.
aí, no onactivate do seu form, faça:
datamadule.datasource.onactivate := procedurequevcmoveuparaoseuform;
e, no ondeactivate e ondestroy do seu form:
datamadule.datasource.onactivate := nil;
(qdo colocar a procedure no form, pode tirar a referência ao form das linhas da procedure)
faça firerente:
recorte a procedure do OnStateChange do datamodule e cole no seu form.
aí, no onactivate do seu form, faça:
datamadule.datasource.onactivate := procedurequevcmoveuparaoseuform;
e, no ondeactivate e ondestroy do seu form:
datamadule.datasource.onactivate := nil;
(qdo colocar a procedure no form, pode tirar a referência ao form das linhas da procedure)
GOSTEI 0
Aersoftware
22/08/2005
Outro erro: Coloquei o código numa procedure chamada ControlaBotoes, assim:
E essas duas no OnDeactivate e no OnDestroy:
No OnActivate, quando fui botar a chamada indicada, ele não me lista o evento OnActivate do DataSource. Então botei assim:
Já que era no OnStateChange que o código tava antes. Mas na hora de compilar, ele seleciona esse revista em vermelho e dá o seguinte erro:
Aí não compila.
Allan Elias Ramos :cry:
procedure TFrmGrupos.ControlaBotoes; begin BtNovo.Enabled := DmDados.DsGrupos.DataSet.Active and not (DmDados.DsGrupos.DataSet.State in [dsEdit, dsInsert]); BtSalvar.Enabled := DmDados.DsGrupos.DataSet.State in [dsEdit, dsInsert]; BtEditar.Enabled := FrmGrupos.BtNovo.Enabled and not DmDados.DsGrupos.DataSet.IsEmpty; BtApagar.Enabled := BtEditar.Enabled; BtSair.Enabled := BtNovo.Enabled; end;
E essas duas no OnDeactivate e no OnDestroy:
procedure TFrmGrupos.FormDeactivate(Sender: TObject); begin DmDados.DsGrupos.OnStateChange := nil; end; procedure TFrmGrupos.FormDestroy(Sender: TObject); begin DmDados.DsGrupos.OnStateChange := nil; end;
No OnActivate, quando fui botar a chamada indicada, ele não me lista o evento OnActivate do DataSource. Então botei assim:
DmDados.DsGrupos.OnStateChange := ControlaBotoes;
Já que era no OnStateChange que o código tava antes. Mas na hora de compilar, ele seleciona esse revista em vermelho e dá o seguinte erro:
[Error] UGrupos.pas(125): E2009 Incompatible types: ´Parameter lists differ´
[Fatal Error] ProjHqmx.dpr(7): F2063 Could not compile used unit ´UGrupos.pas´
Aí não compila.
Allan Elias Ramos :cry:
GOSTEI 0
Emerson Nascimento
22/08/2005
por isso eu disse pra vc recortar a funcao como estava no datamodule.
o evento OnStateChange requer uma função com certas caracteríscas. no caso, a lista de parâmetros da sua função tem de ser idêntica aquela que estava no datamodule.
o evento OnStateChange requer uma função com certas caracteríscas. no caso, a lista de parâmetros da sua função tem de ser idêntica aquela que estava no datamodule.
procedure TFrmGrupos.ControlaBotoes(Sender: TObject); begin with DmDados.DsGrupos do begin BtNovo.Enabled := DataSet.Active and not (DataSet.State in [dsEdit, dsInsert]); BtSalvar.Enabled := DataSet.State in [dsEdit, dsInsert]; BtEditar.Enabled := BtNovo.Enabled and not DataSet.IsEmpty; BtApagar.Enabled := BtEditar.Enabled; BtSair.Enabled := BtNovo.Enabled; end; end;
GOSTEI 0