Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Arrays, dynamisch-->statisch (https://www.delphipraxis.net/46900-arrays-dynamisch-statisch.html)

Majortomster 2. Jun 2005 17:07


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

barf00s 2. Jun 2005 17:09

Re: Arrays, dynamisch-->statisch
 
statisches array kannst mit

Delphi-Quellcode:
type
  TArray = array of integer;

var
  aInteger: TArray;

begin
  SetLength(aInteger, 100); // 100 elemente festlegen
end;
festlegen...

öhm


dynamisch zu statisch würde mit "Move" wunderbar klappen

Delphi-Quellcode:
Move(Pointer(aStatic)^, Pointer(aDynamic)^, iStaticArrayElementCount * SizeOf(aStatic[0]));

Muetze1 2. Jun 2005 17:10

Re: Arrays, dynamisch-->statisch
 
Moin!

Zitat:

Zitat von Majortomster
Ich brauche unbedingt ein statisches Array, denn die Methode TCustomClientDataSet.FindKey akzeptiert NUR ein statisches...

Wie kommst du darauf?

Zitat:

Zitat von barf00s
statisches array kannst mit

Delphi-Quellcode:
type
  TArray = array of integer;

var
  aInteger: TArray;

begin
  SetLength(aInteger, 100); // 100 elemente festlegen
end;

Das ist ein dynamisches, kein statisches!

MfG
Muetze1

/EDIT: Wieder keine Meldung!

Phistev 2. Jun 2005 17:21

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:
var groesse: integer;
//Größe berechnen
SetLength(aInteger, groesse);
Ein statisches Array deklariert man übrigens als:
Delphi-Quellcode:
type TIntArray: array[0..100] of integer
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:
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;

alzaimar 2. Jun 2005 22:03

Re: Arrays, dynamisch-->statisch
 
Zitat:

Ich brauche unbedingt ein statisches Array, denn die Methode TCustomClientDataSet.FindKey akzeptiert NUR ein statisches...
Oh oh, mich dünkt, ich hatte mal ein ähnliches Problem und konnte nur nur dadurch helfen, indem ich das FindKey neu geschrieben habe. Es ist ja im Grunde genommen nur eine art Filter: Du scanst alle Datensätze durch, bis der Datensatz dem Array Of Const entspricht. So schwer ist das doch nicht:
Delphi-Quellcode:
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;
So, oder ähnlich sollte es klappen. Performance sollte akzeptabel sein.

barf00s 3. Jun 2005 08:58

Re: Arrays, dynamisch-->statisch
 
@phistev, mütze .... wiederholt ihr immer die antwort des vorgängers???

Muetze1 3. Jun 2005 14:03

Re: Arrays, dynamisch-->statisch
 
Moin!

Zitat:

Zitat von barf00s
@phistev, mütze .... wiederholt ihr immer die antwort des vorgängers???

Probleme damit, weil ich behaupte das du uns ein dynamisches Array als statisches verkaufen willst? Oder einfach nur schlecht geschlafen?

MfG
Muetze1

barf00s 3. Jun 2005 14:13

Re: Arrays, dynamisch-->statisch
 
ich sehs grad ^^ hab mich ja tatsächlich verschrieben :)
ich nehm alles zurück, schulligung nommel

Majortomster 3. Jun 2005 15:08

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?

Majortomster 3. Jun 2005 15:30

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?

Phistev 3. Jun 2005 16:43

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;

Majortomster 7. Jun 2005 10:07

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:
var
findarray : array of TVarRec;
...
begin
...
      for i := 0 to temp do
      begin
         findarray[i] := lds.FieldValues[tempStrs.Strings[i]]
      end;
...
end;
Wie geht das?

T

barf00s 7. Jun 2005 10:11

Re: Arrays, dynamisch-->statisch
 
in der unit variants gibts allerhand hilfsfunktionen/prozeduren die dir dabei helfen sollten

Majortomster 7. Jun 2005 10:19

Re: Arrays, dynamisch-->statisch
 
[Fehler] sqlreplace.pas(895): Inkompatible Typen: 'TVarRec' und 'Variant'

Das kommt bei der normalen Zuweisung ... ich kriegs nicht hin :|

T

Majortomster 7. Jun 2005 10:43

Re: Arrays, dynamisch-->statisch
 
Nächster Fehlschlag:
Mit folgender Änderung lässt es sich kompilieren und ausführen:

Delphi-Quellcode:
...
      for i := 0 to temp do
      begin
         findArray[i].VType := vtVariant;
         test := lds.FieldValues[tempStrs.Strings[i]];
         findarray[i].VVariant := @test;
      end;
...
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."

Wie funktioniert dieses TVarRec? Nirgends findet man Dokus oder Beispiele :(

T

jim_raynor 7. Jun 2005 11:37

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?

alzaimar 7. Jun 2005 11:58

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]]);

semo 29. Sep 2007 10:43

Re: Arrays, dynamisch-->statisch
 
Delphi-Quellcode:
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^)]);
so klappte es bei mir.
schau dir aber sicherheitshalber noch einmal die dokumentation zu tvarrec an.
wenn du was neues weist poste mal bitte.
interessiert mich auch das ganze.

kolbaschedder 29. Sep 2007 11:23

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