• 0
Sign in to follow this  
gfav

Duvidas

Question

Iae galera! seguinte... to iniciando um projeot no delphi pra interagir com banco de dados mysql num servidor na web! Utilizo o zeos pra conexao!

eu estou fazendo num form uma pesquisa num tabela mysql a partir de um campo da tabela

no form eu coloquei um edittext um grid e um combobox e um botao!

minhas duvidas são...

1º como eu faço um esquema pra aparecer no combobox os campos da minha tabela,

2º como eu faço pra quando digitar no edit e selecionar a campo no combobox ele mostre o resultado no grid de forma que quando for digitando já vai mostrando os resultados..

3º ai quando eu selecionar no grid qual dado eu quero editar eu clicar no botao pra ir pra outro form que criarei com os dados respectivos dados escolhidos no grid para edição?

bom acho que é isso por enquanto!

espero ajuda!! ;)

vlw galera

Share this post


Link to post
Share on other sites

15 answers to this question

Recommended Posts

  • 0
1º como eu faço um esquema pra aparecer no combobox os campos da minha tabela,
gfav, basicamente você vai obter os dados nesta situação, através de um componente para consulta apenas (TZReadOnlyQuery). A questão é: de que forma você pretende utilizar esses dados e quais são os campos do qual você está falando. De um ComboBox, você poderá apenas obter o texto selecionado e em alguns casos um campo Inteiro (tipo um código - é como normalmente uso). Se der mais detalhes fica mais fácil de dar sugestão.

2º como eu faço pra quando digitar no edit e selecionar a campo no combobox ele mostre o resultado no grid de forma que quando for digitando já vai mostrando os resultados.
Ao que parece você utilizará duas informações para fazer o seu filtro (valor do Edit e do ComboBox). Informações sobre este recurso são bastante comuns de encontrar nos foruns;

Uma coisa a ter em mente é que quando a consulta inicial (sem filtro) retorna muitos registros, você pode ter uma performance ruim (mas cada caso é um caso);

Basicamente o que pode ser feito é escrever no evento OnChange do Edit, um código onde você passe para a consulta os dados a serem utilizados como filtros de modo que, a cada vez que o texto ou a seleção do combo mudarem, a consulta seja refeita.

Para o caso de o valor do Edit representar um campo texto em sua consulta, na SQL que você escreve será utilizado o comando LIKE. A título de exemplo, um componente TZReadOnlyQuery poderia conter a seguinte SQL:

'SELECT CodCliente, NomCliente, bla...bla FROM Clientes WHERE NomCliente LIKE :NomCli ORDER BY NomCliente'

então, para informar o parâmetro (:NomCli), dentro do evento OnChange do Edit, você faria algo como:

procedure TBrwClienteEdtNomClienteChange(Sender :TObject);
begin
  QryVerCliente.Close;
  QryVerCliente.ParamByName('NomCli').AsString := EdtNomCliente.Text +'%';
  QryVerCliente.Open;
end;
onde QryVerCliente é o componente responsável pela consulta que será mostrada no seu DBGrid. O '%' adicionado ao texto digitado, funciona como um '*' no DOS, serve para "dizer" ao SQL que traga todos os clientes que contenham o nome começando com o texto passado em EditNomCliente.Text e terminando com qualquer outra coisa (é possível colocar o % no início também); Mas, como no item anterior, mais informações sobre a consulta que você pretende mostrar no grid ajudam a melhor a exemplificação (tabelas, campos, ...)
3º ai quando eu selecionar no grid qual dado eu quero editar eu clicar no botao pra ir pra outro form que criarei com os dados respectivos dados escolhidos no grid para edição?
Para estes casos, costumo implementar no segundo form, os métodos Incluir e Editar de tal modo que passando como parâmetro as informções necessárias (normalmente o Código) e utilizando outro dataset (desta vez um que permita update - TZQuery) onde tenho condições de posicionar no registro a ser manipulado. A título de exemplo, supondo que na consulta que você tem associada ao DBGrid (QryVerCliente - no meu exemplo), esteja o campo CodCliente, então ao clicar num botão 'Alterar' colocaria um código mais ou menos assim:
procedure TBrwClienteBtnAlterarClick(sender :TObject);
begin
  CadCliente := TCadCliente.Create(Self);
  try
    if CadCliente.Alterar(QryVerClienteCOD_CLIENTE.AsInteger) = mrOk then
    begin
     // caso cadastro alterado, refaz consulta para atualizar DBGrid 
      EdtNomClienteChange(Sender);  
    end;
  finally
    CadCliente.Free;
  end;
