Fórum Problema para fazer um select funcionar dentro do DBGrid? #334075

02/12/2006

0

Bom dia pessoal.

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;
Aqui depois que confirmo a gravaçao ai sim apareçe os dados do associado dentro do dbgrid.

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

Adriano_servitec

Responder

Posts

02/12/2006

Brasidata

Bom dia Adriano.

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


Responder

Gostei + 0

02/12/2006

Adriano_servitec

Pessoal acho que ja achei parte do problema
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;
Que usso para deixar os buttons e edits com o enabled false e soh abri-los quando aperto no botao NOVO eh parte do problema.
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;
Aparece uma mensagem de erro quando joga o foco para o maskedit1, como se a tabeal estivesse fechada
[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.

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;
Eh que o DataSet IBQ1 fica fechado no Data Module e por isso abri ele antes de usar o LOCATE. Sobre usar um SQL: Vc quis dizer que em vez de usar o LOCATE fazer um Filtro em SQL? Bom por mim tudo bem, se funciona melhor ainda. (Esse edit uso somente para buscar o campo matricula e o nome do associado de outra tabela (Tabela mestre)



Aliás, outra coisa importante a saber é: quais os componentes de acesso vc está usando? IBX ou DBEXPRESS ?
Desculpe nao ter informado uso Delphi 5.0 , Firebird 2.0 e IBX, no Delphi 5 nao tem os componentes do DBExpress Infelismente :( :D


Responder

Gostei + 0

02/12/2006

Adriano_servitec

Olah [b:cfc93b66d7]Brasidata[/b:cfc93b66d7]

Sobre o SQL seria assim?
procedure TForm3.Edit1Exit(Sender: TObject); begin if DataSource1.State in [dsInsert,dsEdit] then begin [b:cfc93b66d7][color=blue:cfc93b66d7]dm.ibq1.close; dm.ibq1.sql.clear; dm.ibq1.sql.text := ´select matricula, associado from sind2 where matricula = :pmatricula´; dm.ibq1.ParamByName(´pMatricula´).AsString:=Edit1.Text; dm.ibq1.Open;[/color:cfc93b66d7][/b:cfc93b66d7] //depois do select usar um LOCATE??? [color=red:cfc93b66d7]if dm.ibq1.Locate(´Matricula´,(Edit1.text),[]) then[/color:cfc93b66d7] 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;


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;



Responder

Gostei + 0

02/12/2006

Brasidata

PRONTO.
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


Responder

Gostei + 0

02/12/2006

Brasidata

Vc não pediu mas eu sou intrometido e passo mesmo assim:

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...


Responder

Gostei + 0

02/12/2006

Adriano_servitec

Eu fiz assim como vc postou amigo
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;
E mesmo assim aparece o erro

[b:9b5803725c][color=red:9b5803725c]Cannot focus a disabled or invisible windows[/color:9b5803725c][/b:9b5803725c]
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.


Claro que aceito sujestoes sim amigo.
Sou muito enrrolado com esse tal de IF, ELSE, END, BEGIN
Nao tenho base como usar direito


Responder

Gostei + 0

02/12/2006

Adriano_servitec

Olah Brasidata, acho que tinha postado quando vc postou, ai testei o segundo codigo que vc passou
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.. :?:


Responder

Gostei + 0

02/12/2006

Adriano_servitec

O codigo que vc me passou funciona perfeitamente, mais se eu deixar desabilitado essas linhas no evento onStateChange do DataSource (Inclusive mudei para outro DataSource para ver se era problema dele, mais nao era.
{
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.


Responder

Gostei + 0

02/12/2006

Brasidata

[b:f0f7e8ba09][u:f0f7e8ba09]Cannot focus a disabled or invisible windows
[/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.


Responder

Gostei + 0

02/12/2006

Brasidata

PRONTO... Problema enontrado..
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.


Responder

Gostei + 0

02/12/2006

Adriano_servitec

PRONTO... Problema enontrado.. 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.


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***********
E fazer o inverso deste codigo no botao NOVO e retornar a esse codigo depois de gravar no banco de dados no botao GRAVAR.

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.


Responder

Gostei + 0

04/12/2006

Adriano_servitec

Pessoal, agora minha duvida eh o seguinte:

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?


Responder

Gostei + 0

04/12/2006

Brasidata

Continuo apostando no SQL.. Principalmente se o aplicativo for usado em rede...
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...


Responder

Gostei + 0

04/12/2006

Adriano_servitec

Valeu Brasidada, tambem vou continuar usando o SQL.

Mais uma vez obrigado por me ajudar.

Abraços
Adriano


Responder

Gostei + 0

04/12/2006

Emerson Nascimento

SEEK? Não!!!!

SQL Mesmo.

a sugestão passada pelo colega brasidata é a mais indicada.
assim a rede não sofre com tráfego desnecessário.


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar