Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 22-03-2014
jesconsa jesconsa is offline
Miembro
 
Registrado: dic 2009
Posts: 30
Poder: 0
jesconsa Va por buen camino
VirtualTreeView

Ok, disculpa Casimiro.

Gracias
Saludos
Responder Con Cita
  #2  
Antiguo 22-03-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.044
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por jesconsa Ver Mensaje
Saludos

Le he cambiado el título para que sea más fácil de identificar por quien pueda ayudar.
Si prefieres otro título, lo dices
Responder Con Cita
  #3  
Antiguo 23-03-2014
Avatar de pacopenin
pacopenin pacopenin is offline
Miembro
 
Registrado: sep 2010
Ubicación: Asturias
Posts: 382
Poder: 14
pacopenin Va por buen camino
Hola Jesús. Hace muchos años que no uso VST, pero mirando un proyecto antiguo te mando lo que hacía para cargar un árbol de un sólo nivel. No llegué a explorar mucho más allá. A ver si te sirve.

Código SQL [-]
procedure TFListados.iniciaArbol;
var
  Data1 : PEntryData;
  Node1: PVirtualNode;
  NewNode : PVirtualNode;
begin

     VST.BeginUpdate;
     VST.Clear;

     VST.RootNodeCount := 0;

     Node1 := VST.AddChild(VST.RootNode);

     Data1 := PEntryData(VST.GetNodeData(Node1));
     Data1.Titulo := 'Listados';

     Dat.cdInf.close;
     Dat.cdInf.Params.ParamByName('GRUPO').asInteger := Grupo;
     Dat.cdInf.open;

     VST.Selected[VST.TopNode] := true;
     VST.FocusedNode := VST.TopNode;

     while NOT Dat.cdInf.EOF do
       begin
          NewNode := VST.AddChild(VST.FocusedNode);
          with PEntryData(VST.GetNodeData(NewNode))^ do
            begin
               Titulo  := Dat.cdInfNOMBRE.value;
               Informe := Dat.cdInfINFORME.value;
               Id      := Dat.cdInfUSER_FLAG.value;
               Tipo    := Dat.cdInfTIPO.value;
            end;
          Dat.cdInf.Next;
       end;

     VST.EndUpdate;

     VST.FullExpand;
end;
__________________
http://www.gestionportable.com
Responder Con Cita
  #4  
Antiguo 23-03-2014
jesconsa jesconsa is offline
Miembro
 
Registrado: dic 2009
Posts: 30
Poder: 0
jesconsa Va por buen camino
Como manejar el VirtualTreeView

Gracias pacopenin. Ya lo habia resuelto con bucles como:

Código Delphi [-]
Form1.FDTable10.First;
  for X := 1 to Form1.FDTable10.RecordCount do
      begin
        N.NCaption:= Form1.FDTable10.Fieldbyname('Areas').AsString;
    .........
    .........

A la vez que creo los nodos con AddChild les añado los datos, no lo hago en el evento OnInit porque asi me resulta mas facil. Como ves utilizo una tabla asociada directamente con la tabla de la base de datos (se puede hacer directamente asi en la componente Table de FireDac). El problema lo tengo ahora en que los cambios que haga en el VirtualTreeView se graben en la base de datos, por ejemplo pulsar sobre un checkbox de un nodo, etc. Con los Datasources asociados a Grids era facil porque un cambio en el grid automaticamente (activando la propiedad correspondiente) se actualizaba la base, pero aqui no hay enlace con Datasources,..la tabla directa a la base. Alguna idea?

Muchas gracias
Saludos
Responder Con Cita
  #5  
Antiguo 24-03-2014
Avatar de pacopenin
pacopenin pacopenin is offline
Miembro
 
Registrado: sep 2010
Ubicación: Asturias
Posts: 382
Poder: 14
pacopenin Va por buen camino
Pues deberás guardar el id del registro correspondiente en cada nodo (como hago en mi ejemplo) y cuando detectes una modificación, recuperar dicho registro y realizar la edición correspondiente. No se me ocurre otro modo.
__________________
http://www.gestionportable.com
Responder Con Cita
  #6  
Antiguo 25-03-2014
jesconsa jesconsa is offline
Miembro
 
Registrado: dic 2009
Posts: 30
Poder: 0
jesconsa Va por buen camino
VirtualTreeView

