Chamando um Form de Pesquisa- DBEDIT

Delphi

Firebird

FireDAC

19/10/2020

Olá boa noite!

Há alguns dias estou com um probleminha, espero que me ajudem como sempre...


Seguinte: Tenho Form1(Cadastro Produto) e Form2(Consulta Categoria Produto)

Ao digitar qualquer caractere no dbeditcategoria do form1 a aplicação chama o form2 de consulta, até então ok.

No evento onkeypress (Tecla Enter) da minha dbgrid do form 2, no código eu mando que assim que eu selecionar a categoria desejada o form2 fecha, e em seguida o dbeditcategoria do form1 recebe os dados.

Codigo no evento onkeypress dbgrid:

procedure TFrmConsulFabricante.DBGridConsulIndustriaKeyPress(Sender: TObject;
var Key: Char);
begin
if key = #13 then
begin
FrmCadFabricante.DBEdit1.Text := FrmCadFabricante.FDQryFabricante.FieldByName('ID').AsString;
FrmCadFabricante.DBEdit2.Text := FrmCadFabricante.FDQryFabricante.FieldByName('DESCRICAO').AsString;
FrmCadFabricante.DBEdit3.Text := FrmCadFabricante.FDQryFabricante.FieldByName('DTA_CADASTRO').AsString;
FrmConsulFabricante.Close;
end;

O problema e que o form1 recebe os dados, mais o primeiro caractere digitado continua no dbedit. Ex: CCATEGORIATESTE

Código no evento onkeypress do dbedit:

procedure TFrmCadProdutos.DBEditDescCategoriaKeyPress(Sender: TObject;
var Key: Char);
begin
if AnsiUpperCase(Key)[1] in ['0'..'9','A'..'Z'] then
begin
Application.CreateForm(TFrmConsulCategoria,FrmConsulCategoria);
with FrmConsulCategoria.EdtConsultaCategoria do
begin
Text := key;
end;
FrmConsulCategoria.ShowModal;
end;
end;

Agradeço!
Jefferson

Jefferson

Curtidas 0

Respostas

Emerson Nascimento

Emerson Nascimento

19/10/2020

Quem sou eu pra dizer qual é a forma certa para desenvolver um sistema, mas dando minha sugestão mesmo não solicitada...

Esta não é a melhor forma de fazer isto.
Normalmente este tipo de procedimento deve gerar um retorno, e quem chamou é que decide o que fazer com o retorno.
No teu caso, a tela de pesquisa está manipulando a tela que a chamou, e isto não é boa prática.

Além do mais, a tela de pesquisa deve ter seu próprio dataset, não compartilhado com mais nenhum form.

Assim...
Crie uma unit para as classes do sistema. Essa unit terá, entre outras, a classe de retorno de pesquisas (neste caso é apenas um record).
Por exemplo:
unit ClassesSistema;

interface

type
  // classe para retorno de pesquisas (supondo que sempre retornará ID, Descrição e Data de Cadastro)
  TRetornoPesquisa = record
    ID: integer;
    Descricao: string;
    DataCadastro: TDateTime;
  end;

implementation

end.


No teu form de pesquisa, crie, na seção public do form, a seguinte class function (class function e class procedure ficam disponíveis mesmo antes de instanciar o form):
type
  TFrmConsulCategoria = class(TForm)
    []
  private
    []
  public
    class function PesquisaCategoriaProduto(ValorInicial: string = ''): TRetornoPesquisa;
  end;


a implementação será assim:
class function TFrmConsulCategoria.PesquisaCategoriaProduto(
 ValorInicial: string = ''): TRetornoPesquisa;
var
  FrmPesquisa: TForm6;