end;
Daí no form CadCliente, o procedimento Alterar ficaria mais ou menos assim:
function TCadCliente.Alterar(CodCliente :LongInt) :TModalResult;
begin
  QryUpdCliente.ParamByName('CodCliente').AsInteger := CodCliente;
  QryUpdCliente.Open;
  if not QryUpdCliente.EOF then
    Result := ShowModal  // mostrará o form e retornará conforme botão pressionado OK ou Cancel
  else
    Result := mrCancel;  // fechará o form com opção de cancelar
end;

Observe que para este form utilizamos um componente que permite update na tabela e que a consulta SQL dele é similar ao anterior, sendo que aqui passamos como parâmetro o CodCliente com o objetivo de "posicionar" específicamente no cliente selecionado.

Eu gosto de utilizar ModalResult para que apenas se a tela de cadastro sair pela opção mrOk (configuo para quando for clicado em gravar registros) e daí eu atualizo a consulta no Grid. Caso contrário, não há necessidade de refazer a mesma.

Bom, este e mais ou menos o "conceito" que eu utilizo. Existem várias formas de fazer. É apenas para dar uma noção.

[]s

Share this post


Link to post
Share on other sites
  • 0

 basicamente você vai obter os dados nesta situação, através de um componente para consulta apenas (TZReadOnlyQuery). A questão é: de que forma você pretende utilizar esses dados e quais são os campos do qual você está falando. De um ComboBox, você poderá apenas obter o texto selecionado e em alguns casos um campo Inteiro (tipo um código - é como normalmente uso). Se der mais detalhes fica mais fácil de dar sugestão.

Opa.. tpw..nesse combobox eu queria mostrar os dados do campo categoria da tabela categorias... são dados de texto....e depois gostaria de pegar o selecionado desse combobox pra preencher um campo na minha instrução sql!

vlw pelas respostas Micheus...me ajudou muito!

obrigado

Share this post


Link to post
Share on other sites
  • 0
Opa.. tpw..nesse combobox eu queria mostrar os dados do campo categoria da tabela categorias... são dados de texto....e depois gostaria de pegar o selecionado desse combobox pra preencher um campo na minha instrução sql!
Então, para este caso talvez você possa utilizar um comando SQL em um componente TZReadOnlyQuery tipo 'SELECT CodCategoria, DscCategoria FROM Categorias', o qual resultará em todos os registros da tabela categorias.

Para mostrar numa caixa de lista, se não estou enganado, é possível utilizar um TDBLookupComboBox de modo que facilitaria muito as coisas. Se utilizar este componente, não são configuradas as propriedades DataSource e DataField - apenas as de Lookup. O valor selecionado seria disponibilizado em KeyValue;

Mas, se utilizar um TComboBox, você deverá popular esta lista antes de o form ser apresentado. Também utilizo esta abordagem da seguinte forma:

begin
  QryCategorias.Open;
  while not QryCategorias.EOF do
  begin
    CbxCategorias.Items.AddObject(QryCategoriasDSC_CATEGORIA.AsString, Pointer(QryCategoriasCOD_CATEGORIA.AsInteger));
    QryCategorias.Next;
  end;
  QryCategorias.Close;
  ...
end;
depois, para utilizar, eu obtenho o Código devolta e passo à consulta:
begin
...
  CodCategoria := LongInt(CbxCategorias.Items.Objects[CbxCategorias.ItemIndex]);
  QryVerCliente.Close;
  QryVerCliente.ParamByName('NomCli').AsString := EdtNomCliente.Text +'%';
  QryVerCliente.ParamByName('CodCategoria').AsInteger := CodCategoria;
  QryVerCliente.Open;
...
end;

A esta altura o exemplo da consulta que postei antes estaria escrita desta forma:

'SELECT CodCliente, NomCliente, bla...bla

FROM Clientes

WHERE CodCategoria = :CodCategoria

AND NomCliente LIKE :NomCli ORDER BY NomCliente'

[]s

Share this post


Link to post
Share on other sites
  • 0

Opa, tpw... coloquei um componente zqueryreadonly la... coloquei a instrução sql la dentro 'select categoria from categorias' ai pelo exemplo que você me passou adpatado pro meu caso

while not zrqcat.EOF do
  begin
    fedit.CB1.Items.AddObject(zrqcatCATEGORIA.asstring);
    zrqcat.Next;
  end;
zrqcat.close;

(obs.: o combobox está no outro form fedit)

ele da erro

undeclared identifier 'zrqcatCATEGORIA'

o que pode ser isto?

abraço

Share this post


