Função que retorna um lista de strings
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.
agradeço antecipadamente,
Pestana.
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_
Curtidas 0
Respostas
Pestana_
14/11/2007
UP
GOSTEI 0
Rodc
14/11/2007
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:
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;
GOSTEI 0
Pestana_
14/11/2007
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.
GOSTEI 0
Rodc
14/11/2007
Acho que no Pascal deve ser posto ´var´ ao invés de ´&´ no parâmetro da função.
Segue outro exemplo:
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;
GOSTEI 0
Rodc
14/11/2007
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;
GOSTEI 0
Rodc
14/11/2007
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;
GOSTEI 0
Rodc
14/11/2007
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;
GOSTEI 0
Fabiano Góes
14/11/2007
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 !!!
GOSTEI 0
Rodc
14/11/2007
[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,
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,
GOSTEI 0
Pestana_
14/11/2007
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?
Fabiano Góes você tem razão a variavel mensagem não tem nada haver nesta rotiana é que eu esqueci de remover.
flw.
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.
GOSTEI 0
Fabiano Góes
14/11/2007
[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 !!!
GOSTEI 0
Micheus
14/11/2007
[b:8389d8fe04]Pestana_[/b:8389d8fe04], acho que não viram sua nova pergunta...
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:
apenas precisamos, limpar a lista antes de que ela seja populada.
Abraços
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;
Abraços
GOSTEI 0
Pestana_
14/11/2007
[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.
GOSTEI 0
Micheus
14/11/2007
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
GOSTEI 0
Pestana_
14/11/2007
valeu micheus, e obrigado a todos por ter ajudado !
abraços,
Pestana.
abraços,
Pestana.
GOSTEI 0