Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Como cargar los un TreeView desde una tabla SQL (https://www.clubdelphi.com/foros/showthread.php?t=95884)

Diego200519 23-09-2022 23:06:04

Como cargar los un TreeView desde una tabla SQL
 
Hola a todos, como estan?, espero me puedan ayudar con el siguiente problema :confused:, pasa que quiero agregar un TTreeView a mi programa que muestre las instancias y sub instancias de un inventario, es decir, que lo muestre algo así:

+Instancia1
-SubInstancia1.1
-SubInstancia1.2
+Instancia2
-SubInstancia2.1
-SubInstancia2.2

Pero necesito que tome los datos de una tabla la cual esta en SQL, la tabla esta estructurada de la siguiente manera:
CREATE TABLE [dbo].[SAINSTA](
[CodInst] [int] IDENTITY(1,1) NOT NULL,
[InsPadre] [int] NOT NULL,
[Nivel] [int] NOT NULL,
[TipoIns] [smallint] NOT NULL,
[Descrip] [varchar](40) NOT NULL,
[Descto] [decimal](28, 4) NOT NULL,
[DEsComp] [smallint] NOT NULL,
[DEsSeri] [smallint] NOT NULL,
[DEsLote] [smallint] NOT NULL,
[DEsComi] [smallint] NOT NULL,
[DEsCorrel] [smallint] NOT NULL,
[DigitosC] [smallint] NOT NULL,
[DEsTabla] [smallint] NOT NULL,
[CodAlte] [varchar](15) NULL,

Donde Descrip es el nombre de la instancia, InsPadre seria lo que indica el nodo padre de la instancia y CodInst es el codigo individual de cada una, o mejor dicho, el nodo.

He probado usando este codigo que encontre en un foro parecido:
procedure TfPruebaComponentes.FormCreate(Sender: TObject);
var
i,x,n:integer;
Nod : TTreeNode;
NodSuplementario : TTreeNode;
MiPunteroInteger : ^integer;
begin
FDQuery1.Close;
FDQuery1.Open;
FDQuery1.Last;
n:=FDQuery1.RecordCount;
FDQuery1.First;
for x:=0 to (n-1) do
begin
i:=FDQuery1.FieldByName('nodo_padre').AsInteger;
if i=0 then
begin
Nod:=TreeView1.Items.Add (nil,FDQuery1.FieldByName('opc_Descripcion').asstring);
New(MiPunteroInteger);
MiPunteroInteger^:=FDQuery1.Fieldbyname('nodo').asinteger;
nod.Data:=MiPunteroInteger;
nod.Selected :=true;
end
Else
begin
n:=TreeView1.Items.Count-1;
While MiPunteroInteger(TreeView1.Items[n].Data)^ <> i do
Dec(n);
nodSuplementario:=TreeView1.Items.AddChild(TreeView1.Items[N],FDQuery1.FieldByName('opc_Descripcion').asstring);
New(MiPunteroInteger);
MiPunteroInteger^:= FDQuery1.Fieldbyname('nodo').asinteger;
nodSuplementario.Data:=MiPunteroInteger;
Nod.selected:=True;
Nod.Expanded:=False;
end;
FDQuery1.Next;
end;
end;

Pero la verdad no me sirve bien y incluso me marca un error de compilación en el While do :(.

He estado buscando por mucho y la verdad espero que me lean y me puedan ayudar con este problema muchas gracias :D:D.

cloayza 24-09-2022 01:58:33

Estimado Diego200519, bienvenido a club delphi...lea la guía de estilo...lo llamaran al orden en breve...

Casimiro Notevi 24-09-2022 13:06:17

Cita:

Empezado por cloayza (Mensaje 548466)
Estimado Diego200519, bienvenido a club delphi...lea la guía de estilo...lo llamaran al orden en breve...

Tiene perdón por ser nuevo :D
Pero sí, no olvides leer nuestra guía de estilo, gracias.
Y recuerda usar las etiquetas cuando pongas código, por ejemplo:

bucanero 26-09-2022 11:46:15

hola!,
intentalo con esta rutina

Código:


uses
  System.Generics.Collections;

...

procedure LoadTreeViewFromDataset(TreeView: TTreeView; dataset: TDataSet);
var
  id, parent_id: integer;
  nombre: string;
  parentNode, TreeNode: TTreeNode;
begin
  /// genera una lista temporal de indices para acceder a los nodos por su ID
  with Tdictionary<Integer, TTreeNode>.create do
  try
    dataset.First;
    while not dataset.Eof do begin
      /// -- Aqui lee los datos de la tabla del nodo que se va a crear
      id := dataset.FieldByName('id').AsInteger;
      parent_id := dataset.FieldByName('parent_id').Value;
      nombre := dataset.FieldByName('nombre').Value;
      /// ---

      // comprueba si existe el nodo padre
      if not TryGetValue(parent_id, parentNode) then
        parentNode := nil;

      // genera el nuevo nodo
      TreeNode := TreeView.Items.AddChild(parentNode, nombre);
      // inserta un puntero al id de la tabla, por si mas tarde se desea localizar el registro nuevamente
      TreeNode.Data := pointer(id);

      // lo inserta en la lista de indices
      AddOrSetValue(id, TreeNode);
      dataset.next;
    end;
  finally
    /// Libera la lista de indices
    free;
  end;
end;

procedure TForm2.ButtonLeerTreeViewClick(Sender: TObject);
begin
  try
    TreeView1.Items.BeginUpdate;
    FDQuery1.disableControls;
    if not FDQuery1.active then
      FDQuery1.open;
    LoadTreeViewFromDataset(TreeView1, FDQuery1);
  finally
    FDQuery1.close;
    FDQuery1.enableControls;
    TreeView1.Items.endUpdate;
  end;
end;

IMPORTANTE: para no tener problemas con la lectura del arbol desde una consulta SQL es necesario que los resultados se muestren ordenados por el campo padre, ID.

EJEMPLO:
Código SQL [-]
SELECT id, parent_id, nombre
  FROM tabla_arbol
 WHERE id >= parent_id
ORDER BY parent_id, id

Diego200519 05-12-2022 15:25:37

Buenos días bucanero, me complace decirte que la solución que me has propuesto me funciono :D, lamento no haber visto tu respuesta antes, pero si, efectivamente es lo que estaba buscando, mil gracias :D ^\||/


La franja horaria es GMT +2. Ahora son las 07:44:33.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi