DbEdit.SetFocus = Access Violation

Delphi

07/11/2005

Coloquei a função dbEdit2.SETFOCUS, no ONCHANGE da DBEDIT1.
Mas ele gera um access violation.
Não estou conseguinmdo saber o por que.

Agradeço a Ajuda.
Obrigado;


Buck

Buck

Curtidas 0

Respostas

Rafael Santana

Rafael Santana

07/11/2005

os dois Edits estão no mesmo form???


GOSTEI 0
Wiltonfenix

Wiltonfenix

07/11/2005

Tem certeza que o dbedit para onde você está enviando o foco existe?


GOSTEI 0
Martins

Martins

07/11/2005

Coloquei a função dbEdit2.SETFOCUS, no ONCHANGE da DBEDIT1. Mas ele gera um access violation. Não estou conseguinmdo saber o por que. Agradeço a Ajuda. Obrigado;


Verifique se esse edit está no mesmo local, pq caso ele esteja em outro form (pouco provavel), caso vc esteja usando PageControl ou se esse edit estiver invisivel, esse erro será apresentado.

verifique.

Boa sorte!!!


GOSTEI 0
Martins

Martins

07/11/2005

Tem certeza que o dbedit para onde você está enviando o foco existe?


Acredito q deva existir esse Edit2, caso contrário o código dele não compilaria, tá estranho isso, pq mesmo q estive invisivel para o controle o erro apresentado deveria ser outro, e não esse de violação de acesso.

Precisamos de mais detalhes para avaliar o paciente, hehehe!!!


GOSTEI 0
Wiltonfenix

Wiltonfenix

07/11/2005

Quando eu disse ´existe´, entenda-se: criado, instanciado,...

Porque como o Martins disse, ele pode estar em outro Form ou outro componente que não foi criado.


GOSTEI 0
Buck

Buck

07/11/2005

Os dbEdits estão no mesmo Form, estão Visiveis, e Ativadas.
Mas a função está no OnChange da dbEdit1, pois há o Form da ´Consulta´ em cima. Ao Clicar no Grid do Form ´Consulta´, ele volta com o Nome na dbEDIT1.
É aí que o SetFocus tá dando pau...


GOSTEI 0
Wiltonfenix

Wiltonfenix

07/11/2005

Já tentou form_do_edit.dbEdit2.Setfocus ?


GOSTEI 0
Buck

Buck

07/11/2005

sim, ja tentei...


GOSTEI 0
Anfm

Anfm

07/11/2005

Esse erro está acontecendo qdo vc cria o form??


GOSTEI 0
Buck

Buck

07/11/2005

sim, mas aí ´cannot focus a invisible or disabled window´.
mas se colocar ´if form.showing = true then´, aí ele roda, mas dá aquele erro de access violation depois.


GOSTEI 0
Anfm

Anfm

07/11/2005

pq vc está usando o evento onchange? Sempre q o usuário digitar uma letra vc quer q ele vá para o DBEdit2??? Não seria melhor vc colocar isto qdo o usuário pressionar enter?


GOSTEI 0
Martins

Martins

07/11/2005

Os dbEdits estão no mesmo Form, estão Visiveis, e Ativadas. Mas a função está no OnChange da dbEdit1, pois há o Form da ´Consulta´ em cima. Ao Clicar no Grid do Form ´Consulta´, ele volta com o Nome na dbEDIT1. É aí que o SetFocus tá dando pau...


Vc chama o form de consulta de onde? vamos supor.

form1 -> o q tem seus dbedits
form2 -> o q tem o dbgrid

vc chama o form2 através do form1? Se for, é só vc colocar assim.
  Form2.ShowModal;
  DBEdit1.Text := Form2.DBGrid1.Fields[0].AsString;
Assim quando vc fechar o form de consulta ele trará o registro setado no dbgrid, sendo [b:6d40083ae8]0[/b:6d40083ae8] o primeiro campo, vc pode alterar para sua necessidade.

se vc estiver selecionando o campo com OnDbClick no grid, para q ele retorne para form1 com o valor e automaticamente vá para DbEdit2. tente assim
  Form1.Edit1.Text:= DbGrid1.Fields[0].AsString;
  close;


Ou então pode o código q vc tá usando, fica bem mais fácil.


GOSTEI 0
Martins

Martins

07/11/2005