Link to post
Share on other sites
  • 0

gfav, pelo seu comando select ('select categoria from categorias') parece que você tem apenas um campo descritivo (categoria) - não tem um de código, certo?!

Então neste caso vamos ter que mudar algumas coisas:

=> AddObject requer uma string (aquela que aparece na lista e um ponteiro - que eu havia utilizado para guardar o código). Como você tem apenas o campo descritivo, teremos que utilizar outro método Add. Então, substitua a linha:

fedit.CB1.Items.AddObject(zrqcatCATEGORIA.asstring);

por

fedit.CB1.Items.Add(zrqcatCATEGORIA.asstring);

undeclared identifier 'zrqcatCATEGORIA'

o que pode ser isto?

Isto ocorre pro que, provavelmente, você não adicionou os campos ao componente. Para fazer isto, dê um duplo click no componente zrqcat; Deverá aparecer uma pequena janela com botões de navegação(4) desabilitados; Click com o botão direito do mouse sobre ela e selecione a opção All Fields. Isto fará com que os campos que você incluiu no select apareçam na lista.

Se tudo correu corretamente(não havendo erro na sua instrução select), neste momento você já tem o tal campo - componente TField com o nome zrqcatCATEGORIA (note que é a concatenação do nome do dataset +nome do campo).

Eu prefiro esta abordagem por diversas questões, mas há outro meio de fazer isto (sempre há) sem que seja adicionado o campo ao formulário(o que fizemos no passo anterior). você utiliza o método FieldByName(<nome campo>):

fedit.CB1.Items.Add(zrqcat.FieldByName('CATEGORIA').asstring);

=> Para adiantar um pouco as coisas, já lhe informo que a parte do exemplo que postei que utiliza a seleção deste ComboBox precisará ser modificada:

var
  Categoria :string;
begin
  ...
  Categoria := fedit.CB1.Items[CbxCategorias.ItemIndex]);
  QryVerCliente.Close;
  QryVerCliente.ParamByName('NomCli').AsString := EdtNomCliente.Text +'%';
  QryVerCliente.ParamByName('Categoria').AsString := Categoria;
  QryVerCliente.Open;
  ...
end;

a consulta que postei antes estaria escrita desta forma:

'SELECT CodCliente, NomCliente, bla...bla

FROM Clientes

WHERE Categoria = :Categoria

AND NomCliente LIKE :NomCli ORDER BY NomCliente'

Observe que como não armazenamos informação de código na propriedade Objects, então utilizaremos apenas a lista de strings(Items[<indice>] ou Items.Strings[<indice>], usei do 1º modo).

[]s

Share this post


Link to post
Share on other sites
  • 0

opa,,, funcionou.. mais ainda tenho uma duvida!

como eu jogo um valor de um campo já na index do combobox?

a instrução seria +/- assim

select categoria from link where id = 'id'

ai queria jogar o valor do resultado do campo categoria na index do combobox... já aparecer selecionado com esse valor de string.

como eu faço isso?

vlw cara! está quebrando moh galho! ;)

Share this post


Link to post
Share on other sites
  • 0
como eu jogo um valor de um campo já na index do combobox?

a instrução seria +/- assim

select categoria from link where id = 'id'

ai queria jogar o valor do resultado do campo categoria na index do combobox... já aparecer selecionado com esse valor de string.

gfav, é simples. A seleção em um combobox é definida pela propriedade ItemIndex. Então, fedit.CB1.ItemIndex := <indice da posiçao da string na lista> seleciona a string;

É possível obter a posição que uma determinada string na lista, do ComboBox, através do método IndexOf(<string a procurar>) do TStrings:

fedit.CB1.ItemIndex := fedit.CB1.IndexOf(<nome da categoria>);

[]s

Share this post


Link to post
Share on other sites
  • 0

Opa... vlw.. deu certo! mais aproveitando esse tópico aberto já! vou tirar outras duvidas!

nesse form fedit eu puxo do banco de dados o nome de uma img ex: fotoblablabla.jpg

ai eu queria abrir essa img quando for solicitada!

eu coloquei o componente image da palheta additional...

e usei o seguinte codigo

img.Picture.LoadFromFile('http://www.meusite.com.br/fotos_peq/'+zquery2.fieldbyname('foto').AsString);

só que não funciona!

outra... se o campo foto estiver vazio gostaria que não mostrasse nenhuma img ao vez de dar erro...

e a ultima...

tpw.. eu vou fazer um sistema de cadastro também... ai nele queria por um campo pra selecionar a img e enviar por servidor web... como eu faço isso?

acho que é só!

