AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Fehler beim Programm beenden
Thema durchsuchen
Ansicht
Themen-Optionen

Fehler beim Programm beenden

Ein Thema von Jens Hartmann · begonnen am 19. Okt 2015 · letzter Beitrag vom 15. Nov 2015
Antwort Antwort
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.079 Beiträge
 
Delphi 10.4 Sydney
 
#1

AW: Fehler beim Programm beenden

  Alt 10. Nov 2015, 10:47
Deine Frage ist unklar.
Baue ein kurzes (!!!) Beispielprojekt, zippe es und hänge es an.
Im Quelltext per Kommentar deutlich machen wie der Soll- und Ist-Zustand sich darstellt.
  Mit Zitat antworten Zitat
Benutzerbild von Jens Hartmann
Jens Hartmann

Registriert seit: 11. Jan 2009
Ort: Wilnsdorf
1.439 Beiträge
 
Delphi XE2 Professional
 
#2

AW: Fehler beim Programm beenden

  Alt 10. Nov 2015, 19:35
Hallo TiGü,
Zitat von TiGü:
Deine Frage ist unklar.
]

Sie Anhang.

Ich hoffe, das erklärt meine Frage etwas...

Ich versuche es aber auch nochmal wie folgt darzustellen...

Meine VST Struktur sieht ja in etwa so aus...

Code:
-Kunde1
  -Objekt1
  -Objekt2
  -Objekt3
-Kunde2
  -Objekt1
  -Objekt2
...
Wenn ich jetzt im VST auf Kunde1 "klicke", möchte ich natürlich die Daten des zugehörigen Kunden abfragen... Da ich ja nach aktueller Erklärung versuche das Ziel zu verfolgen, das ganze mit einem Record zu erschlagen, habe ich diesen aktuell als ersten Entwurf wie folgt aufgebaut...

Delphi-Quellcode:
  type
    pVSTNodeData = ^rVSTNodeData;
    rVSTNodeData = record
      KundenName, ObjektName, AnlagenTyp, AnlagenBezeichnung : WideString;
      KundenNr, ObjektNr, AnlagenNr : Integer;
    end;
Das heißt, in diesem Record sind alle notwendigen Daten. Dies ist aber falsch, da ja der Zusammenhang zwischen den verschiedenen Kunden und Objekten (Anlagen) nicht hergestellt werden kann. Dies wäre ja nur dann möglich, wenn z.B.

  Objektname : array of WideString wäre.

In der Datenzuweisung mache ich ja immer

Delphi-Quellcode:
  //for-Schleife Kunden
  pNode1 := vstKunden.AddChild(pNode);
  Daten := vstKunden.GetNodeDate(pNode1);
  Daten^.KundenName := 'Kunde';

  //for-Schleife Objekte innerhalb der for-Schleife Kunden
  pNode2 := vstKunden.AddChild(pNode1);
  Daten := vstKunden.GetNodeDate(pNode2); //Hier ist ja der Zeiger auf einen ganz anderen record (logisch, anderer Node)
  Daten^.KundenName := 'Kunde';
Dies würde aber ja bedeuten, das in der Datenebene "Kunde" die Felder "Objekt" etc. überflüssig sind (da nie genutz) und in der Datenebene "Objekt" das Felde "Kunde" überflüssig ist. Dies würde mich wieder in die Richtung meiner ehemaligen Lösung bewegen "3 Objekt/Records" zu erstellen. Je einen für die entsprechende "Node-Ebene"

Wenn ich Euch aber richtig verstanden habe, kann man das irgendwie mit dem NodeType oder ähnlich lösen. Und da Blick ich nicht richtig durch...

Ich hoffe, dass man das jetzt verstehen konnte...

Danke schon mal und Gruß Jens
Angehängte Dateien
Dateityp: zip Musterprojekt.zip (2,48 MB, 1x aufgerufen)
Jens Hartmann
Das Leben selber ist zu kurz, also nutze jeden Tag wie er kommt.
  Mit Zitat antworten Zitat
