![]() |
Arrays, dynamisch-->statisch
Hallo,
wie kann ich ein dynamisches Array erstellen, dessen Größe aber erst zur Laufzeit feststeht? Andere Möglichkeit, die mein Problem auch lösen würde: Eine Möglichkeit, ein dynamisches Array in ein statisches umzuwandeln. ´ Ich brauche unbedingt ein statisches Array, denn die Methode TCustomClientDataSet.FindKey akzeptiert NUR ein statisches... Hat jemand eine Idee? Wäre nett... Gruß, Thomas |
Re: Arrays, dynamisch-->statisch
statisches array kannst mit
Delphi-Quellcode:
festlegen...
type
TArray = array of integer; var aInteger: TArray; begin SetLength(aInteger, 100); // 100 elemente festlegen end; öhm dynamisch zu statisch würde mit "Move" wunderbar klappen
Delphi-Quellcode:
Move(Pointer(aStatic)^, Pointer(aDynamic)^, iStaticArrayElementCount * SizeOf(aStatic[0]));
|
Re: Arrays, dynamisch-->statisch
Moin!
Zitat:
Zitat:
MfG Muetze1 /EDIT: Wieder keine Meldung! |
Re: Arrays, dynamisch-->statisch
SetLength akzeptiert auch als zweiten Parameter (wie jede Funktion) das Ergenis einer anderen Funktion oder den Wert einer Variablen, also:
Delphi-Quellcode:
Ein statisches Array deklariert man übrigens als:
var groesse: integer;
//Größe berechnen SetLength(aInteger, groesse);
Delphi-Quellcode:
Statt Zahlen können auch Konstanten verwendet werden, aber keine Variablen. Zur Umwandlung: Wenn dir move zu unsicher ist, tut's auch eine for-Schleife:
type TIntArray: array[0..100] of integer
Delphi-Quellcode:
i:=0
for loop:= low(dynarray) to high(dynarray) do begin statarray[i+Untergrenze]:=dynarray[loop]; //für Konstruktionen wie array[10..200] inc(i); end; |
Re: Arrays, dynamisch-->statisch
Zitat:
Delphi-Quellcode:
So, oder ähnlich sollte es klappen. Performance sollte akzeptabel sein.
Function MyFindKey (aDataset : TDataset; aFields : Array Of String; aValues : Array Of Variant) : Boolean;
Var i : Integer; Begin While not aDataset.eof do begin i := Low (aFields); Result := True; While Found and (i <= High (aFields)) do If aDataset [aFields[i]] <> aValues[i] Then Result := False; If Result Then Exit; aDataSet.Next; end; Result := False End; |
Re: Arrays, dynamisch-->statisch
@phistev, mütze .... wiederholt ihr immer die antwort des vorgängers???
|
Re: Arrays, dynamisch-->statisch
Moin!
Zitat:
MfG Muetze1 |
Re: Arrays, dynamisch-->statisch
ich sehs grad ^^ hab mich ja tatsächlich verschrieben :)
ich nehm alles zurück, schulligung nommel |
Re: Arrays, dynamisch-->statisch
Danke für die vielen Tipps, aber all dies löst mein Problem leider nicht.
Im Einzelnen: 1. Wenn ich SetLength() auf ein dynamisches Array anwende, dann wird es trotzdem nicht zu einem statischen --> unbrauchbar für FindKey() 2. Move-Funktion --> kopiert doch nur Bytes von einem Speicherbereich in einen anderen, damit könnte ich das statische Array zwar füllen, dies löst aber nicht das Problem, wie ich dieses Array denn erstmal "erschaffen" soll (wie gesagt, dessen Größe steht erst zu Laufzeit fest) 3. in for-schleife das statische Array füllen --> siehe Punkt 2. 4. Eigene FindKey-Methode schreiben --> Möglich, aber dann könnte ich auch gleich die Locate-Methode benutzen, die ein dynamisches Array akzeptiert. Ich MUSS aber FindKey benutzen, da es hundert mal schneller ist als Locate. (in eigenen Tests mit einer großen Abfrage-Schleife in einer Paradox-Datenbank: Locate 13:23 Minuten, FindKey 6:33 Minuten Also nochmal zusammengefasst: Ich habe ein dynamisches Array (of Variant), dessen Größe erst zur Laufzeit feststeht (max. 10 bis 12 Elemente). Dieses stellt Zeilenwerte dar, die ich in einer Tabelle finden muss. Mittels Locate problemlos möglich - aber extrem langsam. Mittels FindKey wesentlich schneller, aber diese Methode will unbedingt ein statisches Array. Wie? |
Re: Arrays, dynamisch-->statisch
Ideal wäre das:
Delphi-Quellcode:
class function kl.funkt(dynArr : array of variant) : boolean; var findArray : array [0..(High(dynArr)+1)] of variant; begin // [...] FindKey(findArray) // usw... end; Aber das geht natürlich in Delphi nicht :| Ich könnte natürlich auch von vornherein 12 statische Arrays anlegen. Eines mit einem Element, eines mit 2 Elementen ... und so weiter - bis 12 Elemente. Bei Beginn der Funktion wird die Größe des dynamischen geprüft und anhand dessen entschieden, in welches der 12 statischen Arrays die Daten übertragen werden, so dass es mit FindKey benutzt werden kann. Das würde bestimmt klappen, aber diese Lösung wäre wohl mehr als dämlich, meint ihr nicht? |
Re: Arrays, dynamisch-->statisch
Deklarier dein dyn. Array als array of TVarRec, nicht als array of variant. Dann sollt's klappen (bei mir hat's funktioniert). Zum Typ TVarRec (System.pas):
Delphi-Quellcode:
TVarRec = record { do not pack this record; it is compiler-generated }
case Byte of vtInteger: (VInteger: Integer; VType: Byte); vtBoolean: (VBoolean: Boolean); vtChar: (VChar: Char); vtExtended: (VExtended: PExtended); vtString: (VString: PShortString); vtPointer: (VPointer: Pointer); vtPChar: (VPChar: PChar); vtObject: (VObject: TObject); vtClass: (VClass: TClass); vtWideChar: (VWideChar: WideChar); vtPWideChar: (VPWideChar: PWideChar); vtAnsiString: (VAnsiString: Pointer); vtCurrency: (VCurrency: PCurrency); vtVariant: (VVariant: PVariant); vtInterface: (VInterface: Pointer); vtWideString: (VWideString: Pointer); vtInt64: (VInt64: PInt64); end; |
Re: Arrays, dynamisch-->statisch
Das hört sich doch sehr interessant an.
Aber wie füllt man ein TVarRec? Bei einer einfach Zuweisung wie zuvor mit dem Variant Array klappt es nicht:
Delphi-Quellcode:
Wie geht das?
var
findarray : array of TVarRec; ... begin ... for i := 0 to temp do begin findarray[i] := lds.FieldValues[tempStrs.Strings[i]] end; ... end; T |
Re: Arrays, dynamisch-->statisch
in der unit variants gibts allerhand hilfsfunktionen/prozeduren die dir dabei helfen sollten
|
Re: Arrays, dynamisch-->statisch
[Fehler] sqlreplace.pas(895): Inkompatible Typen: 'TVarRec' und 'Variant'
Das kommt bei der normalen Zuweisung ... ich kriegs nicht hin :| T |
Re: Arrays, dynamisch-->statisch
Nächster Fehlschlag:
Mit folgender Änderung lässt es sich kompilieren und ausführen:
Delphi-Quellcode:
Aber dies verursacht zur Laufzeit eine Zugriffsverletzung und zwar schon bei Zuweisung des VType-Feldes. "Zugriffsverletzung bei Adresse blabla in Modul 'delDB.exe'. Schreiben von Adresse 000000004."
...
for i := 0 to temp do begin findArray[i].VType := vtVariant; test := lds.FieldValues[tempStrs.Strings[i]]; findarray[i].VVariant := @test; end; ... Wie funktioniert dieses TVarRec? Nirgends findet man Dokus oder Beispiele :( T |
Re: Arrays, dynamisch-->statisch
Du sagst, das FindKey ein statisches Array braucht? Dann hat es doch definitiv eine feste Länge. Heisst du musst dich daran halten, ob du willst oder nicht. Wie sieht denn die Paramater Beschreibung von FindKey aus?
|
Re: Arrays, dynamisch-->statisch
Angeblich : Variant == TVarData. Also solltest Du dein Array Of TVarData so füllen können:
Delphi-Quellcode:
for i := 0 to temp do
findArray[i] := TVarData (lds.FieldValues[tempStrs.Strings[i]]); |
Re: Arrays, dynamisch-->statisch
Delphi-Quellcode:
so klappte es bei mir.
var
Test : array [0..0] of TVarRec; extendedVal: Extended; begin extendedVal := StrToFloat(Edit1.text); Test[0].VExtended := @extendedVal; Label1.Caption := Format('%8.2f', [extended(Test[0].VExtended^)]); schau dir aber sicherheitshalber noch einmal die dokumentation zu tvarrec an. wenn du was neues weist poste mal bitte. interessiert mich auch das ganze. |
Re: Arrays, dynamisch-->statisch
Hallo Jungs,
ich hab das ganze hier nur mal so grob überflogen. Das mit den statischen Geschichten lässt sich für gewöhnlich mit folgendem Trick übergehen.
Delphi-Quellcode:
type TStaticArray = array[0..16000] of Integer; PStaticArray = ^TStaticArray; procedure Wasauchimmer; var pArr = PStaticArray; begin getMem(pArr, 100*SizeOf(Integer)); // Jetzt Array Füllen // Aufruf dann ungefähr so FindKey(pArr^, ..,..); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:28 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 by Thomas Breitkreuz