Fórum Função que retorna um lista de strings #349008

14/11/2007

0

escrevi uma função que retorne um lista de strings e queria saber se está correto, porem aqui não está dando nenhum erro, mas queria saber se o objeto stringList está sendo liberado corretamente ou se tem algum erro de lógica.

procedure TfrmCadUser.tlbtnIncluirClick(Sender: TObject);
var
   lista : TStringList;
begin
   inherited;
   lista := Pesquisar(´select ....´);
   try
      cmbID.Items := lista;  // inclui uma lista de código de usuarios.
   finally
      lista.Free;
   end;
end;

function TfrmCadUser.Pesquisar(strSql) : TStringList;
var
   mensagem : string;
   lst : TStringList;
begin
   lst := TStringList.Create;
   with DM.qryPesq do
    begin
        Close;
        SQL.Clear;
        SQL.Add(strSql);
        Open;
        while not (DM.qryPesq.Eof) do
         begin
            lst.Append(Fields[0].AsString);
            Next;
         end;
        Result := lst;
    end;
end;


agradeço antecipadamente,
Pestana.


Pestana_

Pestana_

Responder

Posts

15/11/2007

Pestana_

UP


Responder

Gostei + 0

15/11/2007

Rodc

Está correto, considerando que a função Pesquisar() foi você quem criou.
Porém, se um dia você (ou outro programador) chamar Pesquisar() e esquecer que tem que liberar o StringList, você poderá ter problemas de memória.
Sugiro fazer como abaixo:
procedure TfrmCadUser.tlbtnIncluirClick(Sender: TObject); 
var 
   lista : TStringList; 
begin 
   inherited; 
   lista :=  TStringList.Create; 
   try 
      lista := Pesquisar(lista, ´select ....´); 
      cmbID.Items := lista;  // inclui uma lista de código de usuarios. 
   finally 
      lista.Free; 
   end; 
end; 

function TfrmCadUser.Pesquisar(&lst TStringList, strSql) : TStringList; 
var 
   mensagem : string; 
begin 
   with DM.qryPesq do 
    begin 
        Close; 
        SQL.Clear; 
        SQL.Add(strSql); 
        Open; 
        while not (DM.qryPesq.Eof) do 
         begin 
            lst.Append(Fields[0].AsString); 
            Next; 
         end; 
        Result := lst; 
    end; 
end;



Responder

Gostei + 0

15/11/2007

Pestana_

Está correto, considerando que a função Pesquisar() foi você quem criou. Porém, se um dia você (ou outro programador) chamar Pesquisar() e esquecer que tem que liberar o StringList, você poderá ter problemas de memória. Sugiro fazer como abaixo:
procedure TfrmCadUser.tlbtnIncluirClick(Sender: TObject); 
var 
   lista : TStringList; 
begin 
   inherited; 
   lista :=  TStringList.Create; 
   try 
      lista := Pesquisar(lista, ´select ....´); 
      cmbID.Items := lista;  // inclui uma lista de código de usuarios. 
   finally 
      lista.Free; 
   end; 
end; 

function TfrmCadUser.Pesquisar(&lst TStringList, strSql) : TStringList; 
var 
   mensagem : string; 
begin 
   with DM.qryPesq do 
    begin 
        Close; 
        SQL.Clear; 
        SQL.Add(strSql); 
        Open; 
        while not (DM.qryPesq.Eof) do 
         begin 
            lst.Append(Fields[0].AsString); 
            Next; 
         end; 
        Result := lst; 
    end; 
end;


[b:26b89f583c]rodc[/b:26b89f583c] muito obrigado por responder, vou testar aqui depois informo o resultado.


agradeço,
Pestana.


Responder

Gostei + 0

15/11/2007

Rodc

Acho que no Pascal deve ser posto ´var´ ao invés de ´&´ no parâmetro da função.
Segue outro exemplo:
procedure TfrmCadUser.tlbtnIncluirClick(Sender: TObject); 
var 
   lista : TStringList; 
begin 
   inherited; 
   lista :=  TStringList.Create; 
   try 
      Pesquisar(lista, ´select ....´); 
      cmbID.Items := lista;  // inclui uma lista de código de usuarios. 
   finally 
      lista.Free; 
   end; 
end; 

function TfrmCadUser.Pesquisar(var lst TStringList, strSql) : boolean; 
var 
   mensagem : string; 
begin 
   with DM.qryPesq do 
    begin 
        Close; 
        SQL.Clear; 
        SQL.Add(strSql); 
        Open; 
        while not (DM.qryPesq.Eof) do 
         begin 
            lst.Append(Fields[0].AsString); 
            Next; 
         end; 
    end; 

    Result := true; 
end;



Responder

Gostei + 0

15/11/2007

Rodc

Melhor, neste último exemplo faça a inclusão assim:
procedure TfrmCadUser.tlbtnIncluirClick(Sender: TObject); 
begin 
   inherited; 
   try 
      lista := Pesquisar(cmbID.Items, ´select ....´); // inclui uma lista de código de usuarios. 
   finally 
      lista.Free; 
   end; 