bcvs

Registriert seit: 16. Jun 2011
736 Beiträge
 
Delphi 12 Athens
 
#3

AW: Fehler beim Programm beenden

  Alt 11. Nov 2015, 08:01
Vergiss diesen Record!!
Das vermischt Datenhaltung mit visueller Darstellung, da deine Daten im Control gespeichert werden. Nicht gut.

Ich würde mir eine Datenstruktur überlegen, die zuerst einmal komplett außerhab dem VST stattfindet.

z.B.
Delphi-Quellcode:
TKunde = class
  Name : String;
  Nr : String;
  Objects: TObjectList;
  constructor Create; // hier Objects erzeugen
  destructor Destroy; Override; // hier Objects freigeben
end;

TKundenObjekt = class
  Name : String;
  WasAuchImmer: String;
end;
Dann braucht du noch eine ObjectList für die Kunden:

KundenListe : TObjectList; Vor dem Einlesen der Daten in den VST wird jetzt erstmal diese Datenstruktur gefüllt.

Dein Record für den VST sieht dann so aus:

Delphi-Quellcode:
  type
    pVSTNodeData = ^rVSTNodeData;
    rVSTNodeData = record
      Data : TObject;
    end;
Dann gehst du die zuvor befüllte KundenListe durch und baust den Inhalt des VST auf:


Delphi-Quellcode:
  //for-Schleife Kunden (i)
  pNode1 := vstKunden.AddChild(pNode);
  Daten := vstKunden.GetNodeDate(pNode1);
  Daten^.Data := KundenListe[i];

  //for-Schleife Objekte (j) innerhalb der for-Schleife Kunden (i)
  pNode2 := vstKunden.AddChild(pNode1);
  Daten := vstKunden.GetNodeDate(pNode2);
  Daten^.Data:=TKunde(KundenListe[i]).Objects[j]);
Jetzt kennt jeder Node des VST seine relevanten Daten und nur diese. Im OnGetText kannst du dann herausfinden, ob es sich um einen Kudnen oder ein Objekt handelt:

Delphi-Quellcode:
  Daten := vstKunden.GetNodeDate(Node);
  if Daten^.Data is TKunde then
    // Kunde
  else
    // Objekt
  Mit Zitat antworten Zitat
Benutzerbild von Jens Hartmann
Jens Hartmann

Registriert seit: 11. Jan 2009
Ort: Wilnsdorf
1.439 Beiträge
 
Delphi XE2 Professional
 
#4

AW: Fehler beim Programm beenden

  Alt 15. Nov 2015, 18:34
Hallo zusammen,

ich habe das Problem gelöst. Und ich glaube sogar, das ganze zu verstehen. Abschließen nochmal vielen Dank für Eure Hilfe und folgend mal die Lösung des Problems...

Delphi-Quellcode:
//Der Record mit dem integrierten Objekt
  type
    PTreeData = ^TTreeData;
    TTreeData = record
      FObject : TObject;
    end;

//Im OnCreate der Form
  ...
  vstKunden.NodeDataSize := SizeOf(TTreeData);
  LoadVST(true);
  ...

//Das Laden des ersten Knoten
procedure TfReportClient.LoadVST(IsStarted: Boolean);
var
  pNode : PVirtualNode;
begin
  try
    vstKunden.BeginUpdate;
    vstKunden.Clear;
    ....
      pNode := vstKunden.AddChild(nil);
      //Kundendaten laden
      LoadCustomersData(pNode,IsStarted);

      vstKunden.EndUpdate;
      ExpandedRootNodes(vstKunden);
      vstKunden.SortTree(0, sdAscending, True);
...
end;

//Das Laden der Kunden
procedure TfReportClient.LoadCustomersData(ANode : PVirtualNode; IsStarted : Boolean);
var
  i : Integer;
  Daten_Kunde : TOCustomers;
