Fórum Problema para fazer um select funcionar dentro do DBGrid? #334075
02/12/2006
0
Meu problema agora eh o seguinte:
Bom tenho um programa que tem duas tabelas uma para cadastrar associados com o campo MATRICULA sendo PK, e outra para cadastrar as datas de pagamentos destes associados que tambem tem o campo MATRICULA sendo FK. Para ser um Mestre/Detalhe
O problema esta no form aonde cadastro as datas (Form secundario)
No form tenho um edit que digito o codigo da matricula do associdado para puxar o codigo, aqui tudo ok, mais tamebm neste form coloquei um dbgrid com a tabela secundaria para msotrar os movimentos de pagamentos cfe digito o codigo do associado, entao resolvi fazer assim no onexit do edit aonde digito o codigo do associado
procedure TForm3.Edit1Exit(Sender: TObject);
begin
{trecho que pertence a tabela cadastro associado Tabela Mestre}
dm.ibq1.open;
if DM.ibq1.LOCATE(´Matricula´,(Edit1.text),[]) then
BEGIN
LABEL3.CAPTION:=DM.ibq1.FieldByName(´associado´).AsString;
END else BEGIN
messagedlg(´Código do associado não Localizado´,mterror,[mbOk],0);
if application.messagebox(´Digitar Novamente?´,´Aviso´,36)=idyes then begin
{final do trecho que localiza o associado}
edit1.text:=´´;
edit1.setfocus;
end else
maskedit1.SETFOCUS;
{trecho que filtra a matricula do associado dentro do dbgrid}
with dm.QryLimpa do
begin
sql.clear;
sql.add(´select * from corrente´);
sql.add(´WHERE (matricula = :pmatricula)´);
parambyname(´pmatricula´).asString := edit1.text;
open;
end;
end;
{final do filtro no dbgrid tabela secundaria}
end;Mais nao esta filtrando a matricula pertecente ao associado para msotrar no dbgrid. Fiz o mesmo codigo do SQL da tabela CORRENTE num form usando um edit e um button e funciona normalmente. Ou seja se eu digitar o codigo 2, por exemplo me mostra no dbgrid todos movimentos do associado 2, e assim por diante. Soh nao aparece la naquele codigo acima postado.
Ja olhei o datasource se esta setado certo, e esta, ateh ja coloquei outro datasource pra ver se mudava, mudei o dngrid tambem e nada. Neste form nao consigo mostrar os dados, soh me mostra depois que eu gravo.
Para gravar uso assim
with dm.QryLimpa do
begin
sql.clear;
sql.add(´select * from corrente´);
sql.add(´WHERE (matricula = :pmatricula) and (mespgto = :pmp) and (mesrefini = :pmi) and (mesreffim = :pmf)´);
parambyname(´pmatricula´).asString := edit1.text;
parambyname(´pmp´).asdate := StrToDate(maskedit1.text);
parambyname(´pmi´).asdate := StrToDate(maskedit2.text);
parambyname(´pmf´).asdate := StrToDate(maskedit3.text);
open;
if not EOF then
begin
Close;
showmessage(´Exception 1 RESTRIÇÃO Dados Duplicados, Erro na Gravação! Tente Novamente!´);
dm.qrylimpa.open;
MaskEdit1.SetFocus;
end
else
{comandos de inserção }
if application.messagebox(Pchar(´Deseja Incluir este Lançamento:´ + #13+ dm.qRYLIMPA.FieldByName(´Sequencia´).AsString +´ ´+ 13+ dm.qRYLIMPA.FieldByName(´associado´).AsString), Pchar(´Incluir Dados´+Self.Caption), MB_ICONQUESTION
+ MB_YESNO) = IDYES then begin
//Close;
dm.ibqcorr.sql.clear;
dm.ibqcorr.sql.Add(´Insert into corrente(matricula, associado, mespgto, mesrefini, mesreffim)´);
dm.ibqcorr.sql.add(´values (:Matricula, :Associado, :Mespgto, :Mesrefini, :Mesreffim)´);
dm.ibqcorr.ParamByName(´Matricula´).Value :=Edit1.text;
dm.ibqcorr.ParamByName(´Associado´).value:=label3.caption;
dm.ibqcorr.ParamByName(´Mespgto´).value:=strtodate(maskedit1.text);
dm.ibqcorr.ParamByName(´Mesrefini´).value:=strtodate(maskedit2.text);
dm.ibqcorr.ParamByName(´Mesreffim´).value:=strtodate(maskedit3.text);
try
dm.ibqcorr.ExecSql;
dm.ibtcorr.commit;
dm.ibqcorr.close;
dm.ibqcorr.sql.clear;
dm.ibqcorr.sql.text := ´select * from corrente´;
dm.ibqcorr.Open;
dm.qrylimpa.close;
dm.qrylimpa.sql.clear;
dm.qrylimpa.sql.text := ´select * from corrente where matricula = :matricula´;
dm.qrylimpa.Open;
sbar.SimpleText := ´Dados Incluídos...´;
b1.setfocus;
except
On E:Exception do begin
dm.ibtcorr.Rollback;
dm.tlimpa.Rollback;
sbar.SimpleText := ´Abortado...´;
Showmessage(´Falha na Inclusão dos Dados!´#1310´Mensagem: ´+E.Message);
end;
end;
end;
end;
end;Nao estou conseguindo entender pq. nao apareçe antes, sempre usei assim em outros programas e nunca me deu problemas.
[color=red:e19cbf88a1]Serah que eh pq faço o select usando um Query chamado qryLimpa e outro query chamado IBQCorr para fazer o Insert, Update, Delete?[/color:e19cbf88a1]
Bom pessoal espero que tenham entendido minha duvida
Obrigado pela ajuda de todos
Adriano.
Adriano_servitec
Curtir tópico
+ 0Posts
02/12/2006
Brasidata
Tá meio embolada a sua explicação ou eu estou com pouco tempo e por isso ainda não entendi 100¬.
Mas uma coisa, de antemão eu te digo:
No primeiro bloco de códigos da sua pergunta notei que você usa o LOCATE. Veja bem: nesse caso, como você só precisa de UM único registro da tabela mestre, o tráfego de informação entre o seu aplicativo e o banco de dados será maior do que realmente você precisa.
Quando você usa algo como:
Tabela.Open;
TAbela.Locate();
VocÊ primeiro ´chama´ todos os registros da tabela pra DEPOIS localizar o que vocÊ quer.
Não seria uma boa idéia você filtrar o registro ANTES de abrir a sua tabela? Por exemplo:
TABELA.close;
Tabela.SQL := ´ select CODIGO, NOME from TABELA where CODIGO =:cod´;
TABELA.ParambyName(´COD´).asstring := Edit1.text;
TABELA.Open;
(onde TABELA é seu dataset)
Assim, você só traz para o seu Form os CAMPOS necessários de UM único registro, suficientes para o seu trabalho no momento.
Aliás, outra coisa importante a saber é: quais os componentes de acesso vc está usando? IBX ou DBEXPRESS ?
Isso não responde a sua pergunta AINDA , mas facilita a compreensão do seu código e melhora a performance do seu aplicativo.
Vou continuar tentando decifrar sua necessidade e logo retorno com algo mais útil para vc.
PS>: Se quiser me add no seu MSN (tá no meu perfil) a gente pode trocar figurinhas sobre o assunto
Gostei + 0
02/12/2006
Adriano_servitec
Reparei que neste codigo aqui
procedure TForm3.DataSource1StateChange(Sender: TObject); var I: Integer; Perm: Boolean; begin //*****trata botoes enabled true ou false******* b1.Enabled := Datasource1.State in [dsBrowse]; b2.Enabled := Datasource1.State in [dsInsert,dsEdit]; b3.Enabled := Datasource1.State in [dsInsert,dsEdit]; b4.Enabled := Datasource1.State in [dsBrowse]; b5.Enabled := Datasource1.State in [dsBrowse]; //********pada deixar edit, jvedit,maskedit e memo com o enabled false***** Perm := (DataSource1.State in [dsInsert, dsEdit]); for I := 0 to Self.ComponentCount -1 do begin if (Self.Components[i] is TEdit) then (Self.Components[i] as TEdit).Enabled := Perm; if (Self.Components[i] is TMaskEdit) then (Self.Components[i] as TMaskEdit).Enabled := Perm; end; end;
Exemplo
Se nesta linha de codigo deixo assim
procedure TForm3.Edit1Exit(Sender: TObject); begin dm.ibq1.open; if DataSource1.State in [dsInsert,dsEdit] then begin if dm.ibq1.Locate(´Matricula´,(Edit1.text),[]) then begin Label3.Caption:=dm.ibq1.FieldByName(´associado´).AsString; maskedit1.setfocus; dm.qrylimpa.close; dm.qrylimpa.sql.clear; dm.qrylimpa.sql.text := ´select * from corrente where matricula = :matricula´; dm.qrylimpa.Open; end else begin messagedlg(´Código do associado não Localizado´,mterror,[mbOk],0); edit1.text:=´´; edit1.SetFocus; end; end; end;
[b:c7945ad20f]Cannot focus a disabled or invisible windows[/b:c7945ad20f]
Soluçao para o erro:
Deixar o codigo que fica no dataSource desativado, o que deixa os buttons e edits desabilitados em modo browser, e enabled true em modo insert, edit.
Mais nao quero assim, pois como uso edit, maskedit, qualquer um pode digitar sem apertar no botao NOVO que se encarrega de abrir o DataSet.
---------------------------
Bom dia Brasidata, obrigado por participar da minha duvida.
Gostei + 0
02/12/2006
Adriano_servitec
Sobre o SQL seria assim?
Bom fiz assim, mesmo assim ainda nao esta ficando enabled os edits depois do codigo, ou seja fica somente antes na hora em que eu uso o botao NOVO assim
dm.qrylimpa.open; dm.qrylimpa.append; edit1.setfocus;
Gostei + 0
02/12/2006
Brasidata
Amigo. Pra conseguir enternder seu codigo tive que editá-lo, corrigindo a IDENTAÇÃO do dito cujo e finalmente descobri pq sua tabela detalhes não tá abrindo... Depois de me enrolar nesse emaranhado de ´begins e ends´ não identados, percebi que o bloco de códigos que deveria abrir sua tabela de detalhes estava no lugar ERRADO. Experimente da forma abaixo e me conte o resultado final por favor:
Código:
procedure TForm3.Edit1Exit(Sender: TObject);
begin
dm.ibq1.open;
if DM.ibq1.LOCATE(´Matricula´,(Edit1.text),[]) then
begin
LABEL3.CAPTION:=DM.ibq1.FieldByName(´associado´).AsString;
{Aqui deve iniciar a abertura da tabela de DETALHES}
with dm.QryLimpa do
begin
sql.clear;
sql.add(´select * from corrente´);
sql.add(´WHERE (matricula = :pmatricula)´);
parambyname(´pmatricula´).asString := edit1.text;
open;
end;
end
else
begin
messagedlg(´Código do associado não Localizado´,mterror,[mbOk],0);
if application.messagebox(´Digitar Novamente?´,´Aviso´,36)=idyes then
begin
edit1.text:=´´;
edit1.setfocus;
end
else
maskedit1.SETFOCUS;
end;
end;
Mas, eu, particularmente, mesmo se essa opção funcionar, prefiro substituir algumas instruções por outras de melhor performance... Se estiver interessado eu te passo a minha sugestão depois.
Abraço e boa sorte
Gostei + 0
02/12/2006
Brasidata
Abaixo está a minha sugetão para o mesmo código sem o LOCATE em lugar algum, aumentando a performance da sua consulta.
procedure TForm3.Edit1Exit(Sender: TObject);
begin
dm.ibq1.close;
dm.ibq1.sql.clear; // acho que não precisa desta linha aqui. Experimente com e sem ela.
dm.ibq1.sql.text := ´select matricula, associado from sind2 where matricula = :pmatricula´;
dm.ibq1.ParamByName(´pMatricula´).AsString := Edit1.Text;
dm.ibq1.Open;
if NOT dm.ibq1.isEmpty then
begin
LABEL3.CAPTION:=DM.ibq1.FieldByName(´associado´).AsString;
with dm.QryLimpa do
begin
close;
sql.clear;
sql.text := ´select * from corrente WHERE matricula = :pmatricula´; // tinha um "(" sobrando nesta sql
parambyname(´pmatricula´).asString := edit1.text;
open;
end;
end
else
begin
messagedlg(´Código do associado não Localizado´,mterror,[mbOk],0);
dm.ibq1.close; // Precisamos fechar a tabela MESTRE.
dm.QryLimpa.close; // E a DETALHES tb.
if application.messagebox(´Digitar Novamente?´,´Aviso´,36)=idyes then
begin
edit1.text:=´´;
edit1.setfocus;
end
else
maskedit1.SETFOCUS;
end;
end;
Acho que vale a pena tentar...
Gostei + 0
02/12/2006
Adriano_servitec
procedure TForm3.Edit1Exit(Sender: TObject);
begin
dm.ibq1.open;
if DM.ibq1.LOCATE(´Matricula´,(Edit1.text),[]) then
begin
LABEL3.CAPTION:=DM.ibq1.FieldByName(´associado´).AsString;
{Aqui deve iniciar a abertura da tabela de DETALHES}
with dm.QryLimpa do
begin
sql.clear;
sql.add(´select * from corrente´);
sql.add(´WHERE (matricula = :pmatricula)´);
parambyname(´pmatricula´).asString := edit1.text;
open;
end;
end
else
begin
messagedlg(´Código do associado não Localizado´,mterror,[mbOk],0);
if application.messagebox(´Digitar Novamente?´,´Aviso´,36)=idyes then
begin
edit1.text:=´´;
edit1.setfocus;
end
else
maskedit1.SETFOCUS;
end;
end;
[b:9b5803725c][color=red:9b5803725c]Cannot focus a disabled or invisible windows[/color:9b5803725c][/b:9b5803725c]
Claro que aceito sujestoes sim amigo.
Sou muito enrrolado com esse tal de IF, ELSE, END, BEGIN
Nao tenho base como usar direito
Gostei + 0
02/12/2006
Adriano_servitec
procedure TForm3.Edit1Exit(Sender: TObject);
begin
dm.ibq1.close;
//dm.ibq1.sql.clear; // acho que não precisa desta linha aqui. Experimente com e sem ela.
dm.ibq1.sql.text := ´select * from sind2 where matricula = :pmatricula´;
dm.ibq1.ParamByName(´pMatricula´).AsString := Edit1.Text;
dm.ibq1.Open;
if NOT dm.ibq1.isEmpty then
begin
LABEL3.CAPTION:=DM.ibq1.FieldByName(´associado´).AsString;
with dm.QryLimpa do
begin
close;
sql.clear;
sql.text := ´select * from corrente WHERE matricula = :pmatricula´; // tinha um "(" sobrando nesta sql
parambyname(´pmatricula´).asString := edit1.text;
open;
end;
end
else
begin
messagedlg(´Código do associado não Localizado´,mterror,[mbOk],0);
dm.ibq1.close; // Precisamos fechar a tabela MESTRE.
dm.QryLimpa.close; // E a DETALHES tb.
if application.messagebox(´Digitar Novamente?´,´Aviso´,36)=idyes then
begin
edit1.text:=´´;
edit1.setfocus;
end
else
maskedit1.SETFOCUS;
end;
end;
E o erro de tabela fechada ainda percite
[b:c9f440c032][u:c9f440c032]Cannot focus a disabled or invisible windows
[/u:c9f440c032][/b:c9f440c032]
Por que serah desse erro de fechar a tabela.. :?:
Gostei + 0
02/12/2006
Adriano_servitec
{
var
I: Integer;
Perm: Boolean;
begin
//*****trata botoes enabled true ou false*******
b1.Enabled := Datasource1.State in [dsBrowse];
b2.Enabled := Datasource1.State in [dsInsert,dsEdit];
b3.Enabled := Datasource1.State in [dsInsert,dsEdit];
b4.Enabled := Datasource1.State in [dsBrowse];
b5.Enabled := Datasource1.State in [dsBrowse];
//********pada deixar edit, jvedit,maskedit e memo com o enabled false*****
Perm := (DataSource1.State in [dsInsert, dsEdit]);
for I := 0 to Self.ComponentCount -1 do
begin
if (Self.Components[i] is TEdit) then
(Self.Components[i] as TEdit).Enabled := Perm;
if (Self.Components[i] is TMaskEdit) then
(Self.Components[i] as TMaskEdit).Enabled := Perm;
end;
}
Ainda nao entendi pq no começo abre a tabela para ir no edit1.text e todos maskedits ficam com o enabled true, mais assim que tento passar para o maskedit1 automaticamente a tabela eh fechada.
Gostei + 0
02/12/2006
Brasidata
[/u:f0f7e8ba09][/b:f0f7e8ba09]
Peraí. Esse erro não tem nada a ver com o código acima. Isso tem a ver com o controle que recebe o foco logo após a execução do evento OnExit do Edit1.
Dá uma checada se o maskedit1, se seu Form, Panels ou qualquer outro controle que vai receber o foco não está com suas propriedades Enabled ou Visible em FALSE... Isso sim, pode causar esse tipo de erro.
Gostei + 0
02/12/2006
Brasidata
Relamente esse código que está no OnChangeState do seu datasource não tá legal... Ele tá desabilitando seus controles e por isso tem-se o erro.
Espero que essa datasource não esteja no seu datamodule e sim no proprio form, senão o pepino ficará maior ainda....
você realmente precisa desabilitar os controles toda vez que a tabela fecha???
Se você não tá usando DBedits não vejo motivos para isso, principalmente filtrando pelo SQL e não pelo LOCATE.
Gostei + 0
02/12/2006
Adriano_servitec
Bom depois de tanto dar trabalho com meu codigo, cheguei a conclusao que o certo para mim tratar os buttons e edits foi usar assim
procedure TForm3.FormShow(Sender: TObject); begin //********TRATA EDIT E BUTTON************* b1.Enabled:=True; b2.Enabled:=False; b3.Enabled:=False; b4.Enabled:=True; b5.Enabled:=False; b6.Enabled:=True; Edit1.Enabled:=False; MaskEdit1.Enabled:=False; MaskEdit2.Enabled:=False; MaskEdit3.Enabled:=False; //******************final do tratamento button, edit***********
Bom amigo, obrigado pelo esforço em me ajudar. Agora acho que funcionou certo. :D
Pelo menos esta mostrando os dados no dbgrid corretamente e tambem estou conseguindo incluir novos dados.
Valeu mesmo, muito obrigado.
Caso resolvido.
Gostei + 0
04/12/2006
Adriano_servitec
Primeiro começei com o LOCATE
Depois passei para o SQL fazendo um Select
agora me disseram que o certo e o mais rapido para esse tipo de consulta eh o SEEK (Nem sei como usa este comando)
Entao a pergunta, qual eh o melhor mesmo para este tipo de consulta?
Gostei + 0
04/12/2006
Brasidata
Sempre recomendo o trio dataset, provider, clientDataSet e os filtros por SQL dinâmico, já que isso diminui sensivelmente o trafego de informações entre a aplicação e o banco de dados (Vital para o bom funcionamento em rede). E com os dados pesquisados estando na memória da máquina cliente fica muito mais rápido processá-los...
Gostei + 0
04/12/2006
Adriano_servitec
Mais uma vez obrigado por me ajudar.
Abraços
Adriano
Gostei + 0
04/12/2006
Emerson Nascimento
SQL Mesmo.
a sugestão passada pelo colega brasidata é a mais indicada.
assim a rede não sofre com tráfego desnecessário.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)