Ir al contenido


Foto

[RESUELTO] Los árboles que no dejan ver el bosque. (TTreeView con datos de una tabla)


  • Por favor identifícate para responder
31 respuestas en este tema

#1 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 10 marzo 2010 - 01:37

Chavos:

Resulta que ahora debo llenar un TTreeView con los datos de una tabla, con una profundidad de cuatro ramas...

Es decir:
Sector
        |_SubSector
                        |_Oficina
                                    |_Encargado


Y del encargado, mostrar sus datos en DbEdit's o Edit's. Los "cortes" están definidos perfectamente puesto que en cualquier momento puedo "saber" dónde me encuentro, pero llenar el TTreeView se me ha complicado por que no sé manejarlo.Chapuceramente he diseñado algo así:
[/]


delphi
  1. procedure TfrmPrncpl.LlnrArblArs;
  2. var
  3.   tnSuperior, tnPadre, tnHijo, tnNieto, tnGato : TTreeNode;
  4.   sInsttcn, sDrccnGnrl, sDrccn, sSubDrccn : string;
  5. begin
  6.   TreVewArblArs.Items.Clear;
  7.   tnSuperior := TreVewArblArs.Items.Add(NIL,'Gobierno del Distrito Federal');
  8.  
  9.   dtamdlDts.ADOQryDts.First;
  10.   tnPadre := TreVewArblArs.Items.AddChild(tnSuperior,dtamdlDts.ADOQryDts.FieldByName('Ca_area').AsString);
  11.   sInsttcn := dtamdlDts.ADOQryDts.FieldByName('Ca_institucion').AsString;
  12.   sDrccnGnrl := dtamdlDts.ADOQryDts.FieldByName('Ca_DirG').AsString;
  13.   sDrccn := dtamdlDts.ADOQryDts.FieldByName('Ca_Dir').AsString;
  14.   sSubDrccn := dtamdlDts.ADOQryDts.FieldByName('Ca_Sub').AsString;
  15.   dtamdlDts.ADOQryDts.Next;
  16.  
  17.   while not dtamdlDts.ADOQryDts.Eof do
  18.   begin
  19.     if sInsttcn = dtamdlDts.ADOQryDts.FieldByName('Ca_institucion').AsString then
  20.     begin
  21.       tnGato := TreVewArblArs.Items.AddChild(tnPadre,dtamdlDts.ADOQryDts.FieldByName('Ca_area').AsString);
  22.       dtamdlDts.ADOQryDts.Next;
  23.     end
  24.     else
  25.     begin
  26.       tnPadre := TreVewArblArs.Items.AddChild(tnSuperior,dtamdlDts.ADOQryDts.FieldByName('Ca_area').AsString);
  27.       sInsttcn := dtamdlDts.ADOQryDts.FieldByName('Ca_institucion').AsString;
  28.     end;
  29.   end;
  30.   dtamdlDts.ADOQryDts.First;
  31.  
  32.     TreVewArblArs.FullExpand;
  33. end;

[][]

Pero como pueden ver, es demasiado "sucio" como para quedar elegante. Además que no es recursivo ni permite adaptarse a algún cambio en la estructura..., ¿alguna idea que pueda ayudarme? [/][/]

  • 0

#2 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.266 mensajes
  • LocationCosta Rica

Escrito 10 marzo 2010 - 01:58

Hola
Me encontré este ejemplo de treeview que hace un manejo interesante de la bd,
No es mio, me lo encontré por ahí, tal vez te sirva de algo.
Saludos
PD: No es tu caso, pero creo que esta interesante. (y)

Archivos adjuntos


  • 0

#3 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 10 marzo 2010 - 02:03

...PD: No es tu caso, pero creo que esta interesante. (y)


Sí, es muy interesante..., tan interesante que fue uno de los primeros ejemplos que encontré y comencé a desmenuzar anoche para construir éste mamotreto que me pidieron. Pero como bien dices, no me ayuda a solucionar mi caso.

Gracias por tu ayuda, muy valiosa.
  • 0

#4 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 10 marzo 2010 - 02:07

Saludos.

TiammatMX, las JEDI tienen un TJvDBTreeView, no lo he utilizado pero quizás te pueda servir.


  • 0

#5 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 10 marzo 2010 - 02:15

...las JEDI tienen un TJvDBTreeView, no lo he utilizado pero quizás te pueda servir.