begin
 try
   try
    //Kundendaten laden aus Kundendatenbank

    if DMMasterData.OpenCustomerQuery then
      begin
        DMMasterData.qryCustomerData.First;

        for i := 0 to DMMasterData.qryCustomerData.RecordCount -1 do
          begin
              Daten_Kunde := TOCustomers.Create;
              with Daten_Kunde do
                begin
                  Kunden_Kundennummer := DMMasterData.qryCustomerData.FieldByName('Kunden_Kundennummer').AsInteger;
                  Kunden_ESKundennummer := DMMasterData.qryCustomerData.FieldByName('Kunden_ESKundennummer').AsInteger;
                  Kunden_Kundenname := DMMasterData.qryCustomerData.FieldByName('Kunden_Kundenname').AsString;
                  Kunden_Ort := DMMasterData.qryCustomerData.FieldByName('Kunden_Ort').AsString;
                  Kunden_Straße := DMMasterData.qryCustomerData.FieldByName('Kunden_Straße').AsString;
                  Kunden_Bemerkung := DMMasterData.qryCustomerData.FieldByName('Kunden_Bemerkung').AsString;
                  Ansprechpartner_Id := DMMasterData.qryCustomerData.FieldByName('Ansprechpartner_Id').AsInteger;
                  Ansprechpartner_Name := DMMasterData.qryCustomerData.FieldByName('Ansprechpartner_Name').AsString;
                end;

                vstKunden.AddChild(ANode,Daten_Kunde);

            DMMasterData.qryCustomerData.Next;
          end;
      end;
    DMMasterData.CloseCustomerQuery;
   except
     Daten_Kunde.Free;
   end;
 finally
   DMMasterData.CloseCustomerQuery;
 end;
end;
//Festlegung, das die Knoten Kunden Kinder haben im OnInit des VST
procedure TfReportClient.vstKundenInitNode(Sender: TBaseVirtualTree; ParentNode,
  Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
begin
  case vstKunden.GetNodeLevel(Node) of
    1:
     begin
       vstKunden.CheckType[Node] := ctCheckBox;
       vstKunden.CheckState[Node] := csCheckedNormal;
       vstKunden.HasChildren[Node] := True;
     end;
    2:
     begin
       vstKunden.HasChildren[Node] := True;
     end;
    3:
     begin
       vstKunden.HasChildren[Node] := True;
     end;
  end;
end;

//Die Objekte und Anlagen werden erst nach dem sie aufgeklappt werden erstellt
procedure TfReportClient.vstKundenExpanding(Sender: TBaseVirtualTree;
  Node: PVirtualNode; var Allowed: Boolean);
var
  NodeLevel : Integer;
  Daten : PTreeData;
begin
  NodeLevel := vstKunden.GetNodeLevel(Node);
  if vstKunden.ChildCount[Node] = 0 then
    begin
      case NodeLevel of
        1: //Objektdaten beim aufklappen des Objekt Knoten erstellen/laden
         begin
           Daten := vstKunden.GetNodeData(Node);
           LoadObjektData(Node, TOCustomers(Daten.FObject).Kunden_Kundennummer);
         end;
        2: //Anlagendaten beim aufklappen des Anlagen Knoten erstellen/laden
         begin
           Daten := vstKunden.GetNodeData(Node);
           LoadSystemData(Node, TOBuilding(Daten.FObject).Objekt_Objektnummer);
         end;
      end;
    end;
end;

//Das Freigeben der Daten
procedure TfReportClient.vstKundenFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var
  Daten : PTreeData;
begin
  Daten := vstKunden.GetNodeData(Node);
  if not Assigned(Daten) then
    exit;
  Daten.FObject.Free;
end;
Jens Hartmann
Das Leben selber ist zu kurz, also nutze jeden Tag wie er kommt.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:44 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz