18/08/2004

Preciso de idéias subst. eventos de campos persistentes?

Caros amigos

Não consigo tornar os campos de uma query persistentes em tempo de execução, sob este esquema: TqueryCAMPO.xxxxx. Tenho em alguns dos campos eventos do tipo (preciso disso porque nas threads preciso de conexões separadas e crias todos objetos dentro da thread - sem form) abaixo:

procedure TqueryCODIGOgettext(Sender: TField; var Text: String;
DisplayText: Boolean);
begin
if sender.AsString=´1´ then
text:=´01´
end;

{TRECHO DE CODIGO}
QpcPronto.SQL.Clear;
QpcPronto.SQL.Add(´SELECT CODIGO FROM OS´);
Tquery.fielddefs.add(´CODIGO´,FTinteger,0,true);
TqueryCODIGO.OnGetText:=QpcProntoCODIGOgettext; //violação de acesso em TqueryCODIGO.OnGetText
QpcPronto.Open;

Sei que vão me dizer, abra a tabela antes que automaticamento os campos serão carregados. Tudo bem, mas preciso associar o evento antes de abrir, para que ao abrir, a cada registro, aconteça os eventos gettext para os campos em que preciso fazer processamentos.

Já que não estou conseguindo isto, busco idéias para simular isso de outra maneira.

Pensei algo do tipo: eliminar os eventos gettext, percorrer todos os registros da tabela testando o conteudo do campo, mas não me vem a idéia de como alterar somente a apresentação dos dados sem precisar usar edit.

QQ sugestão é bem vinda.

DETALHE. uso IBO

Grato
Delmar


Delmar

Respostas

19/08/2004

Bon Jovi

Se puder usar Midas, tente assim:

ClientDataSet1.Close;
ClientDataSet1.CommandText := ´SELECT...´;
ClientDataSet1.FetchOnDemand := True;
ClientDataSet1.PacketRecords := 0; //Para trafegar somente a estrutura.
ClientDataSet1.Open;

(* Fazer aqui a atribuicao dos eventos, pois já possui os TFields, mas sem nenhum registro *)

ClientDataSet1.PacketRecords := -1; //Para trafegar todos os registros.
ClientDataSet1.First; //´Desperta´ o provider para trazer os registros.

Dando certo ou nao, dê um retorno dessa experiência..
T+


Responder Citar

19/08/2004

Bon Jovi

Ah, e claro, nesse caso nao usar TFields em tempo de design. E sim usar .FieldByName(´...´)... ou FindField dependendo da situacao.

var
Field: TField;
begin
Field := ClientDataSet1.FieldByName(´CAMPO_TESTE´);


Responder Citar

19/08/2004

Bon Jovi

Completo:

private 
  procedure TesteGetText(Sender: TField; var Text: String; DisplayText: Boolean);
............
procedure TForm1.TesteGetText(Sender: TField; var Text: String; DisplayText: Boolean);
begin 
  if Sender.AsString = ´1´ then 
    Text := ´01´ 
end; 
............
{TRECHO DE CODIGO} 
ClientDataSet1.Close; 
ClientDataSet1.CommandText := ´SELECT CODIGO FROM OS´; 
ClientDataSet1.FetchOnDemand := True; 
ClientDataSet1.PacketRecords := 0; //Para trafegar somente a estrutura. 
ClientDataSet1.Open; 
ClientDataSet1.FieldByName(´CAMPO_TESTE´).OnGetText := TesteGetText;
ClientDataSet1.PacketRecords := -1; //Para trafegar todos os registros. 
ClientDataSet1.First; //"Desperta" o provider para trazer os registros. 



Responder Citar

19/08/2004

Delmar

Bon Jovi
Acho que estamos no caminho e pode ser a solução, enquanto o Americano, Jason Warton, desenvolvedor do IBO, não me propor uma solução sem midas.

Bem, postei o código como ficou no meu programa. Estou obtendo agora a seguinte mensagem de erro: ´Missing data provider ou data packed´ da clase EDatabaseError. Se configuro em tempo de projeto funciona, para qualquer das formas abaixo. Mas em tempo de execução as duas falham com a mesma msg de erro