Yo también lo intenté, pero resulta que aún no está "maduro" el componente y jamás respondió. De hecho, un par de veces "colgó" a Delphi. Y obviamente, no lo utilicé más.
  • 0

#6 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 10 marzo 2010 - 02:26

Saludos.

Chanfle quizás tienes un montón de datos y puede ser lo que mencionas sobre no estar maduro (aunque lo verde hace daño a menos que sea Dolares).

Tengo este ejemplo de como llevar un TMenu a un TTreeView y puede que te ayude:



delphi
  1. function TForm1.Retira(Str: String; Chr: Char): String;
  2. var
  3.   i: Integer;
  4. begin
  5.   Result:='';
  6.   for i:=1 to Length(Str) do
  7.     begin
  8.       if Str[i]<>Chr then
  9.         Result:=Result+Str[i];
  10.     end;
  11. end;
  12.  
  13. procedure TForm1.MenuToTreeView;
  14. var
  15.   i: Integer;
  16.   Root,Node: TTreeNode;
  17.  
  18. procedure SubItems(MenuItem: TMenuItem; ParentNode: TTreeNode);
  19. var
  20.   i: Integer;
  21.   Node: TTreeNode;
  22. begin
  23.   for i:=0 to MenuItem.Count-1 do
  24.     begin
  25.       if MenuItem.Items[i].Caption='-' then
  26.         Continue;
  27.           Node:=TreeView1.Items.AddChild(ParentNode,Retira(MenuItem.Items[i].Caption,'&'));
  28.           Node.Data:=MenuItem.Items[i];
  29.           if MenuItem.Items[i].Count>0 then
  30.             SubItems(MenuItem.Items[i],Node);
  31.   end;
  32. end;
  33.  
  34. begin
  35.   TreeView1.Items.Clear;
  36.   Menu:=NIL; // turns off the main menu
  37.   Root:=TreeView1.Items.Add(NIL,'Menu');
  38.   for i:=0 to MainMenu1.Items.Count-1 do
  39.     begin
  40.           Node:=TreeView1.Items.AddChild(Root,Retira(MainMenu1.Items[i].Caption,'&'));
  41.           Node.Data:=MainMenu1.Items[i];
  42.           if MainMenu1.Items[i].Count>0 then
  43.             SubItems(MainMenu1.Items[i],Node)
  44.     end;
  45.   TreeView1.FullExpand;
  46. end;


  • 0

#7 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 10 marzo 2010 - 02:28

Pues aquí te dejo una idea de un código mío que tengo por ahí, ésta llena dos niveles (Padre e Hijo) pero puedes agregar más:



delphi
  1. Var
  2.     I,CampoCount:Integer;
  3.     Nodo:Packed Array[0..99] of TTreenode;
  4.     NodoValor:Packed array[0..99] of Variant;
  5. begin
  6.     TreeView1.Items.Clear;
  7.     ZDptos.First;
  8.     CampoCount:=ZDptos.FieldCount;
  9.     While not ZDptos.Eof do
  10.     begin
  11.         if NodoValor[0]<> ZDptos.Fields[0].Value then
  12.             Nodo[0]:=TreeView1.Items.Add(nil,Vartostr(ZDptos.Fields[0].Value));
  13.         for I:=1 to ZDptos.FieldCount-1 do
  14.         begin
  15.             if NodoValor[i]<> ZDptos.Fields[i].Value then
  16.                 Nodo[i]:=TreeView1.Items.AddChild(Nodo[I-1],Vartostr(ZDptos.Fields[i].Value));
  17.         Nodo[i].Data := pointer(ZDptos.FieldByName('ID').AsInteger);
  18.       if Nodo[i].Level = 2 then
  19.         begin
  20.           Nodo[i].Delete;
  21.         end;
  22.               NodoValor[i]:=ZDptos.Fields[i].Value;
  23.         end;
  24.         NodoValor[0]:=ZDptos.Fields[0].Value;
  25.         ZDptos.next;
  26.     end;



Espero te sea de utilidad.

Saludos.
  • 0

#8 andres1569

andres1569

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 431 mensajes

Escrito 10 marzo 2010 - 02:29

Hola TiammatMX,