sim, mas aí ´cannot focus a invisible or disabled window´. mas se colocar ´if form.showing = true then´, aí ele roda, mas dá aquele erro de access violation depois.


Como vc está fazendo essa chamada dos forms, e carregando o valor nos DbEdit´s, entendo q o evento no OnChage é para ser disparado ao receber um valor, valor este q virá da consulta para DbEdit1, recebendo esse valor vá para DbEdit2, mesmo assim não sei se é bom negócio deixar desse jeito, pq vc poderia setar isso condicionalmente, mas vamos ao erro aos forms. Se vc puder postar o código aqui fica mais fácil de chagarmos a uma solução caso vc ainda não tenha encontrado.


GOSTEI 0
Buck

Buck

07/11/2005

fica meio dificil de postar os codigos, pois estão em outro pc, mas vamos lá.

no form1, ficam as DbEdits.
no Form2, fica o dbGrid.

onEnter da dbEdit1, ele chama o Form2 (consulta)

onCellClick do dbGrid, ele fecha o Form2 e preenche a dbEdit1.

OnChange dbEdit1 (Form1)
dbEdit2.SetFocus;

mas se colocar assim no ONChange ele nem roda,

então:
if form1.showing = true then
OnChange dbEdit1 (Form1)
dbEdit2.SetFocus;

........
é isso pessoal,
muito estranho esse erro.
Agradeço a cooperação de vocês...
Abraço !


GOSTEI 0
Martins

Martins

07/11/2005

fica meio dificil de postar os codigos, pois estão em outro pc, mas vamos lá. no form1, ficam as DbEdits. no Form2, fica o dbGrid. onEnter da dbEdit1, ele chama o Form2 (consulta) onCellClick do dbGrid, ele fecha o Form2 e preenche a dbEdit1. OnChange dbEdit1 (Form1) dbEdit2.SetFocus; mas se colocar assim no ONChange ele nem roda, então: if form1.showing = true then OnChange dbEdit1 (Form1) dbEdit2.SetFocus; ........ é isso pessoal, muito estranho esse erro. Agradeço a cooperação de vocês... Abraço !


Vc viu e testou o q eu postei, pq vc tem os dois forms do jeito q eu imaginei.

veja novamente.

form1 -> o q tem seus dbedits
form2 -> o q tem o dbgrid

Código:
procedure TForm1.DBEdit1Enter(Sender: TObject);
begin
  Form2.ShowModal;
  DBEdit1.Text:= Form2.DBGrid1.Fields[0].AsString;
  DBEdit2.Text:= Form2.DBGrid1.Fields[1].AsString;
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
  DBEdit2.SetFocus;
end;

Assim quando vc fechar o form de consulta ele trará o registro setado no dbgrid, sendo 0 o primeiro campo, vc pode alterar para sua necessidade.

Ao clicar em OnCellClick, será disparado o close, pq o registro é setado
no momento em q vc clicar sobre a célula.
  close; 


Qualquer coisa, te mando um exemplo por e-mail, posta aí teu e-mail q eu mando.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

07/11/2005

faça algo assim:

OnEnterDoDBEdit1
Application.CreateForm(TForm2,Form2);
Form2.ShowModal;
DBEdit1.Field.Value := Form2.ItemClicado;
FreeAndNil(Form2);
DBEdit2.SetFocus;

e não use mais o OnChange


GOSTEI 0
Martins

Martins

07/11/2005

faça algo assim: OnEnterDoDBEdit1 Application.CreateForm(TForm2,Form2); Form2.ShowModal; DBEdit1.Field.Value := Form2.ItemClicado; FreeAndNil(Form2); DBEdit2.SetFocus; e não use mais o OnChange


Mais ou menos assim [b:492c90fff5]emerson.en[/b:492c90fff5]

  Application.CreateForm(TForm2, Form2);
  Form2.ShowModal;
  DBEdit1.Text:= Form2.DBGrid1.Fields[0].AsString;
  DBEdit2.Text:= Form2.DBGrid1.Fields[1].AsString;
  FreeAndNil(Form2);
  DBEdit2.SetFocus;



GOSTEI 0
Buck

Buck

07/11/2005

Pessoal, tentei o FREEANDNIL, mas gerou a mesma excessão...


GOSTEI 0
Cabelo

Cabelo

07/11/2005