{CODIGO COM SQL DIRETO NA QUERY}
QpcPronto := Tiboquery.Create(IBOsessionRecepcao);
QpcPronto.DatabaseName:=´dbrecepcao´;
QpcPronto.IB_Connection:=IBODataBaseRecepcao;
QpcPronto.IB_Transaction:=IBOtransactionRecepcao;
QpcPronto.SQL.Clear;
QpcPronto.SQL.Add(´SELECT OS.CODIGO FROM OS WHERE STATUSPC=´+ quotedstr(´S´)+ ´ AND CLIENTEAVISADO IS NULL´);
QpcProntoDSP:=Tdatasetprovider.Create(nil);
QpcProntoDSP.DataSet:=Qpcpronto;
QpcProntoCDS:=Tclientdataset.Create(nil);
QpcProntoCDS.ProviderName:=´QpcProntoDSP´;
QpcProntoCDS.FetchOnDemand := True;
QpcProntoCDS.PacketRecords := 0; //Para trafegar somente a estrutura.
QpcProntoCDS.open; //Missing data provider ou data packed

{CODIGO SQL NO CLIENTDATASET}
QpcProntoDSP:=Tdatasetprovider.Create(nil);
QpcProntoDSP.DataSet:=Qpcpronto;
QpcProntoDSP.Options:=[poAllowCommandText];
QpcProntoCDS:=Tclientdataset.Create(nil);
QpcProntoCDS.ProviderName:=´QpcProntoDSP´;
QpcProntoCDS.CommandText:=´SELECT OS.CODIGO FROM OS WHERE STATUSPC=´+ quotedstr(´S´)+ ´ AND CLIENTEAVISADO IS NULL´;
QpcProntoCDS.FetchOnDemand := True;
QpcProntoCDS.PacketRecords := 0; //Para trafegar somente a estrutura.
QpcProntoCDS.open; //Missing data provider ou data packed

Onde pode estar o problema? Não tenho experiência com datasetprovider +clientdataset, por isso pode não estar completa a configuração dos componentes.

Abraços


Responder Citar

20/08/2004

Bon Jovi

Acho q o problema pode estar aqui: QpcProntoCDS.ProviderName:=´QpcProntoDSP´;
Tente setar diretamente o objeto: QpcProntoCDS.SetProvider(QpcProntoDSP);
Vê se pode dar certo chamar isso no evento BeforeOpen. O mais certo seria num ´BeforeOpenCursor´, sendo que parece nao existir, e vc teria criar um descendente do TClientDataSet pra dar override no método OpenCursor. Dê uma olhada no SimpleDS.pas caso precise fazer isso (C:\Arquivos de programas\Borland\Delphi7\Source\Vcl\SimpleDS.pas

Tem tb o TIBClientDataSet, mas nunca usei.


Responder Citar

20/08/2004

Bon Jovi

Nao desconsiderando a alternativa anterior q é mais certa, mas do jeito q vc fez talvez nao tenha dado certo por vc nao ter setado o nome do provider.

QpcProntoDSP:=Tdatasetprovider.Create(nil);
QpcProntoDSP.Name := ´QpcProntoDSP´;


Responder Citar

20/08/2004

Delmar

Acho q o problema pode estar aqui: QpcProntoCDS.ProviderName:=´QpcProntoDSP´; Tente setar diretamente o objeto: QpcProntoCDS.SetProvider(QpcProntoDSP);



Sim. Eu não fiquei parado peranto o problema. Estudei as propriedades, métodos e eventos e já havia resolvido esta parte da msg de erro. Só não me sobrou tempo para postar o retorno.

Agora, ainda estou tendo o problema de que a thread está congelando (toda aplicação) antes de executar o evento onterminate, porque dentro desta thread estou criando um objeto quickreport para testar a parte de impressão. Mas, não fiz testes a fundo. Ainda na parte da manhã, quero debugar linha por linha para ver se isolo o problema. Não achando solução, peço ajuda novamento.

Muito obrigado pela preciosa ajuda.

Abraços e sucesso
Delmar


Responder Citar