Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Tablas de Paradox en un TreeView - DBGrid (https://www.clubdelphi.com/foros/showthread.php?t=45264)

Goyo 27-06-2007 17:52:47

Tablas de Paradox en un TreeView - DBGrid
 
1 Archivos Adjunto(s)
Estoy diseñando un sistema de control de alumnos, pero tengo una duda de como hacer para que me aparezca un ARBOL con los semestres y a su vez dentro de cada semestre las materias que pertenecen a ese semestre y en un DBGrid capturar las calificaciones por alumno de la materia que este seleccionada, para ello cuento con 4 tablas en paradox:

Tabla: Alumnos
id_alumno : key
Nombre
Apellidos
id_semestre
....etc

Tabla: Semestres
id_semestre : key
Semestre

Tabla: Asignaturas
id_asignatura : key
Asignatura
id_semestre
... etc.

Tabla: Calificaciones
id_calificacion : key
id_asignatura
id_alumno
calificacion
.
.
Les explico como quiero que aparezcan los datos en el formulario:
-----------------------------------------------------------------
Nombre del Alumno: Juan Perez Matricula: 4206 Grupo: A
-----------------------------------------------------------------
----------------------------- Calificacion
->Semestre 1
------>Biologia I ________________ 10
------>Fisica I __________________ 9
------>Historia de Mexico I ________ 8
------>Matematicas I ____________ 7
------>Ingles I __________________10
->Semestre 2
------>Biologia II ________________ 10
------>Fisica II _________________ 10
------>Historia de Mexico II _______10
------>Matematicas II ___________ 10
------>Ingles II _________________10
.
.
Delante del Cuadro del Arbol (Treeview) un Dbgrid donde se pueda escribir la calificacion que corresponde al alumno y esa materia que se tiene seleccionada. Osea que si tengo seleccionado el semestre 2 y la materia Matematicas II, en el DBGrid se capture la calificacion.

anexo una imagen de lo que pretendo realizar.... de antemano muchas gracias por su ayuda.

Saludos

Neftali [Germán.Estévez] 27-06-2007 18:12:19

Supongo que tendrás que generar el TreeView a la Izquierda de forma manual; Y los elementos seleccionados a la izquierda (asignatura) son los que te servirán de Filtro para la última consulta sobre la tabla calaficaciones (con alguna JOIN para obtener campos de las otras) que es la que debes mostrar en el Grid de la derecha.
Al cambiar la selección a la izquierda (otra asignatura) vualves a montar la SQL y la vuelves a lanzar.

¿Exactamente qué es lo que necesitas? ¿Rellenar el Tree? ¿DBGrid? ¿La consulta?
El planteamiento es claro, lo que no explicas es la duda/error que tienes.

Goyo 27-06-2007 18:18:32

Cita:

Empezado por Neftali
Supongo que tendrás que generar el TreeView a la Izquierda de forma manual; Y los elementos seleccionados a la izquierda (asignatura) son los que te servirán de Filtro para la última consulta sobre la tabla calaficaciones (con alguna JOIN para obtener campos de las otras) que es la que debes mostrar en el Grid de la derecha.
Al cambiar la selección a la izquierda (otra asignatura) vualves a montar la SQL y la vuelves a lanzar.

¿Exactamente qué es lo que necesitas? ¿Rellenar el Tree? ¿DBGrid? ¿La consulta?
El planteamiento es claro, lo que no explicas es la duda/error que tienes.

lo que necesito saber es como llenar el Treeview con las tablas (Semestre, Asignaturas y como enlazaria el dbgrid (calificaciones), y como se realizaría la consulta.. creo que ademas como enlazaria la tabla alumnos con todas estas demas tablas...

un saludo y gracias

Goyo 29-06-2007 17:26:37

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

Genner 05-12-2007 18:33:52

Por que no pruebas en el evento OnDblClick del TreeView ahi puedes tomar el valor del puntero para hacer una consulta o para lo que gustes, te dejo un pedazo de codigo, espero te sirva
Código Delphi [-]
 
procedure TForm1.treeDblClick(Sender: TObject);
var
datos:PNodeData;
begin
datos:=tree.GetNodeData(Tree.FocusedNode);
showMessage(datos.Texto);
end;
PAra tu caso supongo que seria

Código Delphi [-]
procedure TForm1.treeDblClick(Sender:Tobject);
var
datos:PMyData;
begin
datos:=tree.GetNodeData(Tree.FocusedNode); //aqui tomas el valor del nodo seleccionado
showMessage(datos.IdSemestre);<- con esto tomas la clave del semestre
end;

Espero te sirva.

Lepe 06-12-2007 20:02:51

Completo un poco más.

Si el VirtualTreeview tienes HideSelection a false, y te aseguras mediante código de que hay algo seleccionado, entonces no hay problema.

En caso contrario, es bueno hacer primero la comprobación:
Código Delphi [-]
   if tree.FocusedNode <> nil then

o bien:
Código Delphi [-]
  if Assigned(tree.FocusedNode) then

PD: El VirtualStringTree tiene el evento OnFocusChanged, con un parámetro que indica el nodo que tiene el foco y la columna. Lugar oportuno para usar el código de Genner.

El hilo es de hace 6 meses, pero al menos dejamos la respuesta para futuras búsquedas. Gracias por reavivarlo Genner.

Saludos

Saludos


La franja horaria es GMT +2. Ahora son las 05:30:14.

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