Pq vc não usa o evento OnShow do form1 para dar o setfocus no dbedit2????????


assim funciona..


GOSTEI 0
Martins

Martins

07/11/2005

Pessoal, tentei o FREEANDNIL, mas gerou a mesma excessão...


Cara isso aí tá complicado, dá pra explicar com mais detalhes o q vc tá fazendo, pq nós estamos cegos, e aí fica complicado, já tentamos n soluções e nada. Queremos ajudar mais precisamos de detalhes, de código.


GOSTEI 0
Buck

Buck

07/11/2005

FORM1 - FrmVenda_Atac
OnEnter - DbEdit1

if DBComboBox1.Text = ´´ then
begin
messageDlg(´Selecione o Tipo da Venda´, mtError, [mbOk],0);
DBComboBox1.SetFocus;
end
else
if (dmVendas.tblVenda_Atac.State = dsEdit) or (dmVendas.tblVenda_Atac.State = dsInsert) then
dmVendas.tblVenda_Atac.Post;

frmCons_Produto.showmodal;

FORM2 - frmCons_Produto

if frmVenda_Atac.Showing = true then
begin
if (dmVendas.tblVenda_Prod_Atac.State = dsInsert) or (dmVendas.tblVenda_Prod_Atac.State = dsEdit) then
begin
close;
dmVendas.tblVenda_Prod_AtacProduto.Value := dmVendas.tblProdutoNome.Value;

end
else
begin
close;
dmVendas.tblVenda_Prod_Atac.Insert;
dmVendas.tblVenda_Prod_AtacProduto.Value := dmVendas.tblProdutoNome.Value;
frmVenda_Atac.dbEdit2.setFotcus;

end
end
else
frmCad_Produto.showmodal;


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

07/11/2005

FORM1 - FrmVenda_Atac 
OnEnter - DbEdit1 

  if DBComboBox1.Text = ´´ then 
  begin 
    messageDlg(´Selecione o Tipo da Venda´, mtError, [mbOk],0); 
    DBComboBox1.SetFocus; 
  end 
  else 
  if (dmVendas.tblVenda_Atac.State = dsEdit) or (dmVendas.tblVenda_Atac.State = dsInsert) then 
    dmVendas.tblVenda_Atac.Post; 

  frmCons_Produto.showmodal; 
  FORM2 - frmCons_Produto 

  if frmVenda_Atac.Showing = true then 
  begin 
    if (dmVendas.tblVenda_Prod_Atac.State = dsInsert) or (dmVendas.tblVenda_Prod_Atac.State = dsEdit) then 
    begin 
      close; 
      dmVendas.tblVenda_Prod_AtacProduto.Value := dmVendas.tblProdutoNome.Value; 
    end 
    else 
    begin 
      close; 
      dmVendas.tblVenda_Prod_Atac.Insert; 
      dmVendas.tblVenda_Prod_AtacProduto.Value := dmVendas.tblProdutoNome.Value; 
      frmVenda_Atac.dbEdit2.setFotcus; 
    end 
  end 
  else 
    frmCad_Produto.showmodal;


creio que o erro esteja nos CLOSE mal utilizados (ou utilizados em momento impróprio)

  if frmVenda_Atac.Showing = true then 
  begin 
    if (dmVendas.tblVenda_Prod_Atac.State = dsInsert) or (dmVendas.tblVenda_Prod_Atac.State = dsEdit) then 
    begin 
      close; /**** ESSE CLOSE ESTÁ FECHANDO O frmVenda_Atac ****/
      dmVendas.tblVenda_Prod_AtacProduto.Value := dmVendas.tblProdutoNome.Value; 
    end 
    else 
    begin 
      close; /**** ESSE CLOSE ESTÁ FECHANDO O frmVenda_Atac ****/
      dmVendas.tblVenda_Prod_Atac.Insert; 
      dmVendas.tblVenda_Prod_AtacProduto.Value := dmVendas.tblProdutoNome.Value; 
      frmVenda_Atac.dbEdit2.setFotcus; /**** frmVenda_Atac ESTÁ FECHADO ****/
    end 
  end 
  else 
    frmCad_Produto.showmodal;



GOSTEI 0
Buck

Buck

07/11/2005

não não.
O CLOSE está fechando o ´frmCons_Venda_Atac´


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

07/11/2005