Hola pacopenin. Lo que he hecho es un poco al reves,..actualizo la base de datos con:

Código Delphi [-]
 dbMain.ExecSQL('update Areas set Selected=:Selected where Id=:Id', [Data.Chk,Data.Id]);

..y luego vuelvo a pintar el arbol, lo hago asi para poder activar una casilla y todos sus hijos, el repintado global me quita de historias...Solo una cosa negativa,..al repintar el arbol , éste esta reducido/colapsado,..si guardo el Nodo para poder expandirlo despues de pintar el arbol no lo hace bien, supongo que el puntero de ese nodo que guardo ya ha cambiado y no sirve de nada...Y tambien hice lo del "repintado" del arbol porque si no no me ponia actualizado el checkbox de los hijos de ese nodo (al checkearlos/señalarlos recursivamente)...espero haberme explicado bien....

Muchas gracias
Saludos

Jesus
Responder Con Cita
  #7  
Antiguo 27-03-2014
Avatar de Chris
[Chris] Chris is offline
Miembro Premium
 
Registrado: abr 2007
Ubicación: Jinotepe, Nicaragua
Posts: 1.678
Poder: 19
Chris Va por buen camino
Antes de empezar, entre los dos componentes te recomiendo que utilices el VirtualTreeView. TJvDBTreeView es poco efeciente y muy poco dinámico.

Para trabajar con el VirtualTreeView [VTV] debes estar muy familiarizado con los punteros. Si tienes un buen entendimiento de los punteros se te hará mucho más fácil trabajar con el VTV.

Lo primero que debes de definir es el tipo de datos de cada Nodo. El tipo de datos debe ser un puntero a un registro. El registro puede contener las propiedades que quieras.

Para explicartelo haré un mini tutorial. Utilizaré dos tablas virtuales. Una llamada clientes y otra llamada contactos. Cada cliente será represetando por un nodo en el VTV. Su respectivos contactos serán representados por subnodos.

Empezaremos por definir el registro de datos que utilizaremos para los nodos:

Código Delphi [-]
type
    TVTVNodeType = (ntClient, ntContact);
    TMyNodeData = record
        NodeType: TVTVNodeType; // Tipo de nodo
        ID: Variant;            // contendrá el id en la DB.
        Name: String;           // nombre del cliente o contacto
        HasContacts: Boolean;   // True cuando el cliente tiene contactos
    end;
    PMyNodeData = ^TMyNodeData;

Luego, escribiré un par de funciones que me serviraran para luego ubicar nodos en el árbol.

Código Delphi [-]
function get_node_of(Tree: TBaseVirtualTree,
                     NodeType: TVTVNodeType,
                     ID: Variant,
                     ParentNode: PVirtualNode = nil);
var
    NodeData: PMyNodeData;
    CurrentNode: PVirtualNode;                  
begin
    // esta función devuelve el nodo que cumpla con
    // las condiciones establecidas en los parámentros.
    result := nil;
    if ParentNode = nil then
        ParentNode := Tree.RootNode;

    CurrentNode = Tree.GetFirstChild(ParentNode)
    with Tree do
        while (CurrentNode <> nil)
        begin
            if not assigned(GetNodeData(CurrentNode)) then
            begin
                // El nodo no tiene datos asociados. Seguir con el siguiente.
                CurrentNode := Tree.GetNext(CurrentNode);
                continue;
            end;

            NodeData = GetNodeData(CurrentNode);
            if (NodeData.NodeType = NodeType) and (NodeData.ID = ID) then
            begin
                result := CurrentNode;
                break;
            end
            else
                CurrentNode := Tree.GetNext(CurrentNode);
        end;
end;

Ahora haremos la primera etapa. Mostrar todos los registros de clientes en el evento OnShow del formulario. Crearemos un nodo para cada registro de cliente.

Código Delphi [-]
procedure TForm1.OnShow(Sender: TObject);
var
    I: Integer;
    NewNodeData: PMyNodeData;
    NewNode: PVirtualNode;