vlw

abraçops

Share this post


Link to post
Share on other sites
  • 0

gfav, nunca fiz nada deste tipo não, mas acho que você vai precisar trabalhar com componente para acesso FTP (para upload com certeza). Vou dar uma pesquisada quando tiver um tempinho, até por que tem um tempo que quero mexer com os componentes da paleta Indy. Qualquer coisa, se achar uma solução, posta ai. ;)

Talvez fosse conveniente abrir um novo tópico para isto

outra... se o campo foto estiver vazio gostaria que não mostrasse nenhuma img ao vez de dar erro...
especificamente neste ponto, uma opção poderia ser usar um try except end inibindo a ocorrência da exceção (continuará quando executando via Delphi, mas "por fora" não)

try
  img.Picture.LoadFromFile('http://www.meusite.com.br/fotos_peq/'+zquery2.fieldbyname('foto').AsString);
except // sem qualquer código dentro do except end
end;

[]s

Share this post


Link to post
Share on other sites
  • 0

Cara... eu coloquei esse codigo

try
  img.Picture.LoadFromFile('http://www.escritoriodosexo.com.br/fotos_peq/'+zquery2.fieldbyname('foto').AsString);
  except


  end;

só que quando não tem nada no campo foto ele da erro e quando tem alguma coisa no campo foto ele também da erro... quando tem dado no campo foto ele da esse erro

unknow picture file extension (.jpg)

e quando está sem dado no campo da esse erro também

só que de vez .jpg ele da o final da url

unknow picture file extension (.br/fotos_peq/)

o que pode ser?

mais uma coisa!

outra duvidazinha

como é que eu coloco um campo do tipo senha.. que fique assim ***...

vlw mano

abraços

Share this post


Link to post
Share on other sites
  • 0
só que quando não tem nada no campo foto ele da erro e quando tem alguma coisa no campo foto ele também da erro... quando tem dado no campo foto ele da esse erro
gfav, acho que assim ficaria mais adequado então:

if Trim(zquery2.fieldbyname('foto').AsString) <> '' then
try
  img.Picture.LoadFromFile('http://www.escritoriodosexo.com.br/fotos_peq/'+zquery2.fieldbyname('foto').AsString);
except
end;

unknow picture file extension (.jpg)
você deve incluir a unit Jpeg na cláusula uses do seu form. Caso não a tenha instalada, click aqui para baixar.

e quando está sem dado no campo da esse erro também

só que de vez .jpg ele da o final da url

unknow picture file extension (.br/fotos_peq/)

o que pode ser?

É como eu disse antes, acho que não vai dar para fazer direto da URL para o componente. Como disse, é provável que tenha que utilizar um componente de FTP (idFTP da paleta Indy), de modo que você solicita a transferência (método Get) da imagem para um TStream (salvando temporariamente) e, depois sim, utilizar o LoadFromFile apontando para este arquivo.

outra duvidazinha

como é que eu coloco um campo do tipo senha.. que fique assim ***...

defina a propriedade PasswordChar do componente Edit, DBEdit ou MaskEdit para '*' - por default é '#0' que significa que não está definida.

[]s

Share this post


Link to post
Share on other sites
  • 0

uma ultima duvidazinha!

quandoi eu executo o programa ele conecta ao banco de dados mysql na web... só que quando eu to mexendo vez em quando ele desconecta da banco de dados... diz

sql error: lost conection to mysql server during query

porque acontce isso?

o que eu posso fazer pra que não ocorra isso?

obrigaado

vlw abraços

Share this post


Link to post
Share on other sites
  • 0

gfav, consultando a documentação do MySQL dá para ver que não é uma única situação que gera este erro (link). Mas deve dar para eliminar algumas.

Notou se só ocorre com uma determinada consulta? Se sim, tente verificar se ela está 100%. A falta de um campo de relacionamento na cláusula WHERE pode gerar um resultado (nº de linhas) maior que o esperado e esta é uma situação em que este erro pode ocorrer.

Não sei se você conhece, mais em todos os casos, o link para a documentação do MySQL (tem versão em português, html/pdf/chm): http://dev.mysql.com/doc/

[]s

Share this post


Link to post
Share on other sites
  • 0

micheus, mais não é em uma unica consulta... normalmente acontece quando eu faço alguma operação... ai se eu deixar um tempo parado caso de 30 segs ai quando vo fazer outra operação da o erro... é como se a conexao com o banco de dados caisse...

não existe nenhuma maneira de eu fazer algo no codigo pra quando a conexao cair ele reconectar automatico... algum evento...?

vlw

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this