esse código (OnEnter) está num terceiro form?


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

07/11/2005

então tente assim:

FORM1 - FrmVenda_Atac 
OnEnter - DbEdit1 

  if DBComboBox1.Text = ´´ then 
  begin 
    messageDlg(´Selecione o Tipo da Venda´, mtError, [mbOk],0); 
    DBComboBox1.SetFocus; 
  end 
  else 
  if (dmVendas.tblVenda_Atac.State = dsEdit) or (dmVendas.tblVenda_Atac.State = dsInsert) then 
    dmVendas.tblVenda_Atac.Post; 

  frmCons_Produto.showmodal; 
  FORM2 - frmCons_Produto 

  if frmVenda_Atac.Showing = true then 
  begin 
    if (dmVendas.tblVenda_Prod_Atac.State = dsInsert) or (dmVendas.tblVenda_Prod_Atac.State = dsEdit) then 
    begin 
      close; 
      dmVendas.tblVenda_Prod_AtacProduto.Value := dmVendas.tblProdutoNome.Value; 
    end 
    else 
    begin 
      close;
      frmVenda_Atac.SetFocus; /*** PÕE O frmVenda_Atac EM FOCO ***/
      dmVendas.tblVenda_Prod_Atac.Insert; 
      dmVendas.tblVenda_Prod_AtacProduto.Value := dmVendas.tblProdutoNome.Value; 
      frmVenda_Atac.dbEdit2.setFotcus; 
    end 
  end 
  else 
    frmCad_Produto.showmodal;



GOSTEI 0
Buck

Buck

07/11/2005

já tinha tentado isso tb...
o mesmo erro -- Access Violation


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

07/11/2005

rapaz... complicado...

se você quiser mande seu projeto para emerson.en@gmail.com

porque eu não consegui simular esse erro.


GOSTEI 0
Vitor Rubio

Vitor Rubio

07/11/2005

algumas perguntas:
você debugou o programa passo a passo para ver em qual linha que ocorre o access violation?

você dá free ou release em alguma form quando fecha?

os componentes de acesso a dados, tipo datasets e datasources onde esses dbedits estão ligados, ficam na mesma form q o dbedits, na outra form ou num datamodule?

tudo que vc está acessando está devidamente criado?

se o access violation for no endereço 00000000... ou FFFFFFF.... quer dizer que você usou uma variavel de uma classe qualquer sem criar ou instanciar. ou a destruiu sem ela estar criada.

se o endereço for diferente disso, quer dizer que você está tentando acessar um objeto que existia e estava instanciado, mas você o destruiu antes do tempo, sem saber que precisaria dele depois.


espero ter ajudado...


GOSTEI 0
Martins

Martins

07/11/2005

por favor colega, com base nos códigos postados aqui destaque a posição apartir da qual o erro é disparado dentro do seu programa.

FORM1 - FrmVenda_Atac 

OnEnter - DbEdit1 

if DBComboBox1.Text = ´´ then 
begin 
messageDlg(´Selecione o Tipo da Venda´, mtError, [mbOk],0); 
DBComboBox1.SetFocus; 
end 
else 
if (dmVendas.tblVenda_Atac.State = dsEdit) or (dmVendas.tblVenda_Atac.State = dsInsert) then 

dmVendas.tblVenda_Atac.Post; // Salva a tabela Venda_atacado

frmCons_Produto.showmodal; // Abri o form2

FORM2 - frmCons_Produto 

if frmVenda_Atac.Showing = true then 
begin 
if (dmVendas.tblVenda_Prod_Atac.State = dsInsert) or (dmVendas.tblVenda_Prod_Atac.State = dsEdit) then 
begin 

close; //Esse close aqui vai fechar esse form2

dmVendas.tblVenda_Prod_AtacProduto.Value := dmVendas.tblProdutoNome.Value; 

end 

else 

begin 
close;  //Fecha aqui tb ... Form1.

dmVendas.tblVenda_Prod_Atac.Insert; 
dmVendas.tblVenda_Prod_AtacProduto.Value := dmVendas.tblProdutoNome.Value; 
frmVenda_Atac.dbEdit2.setFotcus;  //vc não pode ir para cá, pq vc fechou. 

end 
end 
else 
frmCad_Produto.showmodal;



Reveja estes close, esse código precisa ser refeito.


GOSTEI 0
Vitor Rubio