begin
  Result.ID := -1;
  Result.Descricao := '';
  Result.DataCadastro := nil;

  Application.CreateForm(TFrmConsulCategoria, FrmPesquisa);
  FrmPesquisa.EdtConsultaCategoria.Text := Categoria;

  // se o usuário confirmou a tela de pesquisa
  if FrmPesquisa.ShowModal = mrOk then
  begin
    Result.ID := FrmPesquisa.DatasetPesquisa.FieldByName('ID').AsInteger;
    Result.Descricao := FrmPesquisa.DatasetPesquisa.FieldByName('Descricao').AsString;
    Result.DataCadastro := FrmPesquisa.DatasetPesquisa.FieldByName('DtaCadastro').AsDateTime;
  end;

  FreeAndNil(FrmPesquisa);
end;
lembrando que o form de consulta deve ter seu próprio dataset. faça isto para manter os dados independentes entre os forms.

agora é necessário 'consumir' essa pesquisa.
seguindo o que você passou:
procedure TFrmCadProdutos.DBEditDescCategoriaKeyPress(Sender: TObject;
var Key: Char);
var
  Retorno: TRetornoPesquisa;
begin
  if AnsiUpperCase(Key)[1] in ['0'..'9','A'..'Z'] then
  begin
    Retorno := PesquisaCategoriaProduto( key ); // abre a tela de pesquisa. é assim mesmo. não precisa criar o form de pesquisa.
    if Retorno.ID > 0 then // se houve retorno, faz as atribuições
    begin
      FrmCadFabricante.DBEdit1.Text := Retorno.ID;
      FrmCadFabricante.DBEdit2.Text := Retorno.Descricao;
      FrmCadFabricante.DBEdit3.Text := Retorno.DataCadastro;
      key := #0; // anula o que foi digitado pelo usuário
    end;
  end;
end;

será necessário incluir a unit ClassesSistema em todos as units que utilizarem a pesquisa (inclusive na própria unit de pesquisa).
a unit de pesquisa não precisa mais ter na sua uses as units que a utilizam. no caso acredito que você tenha a unit de cadastro na uses da unit de pesquisa. não é necessário.

dessa forma a tela de pesquisa de categoria de produto se torna auto suficiente pode ser chamada de qualquer ponto do sistema, porque têm seu próprio dataset e porque o tratamento do retorno será feito por quem a chamou, não por ela mesma.

agora, se não quiser seguir nada do que foi dito, basta fazer:
procedure TFrmCadProdutos.DBEditDescCategoriaKeyPress(Sender: TObject;
var Key: Char);
begin
  if AnsiUpperCase(Key)[1] in ['0'..'9','A'..'Z'] then
  begin
    Application.CreateForm(TFrmConsulCategoria,FrmConsulCategoria);
    FrmConsulCategoria.EdtConsultaCategoria.Text := key;
    FrmConsulCategoria.ShowModal;

    // anula o que o usuário digitou, mas precisa de tratamento,
    // porque a tela de consulta pode ter sido cancelada
    key := #0;
  end;
end;

é possível que haja algum erro de sintaxe. estou sem Delphi, então fiz tudo no bloco de notas.
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

19/10/2020

Quem sou eu pra dizer qual é a forma certa para desenvolver um sistema, mas dando minha sugestão mesmo não solicitada...

Esta não é a melhor forma de fazer isto.
Normalmente este tipo de procedimento deve gerar um retorno, e quem chamou é que decide o que fazer com o retorno.
No teu caso, a tela de pesquisa está manipulando a tela que a chamou, e isto não é boa prática.

Além do mais, a tela de pesquisa deve ter seu próprio dataset, não compartilhado com mais nenhum form.

Assim...
Crie uma unit para as classes do sistema. Essa unit terá, entre outras, a classe de retorno de pesquisas (neste caso é apenas um record).
Por exemplo:
unit ClassesSistema;

interface

type
  // classe para retorno de pesquisas (supondo que sempre retornará ID, Descrição e Data de Cadastro)
  TRetornoPesquisa = record
    ID: integer;
    Descricao: string;
    DataCadastro: TDateTime;
  end;