begin
    // VTView es el nombre del componente VirtualTreeView en el formulario
    VTView.NodeDataSize := SizeOf(TMyNodeData);

    // Por simplicidad, no pondré un código de petición SQL
    // a la base de datos. Pero para que el código siguiente
    // funcione, debemos hacer una petición SQL que me devuelva
    // 3 campos. El ID y NOMBRE del cliente. El 3er campo será
    // un Boolean que cuando sea True indique si el cliente tiene
    // contactos asociados.

    // ...
    // select id, nombre, has_contacts from clients ...
    // ...

    for I := 0 to Dataset.RecorCount -1 do
    begin
        NewNode := VTView.AddChild(nil, NewNodeData);
        NewNodeData.NodeType    := ntClient;
        NewNodeData.ID          := Dataset.Records[i].FieldByName('id').Value;
        NewNodeData.Name        := Dataset.Records[i].FieldByName('name').Value;
        NewNodeData.HasContacts := Dataset.Records[i].FieldByName('has_contacts').Value;

        if NewNodeData.HasContacts then
          Include(NewNode.States, vsHasChildren);
    end;
end;

Ya hemos agregado los nodos. VirtualTreeView te permite crear nodos y árboles muy elaborados. O sencillos si así lo prefieres. Para este ejemplo usaremos nodos sencillos. Sin mucho adorno. VTV se encargará de pintarlos y no nosotros. Pero VTV necesita saber que cuál es el texto que mostrará en cada nodo. Así que nos lo debe preguntar en el evento "OnGetText". En este evento nuestro código devolverá la propiedad "name" de nodo.

Código Delphi [-]
procedure TForm1.VTVIewGetText(Sender: TBaseVirtualTree;
                               Node: PVirtualNode;
                               Column: Integer; TextType: TVSTTextType;
                               var Text: WideString);
var
    NodeData: PMyNodeData
begin
    NodeData := Sender.GetNodeData(Node);
    if (NodeData <> nil)
        Text := NodeData.Name
    else
        Text := '';
end;

Cuando el usuario expanda un Node de clientes que tiene contactos, debemos cargar desde la DB los registros de contactos. Esto lo haremos en el evento OnInitChildren.

Código Delphi [-]
procedure TForm1.VTVIewInitChildren(Sender: TBaseVirtualTree;
                                    Node: PVirtualNode;
                                    var ChildCount: Cardinal);
var
    I: Integer;
    ClientNodeData, NewNodeData: PMyNodeData;
    NewNode: PVirtualNode;
begin
    ChildCount := 0;
    ClientNodeData := Sender.GetNodeData(Node);
    // Hacer una petición a la DB con los datos de los contactos
    // asociados al cliente seleccionado.
    // PSEUDO-CÓDIGO:
    Dataset := Database.query('select * from contacts where client = ' + ClientNodeData.ID);

    for I := 0 to Dataset.RecorCount -1 do
    begin
        NewNode := VTView.AddChild(Node, NewNodeData);
        NewNodeData.NodeType    := ntContact;
        NewNodeData.ID          := Dataset.Records[i].FieldByName('id').Value;
        NewNodeData.Name        := Dataset.Records[i].FieldByName('name').Value;
        NewNodeData.HasContacts := False;
       
       Inc(ChildCount);
    end;   
end;

A cómo ves todo se trata de manejar los punteros. Utilizado Drag-and-Drop, podríamos mover un contacto desde un cliente a otro cliente. Podríamos eliminar un registro de la DB cuando el usuario elimine un Nodo del árbol y muchas otras funcionalidades que están fuera del alcance de esta respuesta.

VirtualTreeView te ofrece una funcionalidad inigualable. Todo es cuestión de entender cómo opera el componente. VirtualTreeView es sólo como una base. Este componente hace preguntas para todo. Lo que tu código debe implementar son respuestas a esas preguntas. Preguntas que normalmente el componente te las hace en los eventos.

Saludos.
__________________
Perfil Github - @chrramirez - Delphi Blog - Blog Web

Última edición por Chris fecha: 27-03-2014 a las 19:23:29.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Componente VirtualTreeView katuxa OOP 1 20-03-2009 17:39:46
Tutorial del VirtualTreeview Chandra OOP 5 02-05-2007 18:56:41
Como manejar marcos en C#? JuanErasmo .NET 0 19-01-2007 01:17:33
VirtualTreeview porreres Varios 8 19-09-2005 13:05:39
como manejar VIDEO ? ... ingel Varios 0 03-10-2003 21:17:38


La franja horaria es GMT +2. Ahora son las 09:51:00.


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
Copyright 1996-2007 Club Delphi