en primer lugar, supongo que la tabla en cuestión está ordenada de forma que después de cada nivel le siguen los subniveles correspondientes, y así hasta llegar al último, después del cual empieza otra vez ¿con el nivel superior (sector)? ¿puede ser que al acabar con el nivel 4 (encargado) siga con nodos hermanos del nivel 3 (oficina) al estilo de un arbol de directorios?

¿Qué campo empleas para saber el nivel en que estás situado? Veo que comparas el campo 'Ca_institucion' para saber sin has cambiado de nivel, ¿es este campo o hay más campos que comparar?

Saludos
  • 0

#9 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 10 marzo 2010 - 02:41

...en primer lugar, supongo que la tabla en cuestión está ordenada de forma que después de cada nivel le siguen los subniveles correspondientes, y así hasta llegar al último, después del cual empieza otra vez ¿con el nivel superior (sector)...


Correctísimo, es un ADOQuery que está ordenado por los campos que serán considerados como cortes y cambios.

...¿puede ser que al acabar con el nivel 4 (encargado) siga con nodos hermanos del nivel 3 (oficina) al estilo de un arbol de directorios?...


De hecho, como están ordenados por cuatro columnas, el query me permite "saber" en cualquier momento cuándo hay que hacer un corte. Así, sería como un árbol de directorios de cuatro niveles.

...¿Qué campo empleas para saber el nivel en que estás situado? Veo que comparas el campo 'Ca_institucion' para saber sin has cambiado de nivel, ¿es este campo o hay más campos que comparar?...


Las columnas te las listo a continuación:
sInsttcn, sDrccnGnrl, sDrccn, sSubDrccn. sInsttcn es el primer corte y con el que estaba probando que todo funcionara correctamente.
  • 0

#10 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 10 marzo 2010 - 02:45

Pues aquí te dejo una idea de un código mío que tengo por ahí, ésta llena dos niveles (Padre e Hijo) pero puedes agregar más...

Es excelente..., pero soy medio tonto (aún no domino éste condenado componente TTreeView), ¿dónde le puedo añadir los demás niveles?, ilústrame, por favor.
  • 0

#11 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 10 marzo 2010 - 02:46

Saludos.

Chanfle quizás tienes un montón de datos y puede ser lo que mencionas sobre no estar maduro (aunque lo verde hace daño a menos que sea Dolares).

Tengo este ejemplo de como llevar un TMenu a un TTreeView y puede que te ayude:


Gracias, Rolphy. Lo probaré de inmediato.
  • 0

#12 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 10 marzo 2010 - 03:20

Puedes estudiar este código que despliega el árbol de directorios de los discos del sistema incluidos los archivos.

Te dejo un ejemplo simple y rápido de como llenar un árbol:



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   n, i: integer;
  4.   Nodo: TTreeNode;
  5. begin
  6.  
  7.   for n:= 0 to 10 do
  8.   begin
  9.       Nodo:= nil;
  10.       for i:=0 to 4 do
  11.       begin
  12.         Nodo:= TreeView1.Items.AddChild(Nodo, IntToStr(i));
  13.       end;
  14.   end;
  15.   TreeView1.FullExpand;
  16.  
  17. end;



Saludos.
  • 0

#13 kafastoforman

kafastoforman

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 277 mensajes
  • LocationMexico D.F.

Escrito 10 marzo 2010 - 06:28

Hola tiammat, segun lo que te entendi, se me ocurrio hacer esto que tal vez te pueda ayudar:



delphi
  1. procedure TForm1.AddItemsFromQuery(const aColumna: integer;
  2.   const aPadre: TTreeNode; const aQuery: TAdoQuery);
  3.  
  4.   var lPadre: TTreeNode;
  5.  
  6. begin
  7.  
  8. if aColumna >= aQuery.Fields.Count then //Verificamos que la columna pasada exista
  9.   begin
  10.     aQuery.Next;
  11.     exit;
  12.   end;
  13.  
  14.   if trim(aQuery.Fields[aColumna].AsString) = '' then //Verificamos que tenga un valor
  15.   begin
  16.     aQuery.Next;
  17.     exit;
  18.   end;
  19.  
  20.   while not aquery.Eof do
  21.   begin
  22.  
  23.     if (aPadre = nil) then
  24.       AddItemsFromQuery(aColumna+1,
  25.                           TreeView1.Items.AddChild(aPadre,aQuery.Fields[aColumna].AsString),
  26.                           aQuery)
  27.     else
  28.       if aPadre.Text <> aQuery.Fields[aColumna - 1].AsString then
  29.         break
  30.       else
  31.         AddItemsFromQuery(aColumna+1,
  32.                           TreeView1.Items.AddChild(aPadre,aQuery.Fields[aColumna].AsString),
  33.                           aQuery);
  34.  
  35.   end;
  36.  
  37. end;
  38.  
  39. procedure TForm1.Button1Click(Sender: TObject);
  40. begin
  41.  
  42.   TreeView1.Items.Clear;
  43.   AddItemsFromQuery(0,nil,ADOQuery1);
  44.  
  45. end;