end; 



Responder

Gostei + 0

15/11/2007

Rodc

Melhor, neste último exemplo faça a inclusão assim:

Corrigindo o exemplo:
procedure TfrmCadUser.tlbtnIncluirClick(Sender: TObject); 
begin 
   inherited; 
   try 
      Pesquisar(cmbID.Items, ´select ....´); // inclui uma lista de código de usuarios. 
   finally 
      lista.Free; 
   end; 
end;



Responder

Gostei + 0

15/11/2007

Rodc

Afff. tô desatento... segue mais uma correção no exemplo:
procedure TfrmCadUser.tlbtnIncluirClick(Sender: TObject); 
begin 
   inherited; 
   Pesquisar(cmbID.Items, ´select ....´); // inclui uma lista de código de usuarios. 
end;



Responder

Gostei + 0

16/11/2007

Fabiano Góes

procedure TfrmCadUser.Pesquisar(var lst: TStringList; strSql: String);
begin

   with DM.qryPesq do
   begin

      Close;
      SQL.Clear;
      SQL.Add(strSql);
      Open;
      
      while not (DM.qryPesq.Eof) do
      begin
         lst.Append(Fields[0].AsString);
         Next;
      end;

   end;
   
end;


procedure TfrmCadUser.tlbtnIncluirClick(Sender: TObject);
begin
   inherited;
   Pesquisar(cmbID.Items, ´select ....´); // inclui uma lista de código de usuarios.
end;


sem querer ofender o amigo ´rodc´ essa seria a minha idéia para preencher um Objeto TStrings com o resultado de uma query, sendo que já é passado uma referencia do Objeto que deve ser preenchido acho que não precisava retornar nada a não ser que se implemente um tratamento de erro com try...except, e caso ocorra algum problema gerar um except,
tambem existia uma variavel ´mensagem´ que não estava sendo usada.

bom essa é apenas a minha idéia.

abraço !!!


Responder

Gostei + 0

16/11/2007

Rodc

[quote:99ac5bd7fc=´Fabiano Góes´]...acho que não precisava retornar nada a não ser que se implemente um tratamento de erro com try...except, e caso ocorra algum problema gerar um except,
tambem existia uma variavel ´mensagem´ que não estava sendo usada.[/quote:99ac5bd7fc]
Pelo jeito você programa Java, correto? Não gosto de gerar excepty no Delphi porque em debug tem de ficar dando OK na mensagem de erro. É lógico que o retorno neste exemplo está fazendo nada, mas se um dia alguém quiser implementar ele já faz parte da função.
Mas sua sugestão também é válida... :D
Abraços,


Responder

Gostei + 0

16/11/2007

Pestana_

Primeiramente muito obrigado a todo que me ajudaram !

Fabiano Góes eu achei sua implementação super bacana com isso não preciso criar uma lista no botão incluir, mas não está compilando { [Error] Unit1.pas(51): Types of actual and formal var parameters must be identical] }. tem como resolver esse problema ? tentei aqui e não consegui.

andei pensando no que vocês postaram e cheguei a está conclusão o que vocês acham, está correto ou não?

function TfrmCadUser.Pesquisar(var lst : TStringList; strSql : string) : boolean;
begin
   Result := false;
   with DM.qryPesq do
    begin
       Close;
       SQL.Clear;
       SQL.Add(strSql);
       Open;
       while not Eof do
        begin
           lst.Append(Fields[0].AsString);
           Next;
        end;
       if lst.Count > 0 then
         Result := true;
    end;
end;


procedure TfrmCadUser.tlbtnIncluirClick(Sender: TObject);
var
   lista : TStringList;
begin
   lista :=  TStringList.Create;
   try
      if Pesquisar(lista, ´select ...´) then
        cmbID.Items := lista;
   finally
      lista.Free;
   end;
end;


Fabiano Góes você tem razão a variavel mensagem não tem nada haver nesta rotiana é que eu esqueci de remover.


flw.


Responder

Gostei + 0

16/11/2007

Fabiano Góes

[quote:37abf178d1=´Fabiano Góes´]...acho que não precisava retornar nada a não ser que se implemente um tratamento de erro com try...except, e caso ocorra algum problema gerar um except, tambem existia uma variavel ´mensagem´ que não estava sendo usada.

Pelo jeito você programa Java, correto? Não gosto de gerar excepty no Delphi porque em debug tem de ficar dando OK na mensagem de erro. É lógico que o retorno neste exemplo está fazendo nada, mas se um dia alguém quiser implementar ele já faz parte da função.
Mas sua sugestão também é válida... :D
Abraços,[/quote:37abf178d1]

não programo Java não, sou programador Delphi mesmo só estudei C/C++ :wink:

o importante é o post ser finalizado, com retorno ou sem retorno, com except ou sem except, se o amigo Pestana_ conseguiu chegar a uma conclusão beleza. :lol:

abraço galera !!!


Responder

Gostei + 0

17/11/2007

Micheus

[b:8389d8fe04]Pestana_[/b:8389d8fe04], acho que não viram sua nova pergunta...