Vitor Rubio

07/11/2005

por favor colega, com base nos códigos postados aqui destaque a posição apartir da qual o erro é disparado dentro do seu programa.
 
...
else 

begin 
close;  //Fecha aqui tb ... Form1.

dmVendas.tblVenda_Prod_Atac.Insert; 
dmVendas.tblVenda_Prod_AtacProduto.Value := dmVendas.tblProdutoNome.Value; 
frmVenda_Atac.dbEdit2.setFotcus;  //vc não pode ir para cá, pq vc fechou. 

end 
end 
else 
frmCad_Produto.showmodal;
Reveja estes close, esse código precisa ser refeito.


Martins, se ele está numa procedure da form2 e não está usando with form1 ou form1.close, esse close que você citou vai fechar a propria form2 q ele está trabalhando mesmo, a form 1 continua aberta.


GOSTEI 0
Buck

Buck

07/11/2005

não, Martins, os ´closes´ estão em hipoteses diferentes, note o ELSE.

o CLOSE fecha apenas o FORM2 (Consulta)


GOSTEI 0
Martins

Martins

07/11/2005

[quote:290e68463e=´vitor^_^´]
por favor colega, com base nos códigos postados aqui destaque a posição apartir da qual o erro é disparado dentro do seu programa.
 
...
else 

begin 
close;  //Fecha aqui tb ... Form1.

dmVendas.tblVenda_Prod_Atac.Insert; 
dmVendas.tblVenda_Prod_AtacProduto.Value := dmVendas.tblProdutoNome.Value; 
frmVenda_Atac.dbEdit2.setFotcus;  //vc não pode ir para cá, pq vc fechou. 

end 
end 
else 
frmCad_Produto.showmodal;
Reveja estes close, esse código precisa ser refeito.


Martins, se ele está numa procedure da form2 e não está usando with form1 ou form1.close, esse close que você citou vai fechar a propria form2 q ele está trabalhando mesmo, a form 1 continua aberta.[/quote:290e68463e]

:shock:
:lol:

Desculpem pessoal, foi bobeira mesmo.

Continuamos com o problema né?

Mas vamos resolver.


GOSTEI 0
Martins

Martins

07/11/2005

Fiz um exemplo aqui, veja se pode ser adaptado para sua necessiadade.

[b:828bb78e4f]Form2 - Vendas;
Form3 - Consulta Cliente;
[/b:828bb78e4f]

[b:828bb78e4f][i:828bb78e4f]Código no Form2[/i:828bb78e4f][/b:828bb78e4f]
//Evento no OnEnter do DbEdit2
procedure TForm2.DBEdit2Enter(Sender: TObject);
begin
 if DBComboBox1.Text = ´´ then //Se não for selecionado nada no DbComboBox mostre a mensagem.
  begin
    MessageDlg(´Selecione o tipo da venda por favor!!!´, mtInformation, [mbOK], 0);
    DBComboBox1.SetFocus; //Devolva o foco para DbComboBox
  end

  else  //Caso contrário

    if (AdoTable1.State in [dsInsert, dsEdit]) then //Se a tabela estiver em modo de inserção ou edição faça
      begin
        Form3.ShowModal;  //Mostre o form de Consulta - FORM3

        AdoTable1.FieldByName(´VendorName´).AsString := Form3.Table1.FieldByName(´FIRST_NAME´).AsString; 

        AdoTable1.FieldByName(´Address1´).AsString := Form3.Table1.FieldbyName(´ADDRESS_1´).AsString;

        DbEdit3.SetFocus;
      end;
end;


[b:828bb78e4f]No form3 - Consulta Clientes[/b:828bb78e4f]
procedure TForm3.Button1Click(Sender: TObject);
begin
   Close;
end;


Cara com isso aí, eu entro na venda, checo se foi preenchido o tipo da venda, caso contrário, me volta lá para o DbComboBox para q eu preencha, quando eu entro no DbEdit, ele me manda para o Form3 (Consulta clientes) onde eu seleciono o cliente e fecho o form, poderia ter colocado o close até no OnCellClick.

E não tenho problema nenhum.

Veja se vc pode adaptar as suas necessidades.

Ou então eu ainda não entendi o q vc quer fazer, mas quero ajudar, :)

Boa Sorte


GOSTEI 0
POSTAR