Segun la estructura de datos que yo probe y resulto fue la siguiente:

mexico df xochimilco concha angel
mexico df xochimilco concha armando
mexico df xochimilco concha gonzalez
mexico df ao roma gerardo
mexico df ao roma martinez
mexico df ao villas pancho
mexico df ao villas lopez
mexico chiapas municipio pueblo rodrigo
mexico chiapas municipio publito escamilla
españa madrid versa micolonia antonio
españa barcelona catalunia pueblochico raafel

Saludos

Kafastoforman
  • 0

#14 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 11 marzo 2010 - 09:25

Hola tiammat, segun lo que te entendi, se me ocurrio hacer esto que tal vez te pueda ayudar:
.
.
.

Segun la estructura de datos que yo probe y resulto fue la siguiente:

mexico  df  xochimilco  concha  angel
mexico  df  xochimilco  concha  armando
mexico  df  xochimilco  concha  gonzalez
mexico  df  ao  roma  gerardo
mexico  df  ao  roma  martinez
mexico  df  ao  villas  pancho
mexico  df  ao  villas  lopez
mexico  chiapas  municipio  pueblo  rodrigo
mexico  chiapas  municipio  publito  escamilla
españa  madrid  versa  micolonia  antonio
españa  barcelona  catalunia  pueblochico  raafel


¡¡EXCELENTE, KASTAFORMAN!!, de hecho, se aproxima mucho al requerimiento...

Solamente que yo desearía algo así:
(mexico  df  xochimilco  concha)  angel
(mexico  df  xochimilco  concha)  armando
(mexico  df  xochimilco  concha)  gonzalez
(mexico  df  ao  roma)  gerardo
(mexico  df  ao  roma)  martinez
(mexico  df  ao  villas)  pancho
(mexico  df  ao  villas)  lopez
(mexico  chiapas  municipio  pueblo)  rodrigo
(mexico  chiapas  municipio  publito)  escamilla
(españa  madrid  versa  micolonia)  antonio
(españa  barcelona  catalunia  pueblochico)  raafel

Donde lo que se encuentra entre paréntesis no debe aparecer. Estoy en lo dicho, seguiré sus consejos.
  • 0

#15 andres1569

andres1569

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 431 mensajes

Escrito 11 marzo 2010 - 09:57

TiammatMX, no entiendo que no quieras quen salga lo que está entre paréntesis, supongo que te refieres a que no aparezca todo en la misma linea, aunque sí escalonado: ¿Algo como esto?

mexico 
        df 
          xochimilco 
                  concha 
                          angel
                          armando
                          gonzalez
          ao 
                  roma 
                          gerardo
                          martinez
          ao 
                  villas 
                          pancho


etc.
  • 0

#16 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 11 marzo 2010 - 10:07

De hecho, el resultado actual es el que se muestra en la ilustración. Pero si se dan cuenta, se repiten las ramas, por que el contenido de la etiqueta no se ha modificado.

La idea es compactar el resultado a una línea por registro, pero conservando la "arborización" del contenido.

Archivos adjuntos


  • 0

#17 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 11 marzo 2010 - 10:40

Y perdón, se me olvidó poner el código..., casi nada...  :p :p



