Ver Mensaje Individual
  #4  
Antiguo 29-06-2007
Avatar de Goyo
Goyo Goyo is offline
Miembro
 
Registrado: feb 2006
Posts: 89
Reputación: 19
Goyo Va por buen camino
Wink solucion de como llenar un Treeview con dos Tablas de Paradox

me contesto yo mismo, despues de buscar por la web informacion de como llenar un TreeView, encontre un Componente gratuito VirtualTree http://www.delphi-gems.com que hace exactamente lo mismo, que el TreeView normal.

Bueno les explico de como llenarlo utilizando dos tablas (Semestre: id_semestre, Semestre, Asignatura: id_materia,materia), para ello creamos una nueva aplicacion, introducimos el componente VirtualStringTree (deben tenerlo ya instalado) y despues dos TTable1..2 y dos Dataset1..2, y dos DbGrid para visualizar las tablas (esto lo pueden omitir); ya que se tienen estos componentes: unimos el TTable1 a la tabla maestra (TbSemestres) y el DataSet1 (DsSemestres) y la activamos, ahora en el TTable2 que sera nuestra tabla detalle (TbAsignaturas) y el Dataset2 (DsAsignaturas), una vez que ya se tiene la TbAsignaturas, nos vamos a su propiedad MasterSource: y seleccionamos DsSemestres, y en su propiedad IndexName: sera el indice de tipo Case Sensitive (campo que unira ambas tablas) de la tabla Asignaturas, escribimos Id_Semestre y en la propiedad MasterField: Id_semestre (campo a ligar con la tabla Semestre) y activamos en TbAsignaturas.

aqui les pongo el codigo que hara el resto para crear el arbol con las dos tablas)... obviamente yo lo traduci al español el tutorial completo se encuentra en: http://www.keashsoft.com/ que de donde yo lo baje.

Código Delphi [-]
unit ejemploVirtualTree;
{
  Virtualstrees and DBs
  (C) 2005 Florian Köllich, www.keashsoft.com
  Available under GPL.
  Este programa demuestra el uso de VirtualTree de Mike Lischke
  conjuntamente con una relación maestro/detalle. Aquí, se utilizan
  las bases de datos “Semestre.db” del ejemplo de los BDE y “Asinaturas.db”.
  Requerimientos:
  * Paquete Virtualtrees disponible en www.delphi-gems.com
  * con ejemplos de bases de datos del BDE.
}
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, DBTables, StdCtrls, ExtCtrls, Grids, DBGrids, VirtualTrees;
type
  // Definicion de los datos a usar en el VirtualTree:
  PMyData = ^TMyData;
  TMyData = record
    id_semestre: String[8];
    NomSemestre:String[255];
    id_materia: String[10];
    materia: String[255];
  end;
type
  TForm1 = class(TForm)
    tree: TVirtualStringTree;
    Panel1: TPanel;
    CheckBox1: TCheckBox;
    Memo1: TMemo;
    DsAsignaturas: TDataSource;
    DsSemestre: TDataSource;
    TbSemestres: TTable;
    TbAsignaturas: TTable;
    DBGrid3: TDBGrid;
    DBGrid4: TDBGrid;
    procedure FormCreate(Sender: TObject);
   procedure treeInitNode(Sender: TBaseVirtualTree; ParentNode,
      Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
    procedure treeInitChildren(Sender: TBaseVirtualTree;
      Node: PVirtualNode; var ChildCount: Cardinal);
    procedure treeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
      Column: TColumnIndex; TextType: TVSTTextType;
      var CellText: WideString);
    procedure CheckBox1Click(Sender: TObject);
    procedure treeChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
  private
    { Private declarations }
  public
    { Public declarations }
     procedure RebuildTree;   // llamada para construir/actualizar el arbol
  end;
var
  Form1: TForm1;
  bAutoLocate : boolean;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
  RebuildTree;
end;
procedure TForm1.RebuildTree;
begin
  // sistema RootNodeCount y NodeDataSize aqui.
  // Los datos se asignan para cada nodo en OnInitNode.
  tree.RootNodeCount := TbSemestres.RecordCount;
  tree.NodeDataSize := SizeOf(TMyData);
end;
procedure TForm1.treeInitNode(Sender: TBaseVirtualTree; ParentNode,
  Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
var data:PMyData;
begin
  // llenar un nodo con las Tablas Semestre y Asignaruas. El metodo
  // GetNodeLevel es utilizado sin distinguir entre el nodo maestro/detalle
  // Ttable's RecNo esta característica se utiliza para recuperar los datos correctos del nodo
  data := Sender.GetNodeData(Node);
  if Sender.GetNodeLevel(Node) = 0 then
  begin
    // Nodo maestro - Semestre
    TbSemestres.RecNo := node.Index + 1;
    data.id_semestre := TbSemestres.fieldbyname('id_semestre').asString;
    data.nomsemestre := TbSemestres.fieldbyname('NomSemestre').asString;
    if TbAsignaturas.RecordCount>0 then InitialStates:=InitialStates+[ivsHasChildren];
  end else
  begin
    // Nodo Detalle - Asignaturas
    TbSemestres.RecNo := parentnode.Index + 1;
    TbAsignaturas.RecNo := Node.Index + 1;
    data.id_semestre := TbSemestres.fieldbyname('id_semestre').asString;
    data.nomsemestre := TbSemestres.fieldbyname('nomsemestre').asString;
    data.id_materia := TbAsignaturas.fieldbyname('id_materia').asString;
    data.materia := TbAsignaturas.fieldbyname('Materia').AsString;
  end;
end;
procedure TForm1.treeInitChildren(Sender: TBaseVirtualTree;
  Node: PVirtualNode; var ChildCount: Cardinal);
begin
  // establecer ChilCount al RecordCount del dataset del detalle
  TbSemestres.RecNo := node.Index+1;
  childcount := TbAsignaturas.RecordCount;
end;
procedure TForm1.treeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var data:PMyData;
begin
  // Aqui se despliegan los datos
  data := Sender.GetNodeData(node);
  if Sender.GetNodeLevel(node) = 0 then
//    CellText := inttostr(data.id_semestre) + ' ' + data.NomSemestre
    CellText := data.id_semestre + ' ' + data.NomSemestre
  else
    CellText := format('%s   %s',[data.id_materia,data.Materia]);
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  bAutoLocate := checkbox1.checked;
end;
procedure TForm1.treeChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
  // Autolocate asegura de que la seleccion del arbol y los
  // cursores de los datasets sean sync'd.
  if bAutoLocate and assigned(node) then
  begin
    if sender.GetNodeLevel(node) = 0 then
      TbSemestres.RecNo:=node.Index+1
    else begin
      TbSemestres.RecNo:=node.parent.Index+1;
      TbAsignaturas.RecNo:=node.Index+1;
    end;
  end;
end;
end.

espero sea de mucha utilidad a todas aquellas personas que como yo quieren ampliar mas su conocimiento en la programacion de delphi... por cierto respecto a este programa como lo dice la primer pregunta formulada, ahora no se como unir este codigo del arbol para que cuando yo seleccione un alumno, me muestre el arbol y al seleccionar una asignatura, automaticamente en un DbGrid me muestre el registro para que pueda yo capturar y/o modificar alguna calificacion de este alumno y de la materia seleccionada en el Treeview....

de antemano muchas gracias por la atencion...
saludos
Responder Con Cita