implementation

end.


No teu form de pesquisa, crie, na seção public do form, a seguinte class function (class function e class procedure ficam disponíveis mesmo antes de instanciar o form):
type
  TFrmConsulCategoria = class(TForm)
    []
  private
    []
  public
    class function PesquisaCategoriaProduto(ValorInicial: string = ''): TRetornoPesquisa;
  end;


a implementação será assim:
class function TFrmConsulCategoria.PesquisaCategoriaProduto(
 ValorInicial: string = ''): TRetornoPesquisa;
var
  FrmPesquisa: TFrmConsulCategoria;
begin
  Result.ID := -1;
  Result.Descricao := '';
  Result.DataCadastro := nil;

  Application.CreateForm(TFrmConsulCategoria, FrmPesquisa);
  FrmPesquisa.EdtConsultaCategoria.Text := Categoria;

  // se o usuário confirmou a tela de pesquisa
  if FrmPesquisa.ShowModal = mrOk then
  begin
    Result.ID := FrmPesquisa.DatasetPesquisa.FieldByName('ID').AsInteger;
    Result.Descricao := FrmPesquisa.DatasetPesquisa.FieldByName('Descricao').AsString;
    Result.DataCadastro := FrmPesquisa.DatasetPesquisa.FieldByName('DtaCadastro').AsDateTime;
  end;

  FreeAndNil(FrmPesquisa);
end;
lembrando que o form de consulta deve ter seu próprio dataset. faça isto para manter os dados independentes entre os forms.

agora é necessário 'consumir' essa pesquisa.
seguindo o que você passou:
procedure TFrmCadProdutos.DBEditDescCategoriaKeyPress(Sender: TObject;
var Key: Char);
var
  Retorno: TRetornoPesquisa;
begin
  if AnsiUpperCase(Key)[1] in ['0'..'9','A'..'Z'] then
  begin
    Retorno := PesquisaCategoriaProduto( key ); // abre a tela de pesquisa. é assim mesmo. não precisa criar o form de pesquisa.
    if Retorno.ID > 0 then // se houve retorno, faz as atribuições
    begin
      FrmCadFabricante.DBEdit1.Text := Retorno.ID;
      FrmCadFabricante.DBEdit2.Text := Retorno.Descricao;
      FrmCadFabricante.DBEdit3.Text := Retorno.DataCadastro;
      key := #0; // anula o que foi digitado pelo usuário
    end;
  end;
end;

será necessário incluir a unit ClassesSistema em todos as units que utilizarem a pesquisa (inclusive na própria unit de pesquisa).
a unit de pesquisa não precisa mais ter na sua uses as units que a utilizam. no caso acredito que você tenha a unit de cadastro na uses da unit de pesquisa. não é necessário.

dessa forma a tela de pesquisa de categoria de produto se torna auto suficiente pode ser chamada de qualquer ponto do sistema, porque têm seu próprio dataset e porque o tratamento do retorno será feito por quem a chamou, não por ela mesma.

agora, se não quiser seguir nada do que foi dito, basta fazer:
procedure TFrmCadProdutos.DBEditDescCategoriaKeyPress(Sender: TObject;
var Key: Char);
begin
  if AnsiUpperCase(Key)[1] in ['0'..'9','A'..'Z'] then
  begin
    Application.CreateForm(TFrmConsulCategoria,FrmConsulCategoria);
    FrmConsulCategoria.EdtConsultaCategoria.Text := key;
    FrmConsulCategoria.ShowModal;

    // anula o que o usuário digitou, mas precisa de tratamento,
    // porque a tela de consulta pode ter sido cancelada
    key := #0;
  end;
end;

é possível que haja algum erro de sintaxe. estou sem Delphi, então fiz tudo no bloco de notas.
GOSTEI 0
Jefferson

Jefferson

19/10/2020

Obrigado!! Vou tentar aqui.
GOSTEI 0
POSTAR