Fabiano Góes eu achei sua implementação super bacana com isso não preciso criar uma lista no botão incluir, mas não está compilando { [Error] Unit1.pas(51): Types of actual and formal var parameters must be identical] }. tem como resolver esse problema ? tentei aqui e não consegui.
este erro, não deve estar ocorrendo com este seu código como ele foi posto aqui. Provavelmente vc fez algo como passar como parâmetro a propriedade Items (TStrings) na chamada a Pesquisar que requer um parâmetro TStringList.

andei pensando no que vocês postaram e cheguei a está conclusão o que vocês acham, está correto ou não?
correto está.
Mas, ainda, dá para fazer diferente.
Primeiro, observe que a condição avaliada pelo seu IF, ou seja ´lst.Count > 0´, só pode retornar um dos dois valores: TRUE e FALSE;
Logo, vc o atribui direto ao seu Result, com isso vc elimina 2 linhas da procedure;
Segundo, se vc utilizar a propriedade Text do SQL, ao invés do método Add, vc poderá suprimir a chamada ao método Clear;
Terceiro, se vc está apenas armazenando a lista de strings (mais nada) então vc poderia utilizar a própria propriedade Items do combolistbox na chamada ao seu procedimento Pesquisar. Observando que ao declarar classe como parâmetro, não é necessário precedê-lo com VAR no cabeçacho da procedure (o parâmetro será sempre por referência, não por valor).

Vejamos:
function TfrmCadUser.Pesquisar(lst : TStrings; strSql : string) : boolean;
begin
   with DM.qryPesq do
   begin
      Close;
      SQL.Text := strSql;
      Open;
      while not Eof do
      begin
         lst.Append(Fields[0].AsString);
         Next;
      end;
   end;
   Result := lst.Count > 0;
end;


procedure TfrmCadUser.tlbtnIncluirClick(Sender: TObject);
begin
   cmbID.Items.Clear;
   Pesquisar(cmbID.Items, ´select ...´);
end;
apenas precisamos, limpar a lista antes de que ela seja populada.

Abraços


Responder

Gostei + 0

17/11/2007

Pestana_

[quote:6d070ca42b=´Pestana_´]Fabiano Góes eu achei sua implementação super bacana com isso não preciso criar uma lista no botão incluir, mas não está compilando { [Error] Unit1.pas(51): Types of actual and formal var parameters must be identical] }. tem como resolver esse problema ? tentei aqui e não consegui.
este erro, não deve estar ocorrendo com este seu código como ele foi posto aqui. Provavelmente vc fez algo como passar como parâmetro a propriedade Items (TStrings) na chamada a Pesquisar que requer um parâmetro TStringList.[/quote:6d070ca42b]


Micheus muito obrigado por responder a minha pergunta !

em relação ao erro que foi citado eu estava falando do penultimo poste do Fabiano Góes e que realmente era isso mesmo que você comentou sobre o erro.

ficou show de bola o seu código com isso nem precisa declarar e instanciar a classe TStringList no botão Incluir. Ajustei ao meu código e ficou tudo belezinha tá rodando redondo hehehehe.

uma coisa importante que você citou: {
[i:6d070ca42b]Observando que ao declarar classe como parâmetro, não é necessário precedê-lo com VAR no cabeçacho da procedure (o parâmetro será sempre por referência, não por valor).[/i:6d070ca42b] } essa eu realmente não sabia, foi muito bom essa sua dica.

uma coisa que eu ainda não entendi é que TStringList é herdado de TStrings, então porque eu não poderia declarar como parametro TStringList ao invês de TString, será que tem algo haver como o checkListBox.Items que referência a classe TStrings e faz uso somente desta classe e com isso não conhece a classe TStringList. desculpe a perguranta é que eu entendo pouco sobre OO, mas tudo bem você já ajudou e muito.

abraços,
Pestana.


Responder

Gostei + 0

18/11/2007

Micheus

uma coisa que eu ainda não entendi é que TStringList é herdado de TStrings, então porque eu não poderia declarar como parametro TStringList ao invês de TString, será que tem algo haver como o checkListBox.Items que referência a classe TStrings e faz uso somente desta classe e com isso não conhece a classe TStringList.
Só para arredondar os termos, TStringList é [b:79cdd0f7f3]descendente[/b:79cdd0f7f3] de TStrings e [b:79cdd0f7f3]herda[/b:79cdd0f7f3] suas características (e, a ´grosso modo´, define novas e/ou altera existentes).

Não sei se vou conseguir ser didático, mas é mais ou menos isto mesmo - tem a ver com hierarquia. Como eu disse, TStringList é descendente de TString e, então, ´reconhece´ todos os métodos e propriedades deste. Já o inverso não é verdadeiro.

Neste sentido, seria possível vc declarar o parâmetro como sendo um TStrings e chamar o procedimento passando um TStringList.

Abraços


Responder

Gostei + 0

18/11/2007

Pestana_

valeu micheus, e obrigado a todos por ter ajudado !


abraços,
Pestana.


Responder

Gostei + 0

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

Aceitar