delphi
  1. procedure TfrmPrncpl.LlnrArblArs;
  2. var
  3.   i, count, L_Acc_Fieldcount : Integer;
  4.   L_Acc_Treenode : Packed Array[0..99] of TTreenode;
  5.   L_Acc_value : Packed array[0..99] of Variant;
  6. begin
  7.   TreVewArblArs.Items.Clear;
  8.   L_Acc_Treenode[0]:= TreVewArblArs.Items.Add(NIL,'Gobierno del Distrito Federal');
  9.   dtamdlDts.ADOQryDts.First;
  10.   L_Acc_Fieldcount := dtamdlDts.ADOQryDts.FieldCount;
  11.  
  12.   while not dtamdlDts.ADOQryDts.Eof do
  13.   begin
  14.  
  15.     if L_Acc_Value[0] <> dtamdlDts.ADOQryDts.Fields[0].Value then
  16. //      L_Acc_Treenode[0] := TreVewArblArs.Items.Add(nil,Vartostr(dtamdlDts.ADOQryDts.Fields[0].Value));
  17.       L_Acc_Treenode[0] := TreVewArblArs.Items.Add(nil,VarToStr(dtamdlDts.ADOQryDts.FieldByName('ca_area').Value));
  18.  
  19.     for i := 1 to dtamdlDts.ADOQryDts.FieldCount -2 do
  20.     begin
  21.             if L_Acc_Value[i] <> dtamdlDts.ADOQryDts.Fields[i].Value then
  22. //                L_Acc_Treenode[i] := TreVewArblArs.Items.AddChild(L_Acc_Treenode[i-1],Vartostr(dtamdlDts.ADOQryDts.Fields[i].Value));
  23.                 L_Acc_Treenode[i] := TreVewArblArs.Items.AddChild(L_Acc_Treenode[i-1],VarToStr(dtamdlDts.ADOQryDts.FieldByName('ca_area').Value));
  24.  
  25.             L_Acc_Value[i] := dtamdlDts.ADOQryDts.Fields[i].Value;
  26.         end;
  27.         L_Acc_Value[0] := dtamdlDts.ADOQryDts.Fields[0].Value;
  28.  
  29.     dtamdlDts.ADOQryDts.Next;
  30.   end;
  31.   dtamdlDts.ADOQryDts.First;
  32.  
  33.     TreVewArblArs.FullExpand;
  34. end;


  • 0

#18 andres1569

andres1569

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 431 mensajes

Escrito 11 marzo 2010 - 10:57

Hola de nuevo,

Lo que pongo aquí es una forma recursiva de afrontar el asunto, teniendo en cuenta que los datos se toman de una consulta SQL y que por lo tanto tiene muchas columnas repetidas que hay que ir comparando desde la primera hasta la de mayor detalle (encargado). Esto condiciona la forma de abordarlo, ya que otras veces se tienen las 4 tablas por separado y con un master-detail se realiza todo de forma más cómoda.

No lo he probado ya que no tengo ahora una tabla donde hacer probaturas, así que ya me dirás qué resultado arroja (si hay algún cuelgue o bucle inifinito, mis excusas de antemano  :cheesy:  :embarrassed:)

Le he añadido un parámetro CampoClave, donde se le puede pasar el campo que actúa de clave de encargados, en caso de ser numérico se almacena también en el último nodo de cada rama para que al hacer click puedas localizar el registro en la tabla.



