Fórum Procedure recursivo fecha-me o dataset #290010
29/07/2005
0
Estou a usar +- o seguinte código abaixo para me montar o menu,
procedure fazmenu;
ibquery.open
while not ibquery.eof
if tipo = ´M´ then
montamenu(codigo,nil);
next
end.
end
procedure montamenu(codigo : int; menu : titemmenu
Qrmenu.sql.clear;
Qrmenu.sql.add(´Select menu where codigo = codigo´ break by ordem´);
query.open;
while not Qrmenu.eof do begin
if qrmenu.tipo = ´P´ then //programa
begin
NovoItem := TMenuItem.Create(MainMenu1);
NovoItem.Caption := MenuCaption;
MainMenu1.items.Add(novoitem);
end;
else begin
if qrmenu.tipo = ´S´ then //submenu
montamenu(codigo,novoitem);
end;
end;
end;
O programa funciona bem, mas quando tinho o submenu ele monta-me correctamente so que depois desligar o Dataset ibquery do primeiro procedure fazmenu.
Alguem sabe como resolver este problema.
Cumprimentos
portelinha@clix.pt
Porty
Curtir tópico
+ 0Posts
29/07/2005
Kotho
procedure montamenu(codigo : int; menu : titemmenu
var
vQrmenu: <Classe do componente, por exemplo TSQLQuery>;
begin
vQrmenu := <Classe>.Create(Self);
...
//defina as propriedades de conexão, e outras necessárias
...
...
//no final tem que destruir o objeto
...
FreeAndNil(vQrmenu);
end;
Gostei + 0
29/07/2005
Rjun
procedure fazmenu; begin ibquery.open; try while not ibquery.eof do begin if tipo = ´M´ then montamenu(codigo,nil); ibquery.next ; end; finally ibquery.Close; end; end; procedure montamenu(codigo : int; menu : titemmenu); begin Qrmenu.sql.clear; Qrmenu.sql.add(´Select menu where codigo = codigo´ break by ordem´); // <== não conheço essa cláusula break QrMenu.open; try while not Qrmenu.eof do begin if (qrmenu.FieldByName(´tipo´).Value = ´P´) then //programa begin NovoItem := TMenuItem.Create(MainMenu1); NovoItem.Caption := MenuCaption; MainMenu1.items.Add(novoitem); end; else if qrmenu.FieldByName(´tipo´) = ´S´ then //submenu montamenu(codigo,novoitem); end; finally Qrmenu.Close; end; end;
Gostei + 0
29/07/2005
Porty
por favor vê se consegues fazer algo.
procedure TForm1.MontaMenu(Grupo: String; Menu: TMenuItem);
var
Item: TMenuItem;
begin
qry.Close;
qry.SQL.Clear;
Qry.SQL.Add(´SELECT * FROM menu´);
Qry.SQL.Add(´WHERE GRUPO = ´ + Grupo );
Qry.SQL.Add(´ORDER BY ORDEM´);
Qry.Open;
while not Qry.Eof do begin
Item := TMenuItem.Create(nil);
Item.Caption := Qry.FieldByName(´TEXTO´).AsString;
Item.Tag := Qry.FieldByName(´CODIGO´).AsInteger;
if Qry.FieldByName(´TIPO´).AsString = ´M´ then
begin
try Menu1.items.Add(item);
if x2ficheiro1 <> nil then x2ficheiro1.Free;
menu := menu1.Items[qrymenu.FieldByName(´NIVEL´).asinteger];
except showmessage(´Erro ao criar ponto de menu´ + #13 + ´ID: ´ + qrymenu.FieldByName(´CODIGO´).asstring ); end;
end
else
if Qry.FieldByName(´TIPO´).AsString = ´S´ then
begin
Menu.Add(Item); MontaMenu(Qry.FieldByName(´link´).AsString, Item)
end
else
if Length(Trim(Qry.FieldByName(´LINK´).AsString)) > 0 then
begin
try Menu.Add(Item); Item.OnClick := MenuClick;
except showmessage(´Erro ao criar ponto de menu´ + #13 + ´ID: ´ + Qry.FieldByName(´CODIGO´).AsString );
end;
end;
Qry.Next;
end; // while not
item := nil;
Qry.Close;
end;
procedure TForm1.MenuClick(Sender: TObject);
var
Menu: TMenuItem;
Txt: String;
Qry: TQuery;
Frm: TForm;
Frc: TformClass;
begin
end;
procedure TForm1.Button1Click(Sender: TObject);
var menu: TMenuItem; i : integer;
begin
I := 0;
qrymenu.Close;
qrymenu.SQL.Clear;
qrymenu.SQL.Add(´SELECT * FROM menu´);
qrymenu.SQL.Add(´WHERE TIPO = ´ + #39 + ´M´ + 39 );
qrymenu.SQL.Add(´ ORDER BY NIVEL´);
qrymenu.Open;
qrymenu.First;
while not qrymenu.Eof do
begin
try
menu := menu1.Items[0];
except
showmessage(´Erro ao cirar menu´);
end;
MontaMenu(qrymenu.FieldByName(´GRUPO´).AsString, menu);
i := i + 1;
qrymenu.Next;
end;
end;
Gostei + 0
29/07/2005
Rjun
procedure TForm1.MontaMenu(Grupo: String; Menu: TMenuItem); var Item: TMenuItem; begin qry.SQL.Clear; Qry.SQL.Add(´SELECT * FROM menu WHERE GRUPO = ´ + Grupo + ´ORDER BY ORDEM´); Qry.Open; try while not Qry.Eof do begin Item := TMenuItem.Create(nil); Item.Caption := Qry.FieldByName(´TEXTO´).AsString; Item.Tag := Qry.FieldByName(´CODIGO´).AsInteger; try if Qry.FieldByName(´TIPO´).AsString = ´M´ then begin Menu1.items.Add(item); if x2ficheiro1 <> nil then x2ficheiro1.Free; menu := menu1.Items[qrymenu.FieldByName(´NIVEL´).asinteger]; end else if Qry.FieldByName(´TIPO´).AsString = ´S´ then begin Menu.Add(Item); MontaMenu(Qry.FieldByName(´link´).AsString, Item); end else if Length(Trim(Qry.FieldByName(´LINK´).AsString)) > 0 then begin Menu.Add(Item); Item.OnClick := MenuClick; end; except showmessage(´Erro ao criar ponto de menu´ + #13 + ´ID: ´ + Qry.FieldByName(´CODIGO´).AsString ); end; Qry.Next; end; // while not item := nil; finally Qry.Close; end; end; procedure TForm1.MenuClick(Sender: TObject); var Menu: TMenuItem; Txt: String; Qry: TQuery; Frm: TForm; Frc: TformClass; begin end; procedure TForm1.Button1Click(Sender: TObject); var menu: TMenuItem; i : integer; begin i := 0; //<== Variável sem utilidade nenhuma. qryMenu.Close; qrymenu.SQL.Clear; qrymenu.SQL.Add(´SELECT * FROM menu WHERE tipo = ´´M´´ ORDER BY nivel´); qrymenu.Open; while not qrymenu.Eof do begin try menu := menu1.Items[0]; MontaMenu(qrymenu.FieldByName(´GRUPO´).AsString, menu); i := i + 1; except showmessage(´Erro ao criar menu´); end; qrymenu.Next; end; end;
Gostei + 0
29/07/2005
Jairroberto
Não entendi porque vocês desconsideraram a resposta correta do Kotho!
Quando você chama recursivamente o procedimento ´MontaMenu´ de dentro do loop pelos dados do componente denominado ´Qry´, logo na primeira linha do ´MontaMenu´ a chamada recursiva fecha automaticamente o ´Qry´ por limpar o conteúdo da sua propriedade ´SQL´ (Qry.SQL.Clear;). Para conseguir fazer essa chamada recursiva é preciso ter uma variável local no procedimento ´MontaMenu´ do tipo ´TQuery´ (ou outro que seja utilizado). Veja uma parte do código modificado:
procedure TForm1.MontaMenu(Grupo: String; Menu: TMenuItem);
var
Item: TMenuItem;
Qry: TQuery;
begin
Qry := TQuery.Create(Self);
try
// Ajuste a linha abaixo com o DatabaseName correto
Qry.DatabaseName := ´NomeDoDatabase´;
Qry.SQL.Add(´SELECT * FROM menu WHERE GRUPO = ´ + Grupo + ´ORDER BY ORDEM´);
Qry.Open;
try
while not Qry.Eof do
begin
...
{ Esta chamada recursiva cria outro componente Qry,
mantendo aberto o que foi criado no escopo atual }
MontaMenu(Qry.FieldByName(´link´).AsString, Item);
...
Qry.Next;
end;
finally
Qry.Close;
end;
finally
Qry.Free;
end;
end;
Um abraço,
Jair
Gostei + 0
29/07/2005
Porty
Não entendi porque vocês desconsideraram a resposta correta do Kotho! Quando você chama recursivamente o procedimento "MontaMenu" de dentro do loop pelos dados do componente denominado "Qry", logo na primeira linha do "MontaMenu" a chamada recursiva fecha automaticamente o "Qry" por limpar o conteúdo da sua propriedade "SQL" (Qry.SQL.Clear;). Para conseguir fazer essa chamada recursiva é preciso ter uma variável local no procedimento "MontaMenu" do tipo "TQuery" (ou outro que seja utilizado). Veja uma parte do código modificado:
Atenção pessoal a Query que é fechada é a QryMenu e não da qry do procedimento montamenu.
Um abraço,
Gostei + 0
29/07/2005
Porty
Já Funcionou com a dica do JairRoberto. Mas tenho agora uma pequena dúvida quando ele diz para
qry.DatabaseName := //coloca o nome da bd
tive que criar no BDE o alias para o caminho da base dados firebird.
Se no meu projecto já tenho uma ligação directa com o TIBdatabase não posso associar a query? E que assim tenho que definir sempre o alias no BDE.
Obrigada
Gostei + 0
29/07/2005
Jairroberto
A ´QryMenu´ você fecha explicitamente, já a ´Qry´ do ´MontaMenu´ é fechada automaticamente quando você atribui um novo valor para a propriedade ´SQL´. Leia novamente a minha resposta com atenção para entendê-la melhor.
Sobre o ´DatabaseName´, ajustei o exemplo de acordo com os elementos que você passou na pergunta, por isso supus que você estivesse usando TQuery (BDE). Mas se você está usando IBX, é só adaptar os componentes e suas propriedades:
var Qry: TIBQuery; begin Qry := TIBQuery.Create(Self); try Qry.Database := IBDatabase1; Qry.Transaction := IBTransaction1; Qry.SQL.Add(´SELECT * FROM menu WHERE GRUPO = ´ + Grupo + ´ORDER BY ORDEM´); ...
Um abraço,
Jair
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)