![]() |
GetPropValue und ArrayOf...
Hallo,
ich habe ein kleines Problem (oder ein Brett vorm Kopf). Gegeben ist folgender Konstrukt:
Delphi-Quellcode:
Ich muss nun zur Laufzeit die Properties von TBlaObject auslesen, was ja auch... type ArrayOfString = array of String; TBlaBla = class(irgenetwas) private FQArray : ArrayOfString; FSonst : String; public destructor Destroy; override; published property Sonst : String read FSonst write FSonst; property QArray : ArrayOfString read FQArray write FQArray; end; ArrayOfBlaBla = Array of TBlaBla; TBlaObject = class(irgenetwas) private FAlleQArrays : ArrayOfBlaBla; FDieses : String; public destructor Destroy; override; published property Dieses : String read FDieses write FDieses; property AlleQArrays : ArrayOfBlaBla read FAlleQArrays write FAlleQArrays; end; ... eigentlich kein Problem ist:
Delphi-Quellcode:
Das klappt soweit, bis, ja bis das ArrayOfBlaBla dran ist.... type // Dient zum Zwischenspeichern TEntry = class Name : String; Typ : TVarType; Value : Variant; List : TObjectList; end; function GetObjectData(AObject : TObject; var List : TObjectList) : Boolean; implementation function GetObjectData(AObject : TObject; var List : TObjectList) : Boolean; var PropList : pPropList; I, J, K : Integer; PropValue : Variant; Entry : TEntry; begin PropList := AllocMem(SizeOf(PropList^)); try I := 0; J := GetPropList(AObject, PropList); if (J <> 0) and (PropList^[I] <> nil) then begin while (I < J) do begin Entry := TEntry.Create; Entry.Name := PropList^[i].Name; try PropValue := GetPropValue(AObject, PropList^[i].Name); // Fehler bei ArrayOf Entry.Value := PropValue; // Edit Entry.SoapTyp := TVarData(PropValue).VType; except end; Inc(I); // Edit end; end; finally FreeMem(PropList); end; Result := List.Count - 1 > -1; end; ... Dann steigt GetPropValue mit einer Exception aus: EVariantTypCastError := 'Ungültige Variant-Typumwandlung' Hat jemand dafür einen Tipp oder eine Lösung? Gruß Alter Mann |
Re: GetPropValue und ArrayOf...
Von einem alten Mann zum anderen: der Code ist nicht der echte Code - oder es fehlt ein Inc(i) in deiner Endlos-Schleife. Außerdem tritt der Fehler wohl eine Zeile später auf:
Delphi-Quellcode:
Das kann ja nicht funktionieren - ein array of object wird so niemals in einen string konvertiert.
Entry.Value := VarToStr(PropValue);
Gute Nacht marabu |
Re: GetPropValue und ArrayOf...
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
das mit dem Inc(I) und dem VarToStr(PropValue) ist klar, ich habe es auch geändert. Das hat allerdings keinen Einfluss auf den Fehler. Ich habe zum besseren Verständnis ein Screenshot angehängt. |
Re: GetPropValue und ArrayOf...
Guten Morgen.
Kannst du den fehlerhaften Code nicht isolieren und hier einstellen? Es würde die Untersuchung des Fehlers vereinfachen. Freundliche Grüße marabu |
Re: GetPropValue und ArrayOf...
Hallo marabu
Ich würde gern den Code reinstellen, nur geht es nicht, da ich auf einen Web-Service zugreife. In den Code-Bsp. stellt Zitat:
über den Web-Service bekomme. Es hat ca. 25 einfache Eigenschaften wie WideString, TXSDateTime, Boolean usw., aber auch ca. 30 Eigenschaften die alle vom Type: Array of sind. In den Array of werden weitere Objekte referenziert, je nach bedarf. Nun wollte ich dynamisch die Eigenschaften durchgehen um nur die Elemente in einer Liste zu speichern in denen tatsächlich auch Werte enthalten sind. Beispielhaft etwa so:
Delphi-Quellcode:
Unit zur Ermittlung der Eigenschaften:
unit uMain;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, ExtCtrls, StdCtrls, Contnrs, BlaObject; type TForm1 = class(TForm) Panel1: TPanel; Button1: TButton; Panel2: TPanel; tvData: TTreeView; Splitter1: TSplitter; lvData: TListView; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } FRootNode : TTreeNode; procedure InsertListData(List : TObjectList); public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} uses uTools; procedure TForm1.InsertListData(List : TObjectList); var I : Integer; SE : TSoapEntry; begin for I := 0 to List.Count -1 do begin SE := TSoapEntry(List.Items[I]); tvData.Items.AddChild(FrootNode, SE.Name); end; end; procedure TForm1.Button1Click(Sender: TObject); var UObject : TBlaObject; List : TObjectList; begin UObject := TBlaObject.Create; try List := TObjectList.Create; try FRootNode := tvData.Items.Add(nil, UObject.ClassName); if GetObjectData(UObject, List) then InsertListData(List); finally List.Free; end; finally UObject.Free; end; end; end.
Delphi-Quellcode:
Das Objekt welches vom Web-Service kommt:
unit uTools;
interface uses Windows, SysUtils, Classes, Variants, Contnrs, TypInfo, BlaObject; //<- Webservice type // Dient zum Zwischenspeichern TSoapEntry = class Name : String; SoapTyp : TVarType; Value : Variant; List : TObjectList; end; function GetObjectData(AObject : TObject; var List : TObjectList) : Boolean; implementation var PropList : pPropList; I, J, K : Integer; SoapEntry : TSoapEntry; PropValue : Variant; PropArray : Array of TBlaBla; PropObject : TObject; begin PropList := AllocMem(SizeOf(PropList^)); try I := 0; J := GetPropList(AObject, PropList); if (J <> 0) and (PropList^[I] <> nil) then begin while (I < J) do begin SoapEntry := TSoapEntry.Create; SoapEntry.Name := PropList^[i].Name; try if POS('Elem', PropList^[i].Name) = 0 then // Die 'Arrays of' fangen alle mit 'Elem' an, ohne kommt es zur Exception begin PropValue := GetPropValue(AObject, PropList^[i].Name); // Hier Exception bei 'Array of' SoapEntry.Value := PropValue; SoapEntry.SoapTyp := TVarData(PropValue).VType; end else begin // Nur ein weiter Versuch, der nicht zum Ziel führt SoapEntry.SoapTyp := varArray; SoapEntry.List := TObjectList.Create; PropArray := @PropList^[i]; for K := 0 to High(PropArray) do begin PropObject := TBlaBla(PropArray[K]); GetObjectData(PropObject, SoapEntry.List); // recursiver Aufruf der dann bei GetPropList scheitert end; end; except end; if List.IndexOf(SoapEntry) = -1 then List.Add(SoapEntry) else SoapEntry.Free; Inc(I); end; end; finally FreeMem(PropList); end; Result := List.Count - 1 > -1; end;
Delphi-Quellcode:
Wie geschrieben nur Beispielhaft, da der Code so nicht läuft(fehlende Initialisierung des 'webservices').unit BlaObject; interface uses Windows, SysUtils, Classes; type ArrayOfString = array of String; TBlaBla = class(TObject) private FQArray : ArrayOfString; FSonst : String; published property Sonst : String read FSonst write FSonst; property QArray : ArrayOfString read FQArray write FQArray; end; ArrayOfBlaBla = Array of TBlaBla; TBlaObject = class(TObject) private FAlleQArrays : ArrayOfBlaBla; FDieses : String; published property Dieses : String read FDieses write FDieses; property AlleQArrays : ArrayOfBlaBla read FAlleQArrays write FAlleQArrays; end; ... implementation end. Ich hoffe ich habe mich klar ausgedrückt. Auch wenn einige nun vielleicht schreiben werden, dass ich es 'Statisch' machen könnte/sollte, geht es nicht, da sich das Objekt vom Web-Service ändert und sich die Codeänderungen in der Anwendung nur auf den Neuimport der WDSL-Datei beschränken soll. Danke für die Mühe... PS Falls noch Fragen sind fragen |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:27 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