delphi
  1. function TfrmPrncpl.AnadeNodo(NodoPadre: TTreeNode; Table: TDataSet;
  2.   NivelActual: Word; CampoClave: TField; Campos: array of TField;
  3.   var Valores: array of variant) : Integer;
  4. var
  5.   i : Integer;
  6.   Nodo : TTreeNode;
  7. begin
  8.   result := NivelActual;
  9.   while (result = NivelActual) AND NOT Table.EOF do
  10.   begin
  11.     // creamos un nuevo nodo dependiente del NodoPadre y le asignamos el valor
  12.     // del campo actual.
  13.     // NOTA: En caso de que haya un CampoClave y que estemos situados en el
  14.     //      último campo, utilizamos el método AddChildObject para asignarle
  15.     //      además un valor (mapeando de Integer a Pointer) que represente a la
  16.     //      la clave primaria del registro actual y que nos servirá para que cuando
  17.     //      el usuario pinche en dicho nodo podamos desplazarnos hasta esa posición
  18.     //      en el Dataset, suponiendo que dicha clave exista y que sea numérica ?¿
  19.     with TreVewArblArs.Items do
  20.       if (CampoClave <> nil) AND (result = High(Campos)) then
  21.         Nodo := AddChildObject(NodoPadre, Campos[result].AsString, Pointer(CampoClave.AsInteger))
  22.       else Nodo := TreVewArblArs.Items.AddChild(NodoPadre, Campos[result].AsString);
  23.     // Si no estamos aún en el último nivel, icrementamos result y nos vamos al
  24.     // siguiente nivel mediante una llamada recursiva, enviándole como NodoPadre
  25.     // el Nodo que acabamos de crear ...
  26.     if result < High(Campos) then
  27.     begin
  28.       Inc(result);
  29.       result := AnadeNodo(Nodo, Table, result, CampoClave, Campos, Valores);
  30.     end
  31.     // ... y si estamos ya en el último nivel, memorizamos los valores anteriores,
  32.     // luego avanzamos un registro en la tabla y recorremos la lista de campos
  33.     // desde el primero comparando con los valores anteriores para averiguar a
  34.     // qué nivel debemos descender para crear el siguiente nodo
  35.     else begin
  36.       for i:=0 to High(Campos) do Valores[i] := Campos[i].Value;
  37.       Table.Next;
  38.       if NOT Table.EOF then
  39.         for result:=0 to High(Campos) do
  40.           if Campos[result].Value <> Valores[result] then break;
  41.     end;
  42.   end;
  43. end;
  44.  
  45. procedure TfrmPrncpl.LlnrArblArs;
  46. var
  47.   i : Integer;
  48.   tnSuperior, tnPadre : TTreeNode;
  49.   FldClave, FldInsttcn, FldDrccnGnrl, FldDrccn, FldSubDrccn : TField;
  50.   Valores: array of variant;
  51. begin
  52.   TreVewArblArs.Items.BeginUpdate;  // para evitar que se actualice el TreeView a cada nodo creado
  53.   try
  54.     TreVewArblArs.Items.Clear;
  55.     tnSuperior := TreVewArblArs.Items.Add(NIL, 'Gobierno del Distrito Federal');
  56.     dtamdlDts.ADOQryDts.First;
  57.     tnPadre := TreVewArblArs.Items.AddChild(tnSuperior, dtamdlDts.ADOQryDts.FieldByName('Ca_area').AsString);
  58.  
  59. // almacenamos en variables las referencias a los campos involucrados, para
  60. // ganar en velocidad
  61.     FldClave := dtamdlDts.ADOQryDts.FieldByName('ID_CLAVE');
  62.  
  63.     FldInsttcn := dtamdlDts.ADOQryDts.FieldByName('Ca_institucion');
  64.     FldDrccnGnrl := dtamdlDts.ADOQryDts.FieldByName('Ca_DirG');
  65.     FldDrccn := dtamdlDts.ADOQryDts.FieldByName('Ca_Dir');
  66.     FldSubDrccn := dtamdlDts.ADOQryDts.FieldByName('Ca_Sub');
  67.  
  68. // inicializamos la matriz de valores
  69.     SetLength(Valores, 4);
  70.     for i:= 0 to 3 do Valores[i] := null;
  71. // lanzamos la función recursiva pasándole 0 como nivel inicial, y el nodo padre
  72.     AnadeNodo(tnPadre, dtamdlDts.ADOQryDts, 0, FldClave, [FldInsttcn,
  73.               FldDrccnGnrl, FldDrccn, FldSubDrccn], Valores);
  74.   finally
  75.     TreVewArblArs.Items.EndUpdate;
  76.   end;
  77.   TreVewArblArs.FullExpand;
  78. end;




  • 0

#19 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 11 marzo 2010 - 11:16

...Lo que pongo aquí es una forma recursiva de afrontar el asunto, teniendo en cuenta que los datos se toman de una consulta SQL y que por lo tanto tiene muchas columnas repetidas que hay que ir comparando desde la primera hasta la de mayor detalle (encargado). Esto condiciona la forma de abordarlo, ya que otras veces se tienen las 4 tablas por separado y con un master-detail se realiza todo de forma más cómoda.
...


Gracias..., es una excelente idea. Voy a probarlo de inmediato y te platico los resultados. Ya me urge terminar con ésto para avanzar, que me están bufando para que me apure...  :embarrassed: :cry: :sad:
  • 0

#20 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 11 marzo 2010 - 11:48

Lo que pongo aquí es una forma recursiva de afrontar el asunto...


Gracias por el esfuerzo, andres1569..., pero el resultado es igual a lo que tengo desde ayer...

Archivos adjuntos


  • 0




IP.Board spam blocked by CleanTalk.