PDA

Ver la Versión Completa : Recorrer tree


FerCastro
09-08-2008, 15:50:45
Hola al foro

Tengo un tree y necesito recorrerlo para buscar los elementos que contiene. Estoy haciendo un procedimiento recursivo pero no consigo salir. bueno si salgo pero no recorro el árbol, me quedo en el primer nodo y de ahi no salgo.

Alguien ha hecho algo parecido que pudiera echarme una mano? agradezco la ayuda de antemano.

FCG
México

coso
09-08-2008, 16:16:52
Hola,
deberias recorrer la propiedad Items tal cual, no hace falta recursividad:



Memo1.Clear;
for i := 0 to treeview1.Count - 1 do
Memo1.Add(Treeview1.Items[i].Text);

FerCastro
09-08-2008, 16:35:45
Déjame te explico lo que quiero hacer:

Tengo un arbol el cual representa la estructura de una empresa, los nodos son departamentos y los hijos de estos son los empleados, y cada departamento puede a su vez tener departamentos anidados.

Lo que quiero hacer es buscar dentro de un departamento todos los empleados que contiene, incluidos los empleados que pudieran estar dentro de los departamentos que son hijos del departamento padre..

Ahora, no siempre inicio el recorrido en el nodo principal.

Espero haber sido claro.

FCG

felipe88
09-08-2008, 17:27:07
Hola,
Teniendo en cuenta que generalmente hay un nodo seleccionado, a partir de ahi seria el despliegue que necesitas; probando algo asi
procedure TForm1.Button1Click(Sender: TObject);
var p, i:Integer;
begin
for p:=TreeView1.Selected.Index to TreeView1.Items.Count - 1 do
begin
Memo1.Lines.Add(TreeView1.Items[p].Text);
end;
end;

Solo restaria determinar el valor a detenerse, el cual tendria el siguiente nodo padre, siguiendo este orden:

padre1
hijo1
hijo2
padre2 // Aca deberia detenerse el for.
hijo1
hijo2

Desconozco si cada nodo padre tenga su propio valor unico, de este modo no seria necesario implementar el for, y creo que lograrias lo que necesitas.

FerCastro
09-08-2008, 17:34:40
Hola Felipe.

El esquema es asi:

- Departamento Padre
- Departamento Uno
- Empleado
- Empleado
- Empleado
- Departamento Dos
- Empleado
- Empleado
- Departamento Tres
- Empleado
- Empleado
---- Departamento Cuatro
---- Empleado
---- Empleado

Por ejemplo, si elijes al departamento uno podríamos decir que es sencillo, pues solo haces el recorrido de los elementos del nodo elegido y todos serán empleados. Pero, si elijes el departamento 3 CREO que necesitas un procedimiento recursivo el cual seleccionará los elementos empleado del departamento tres, pero cuando encuentre que dentro de ese departamento existe otro departamento el proceso debe iniciar de nuevo, no?

No se si la recursividad sea forzosa para recorrer un tree, quiero creer que si.

Alguna idea?

Saludos y gracias

- Ya posteado no se nota, pero el departamento 4 está contenido dentro del departamento 3. Parece que no respeta espacios.

felipe88
09-08-2008, 17:55:33
Bueno, creo que es una buena solucion lo del procedimiento recursivo; pero a lo que yo me refiero es exactamente a lo que me dices pero cuando encuentre que dentro de ese departamento existe otro departamento el proceso debe iniciar de nuevo, no? entonces, ¿como determinamos que existe un nivel menor (hijo) o mayor (padre)?, no estoy muy seguro de como obtener esto (Parent, Children), de primera mano se me ocurre una condicion que al cumplirse ejecute de nuevo el procedimiento (Recursividad).

FerCastro
09-08-2008, 17:56:54
La recursividad funcionaba bien, lo que estaba utilizando mal era un método del objeto Nodo.

Agradezco la ayuda prestada y si alguien desea saber cómo lo hice con todo gusto lo aclaro.

Saludos!!

FCG

felipe88
09-08-2008, 18:01:06
Bueno, pues que bien... que esperas para compartirla ;)

FerCastro
09-08-2008, 18:25:58
- Aclaro, cuando creo el árbol identifico los empleados con ':.' al inicio del nombre, se que es no es una solución muy ortodoxa, y si alguien tiene una mejor le agradeceré me la haga saber.

No pongo el código de cuando mando el empleado a una tabla virtual y al grid, pues esto solo aplica a mi programa.

Si alguien quiere que le amplíe la explicación, o si alguien simplifica el código con todo gusto las sugerencias y preguntas son bienvenidas. Está comentado pero pudierab haber omitido algunos detalles.

Saludos!!


FCG








// la función recibe como parametro un nodo, que inicialmente es el nodo elegido al principio.

function TFReporte.TomaNodos(oNodo:TTreeNode): integer;
var
nCiclo: Integer;
cNombre: string;
nPos: Integer;
oNodoHijo : TTreeNode;
nLargo: Integer;
bEncuentra: Boolean;
Begin

// con este ciclo for recorremos todos los elementos del nodo que entra como parámetro
for nCiclo := 0 to oNodo.Count - 1 do
Begin
// tomamos el nodo que corresponde a la posición que indica el ciclo
oNodoHijo := oNodo.Item[nCiclo];

// Vamos a verificar si el nodo elegido es empleado
cNombre := oNodoHijo.Text;
nPos:=Pos(':.',cNombre);

// Si el nodo es un empleado, o para cualquier ejemplo práctico, si no es nodo padre dentro de un nodo padre
if nPos > 0 then
Begin

// Mandar el empleado al grid


end;
End
// De lo contrario el nodo es un departamento, o es un nodo padre dentro de un nodo padre
Else
Begin
// La función se llama así misma con un nuevo parámetro, ahora el nuevo nodo que puede contener hijos dentro de otro nodo.
TomaNodos(oNodoHijo);
End ;

End;

End;