Autor Beitrag
Jocke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28

XP
D6 Pers
BeitragVerfasst: Fr 12.09.08 11:17 
Guten Morgen,

ich bräuchte mal Unterstützung.

Ich habe 2 csv Dateien, die ich verbinden möchte.
Die erste Datei folgende Daten :

Fremdnummer,Auftragnummer, ......
100000,20000,......
100001,20097,......
100002,20010,......
usw.

Die 2.Datei ist nun über die Fremdnummer verknüpf, wobei es allerdings zu jeder Fremdnummer 3 Datensätze gibt.

Fremdnummer,Art,Betrag,.....
100000,RG,100,....
100000,GS,50,.....
100000,DIFF,50,...
100001,RG,200,....
100002,GS,90,.....
100003,DIFF,110,...
usw.

Als Ergebnis möchte ich nun eine Tabelle haben (z.B. Stringgrid), die wie folgt aussieht :
ausblenden Quelltext
1:
2:
3:
4:
Auftragnummer BetragRG BetragGS  BetragDiff
20000           100      50       50
20097           200      90       110
....


Ich habe als erstes die 1.Datei in ein Stringgrid eingelesen. Danach habe ich 2 verschachtelten Schleifen die 2.Datei verknüpft, wobei die äussere Schleife die Datensätze der 2.Datei nacheinander durchgeht und die innere Schleife jeden einzelnen Datensatz mit allen Einträgen im Stringgrid vergleicht.

Das ganze funktioniert im Prinzip, ist allerdings nicht praktikabel, wenn die Dateien sehr grosse Datenmengen enthalten. Hat die 1.Datei 10000 Datensätze und die 2.Datei 30000, dann wird die äussere Schleife 30000 mal durchlaufen und bei jedem Durchlauf wird die innere Schleife dann x-mal durchlaufen, bis der dazugehörige Eintrag im Stringgrid gefunden wurde.

D.h. ich muss die Sache irgendwie anders anpacken.
Vielleicht kann mir hier jemand einen Denkanstoß geben.

Vielen Dank.

_________________
mfg
Jocke
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 12.09.08 11:30 
Moin!

user profile iconJocke hat folgendes geschrieben:
Vielleicht kann mir hier jemand einen Denkanstoß geben.
Ein TStringGrid ist eine Anzeige, kein Datenlager... :roll: ;)

Lies die Daten in interne Datenstrukturen oder eine Datenbank ein und gib nur das Ergebnis aus. :idea:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Jocke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28

XP
D6 Pers
BeitragVerfasst: Fr 12.09.08 11:35 
Hallo Narses,
kannst du mir zu
user profile iconNarses hat folgendes geschrieben:
Lies die Daten in interne Datenstrukturen

mal ein Stichwort geben ?

_________________
mfg
Jocke
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 12.09.08 12:55 
Moin!

Schau mal, ob du mit Suche in: Delphi-Forum, Delphi-Library CSV DATEI LADEN weiter kommst. :lupe: :les: Wenn nicht, schauen wir hier weiter. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Jocke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28

XP
D6 Pers
BeitragVerfasst: Fr 12.09.08 13:59 
Hallo Narses,

erst mal vielen Dank für deine Antwort.

Also das eigentliche Einlesen der CSV-Datei macht keine Probleme, dass läuft schon.
Deinen Hinweis, dass ein Stringgrid kein Datenspeicher ist, werde ich in Zukunft auf jeden Fall beherzigen, dass war mir bisher nicht so klar.
Ich könnte ja hier ein Array oder Record nehmen, dass ist kein Problem.

Die eigentliche Problemstellung für mich ist hier nur, wie ich, wenn ich einen Datensatz aus der 2. Datei habe, am schnellsten den Index des passenden Datensatzes aus dem Array herausfinde.

also :

array[1]=100000
array[2]=100001
array[3]=100002
array[4]=100003
....
array[10000]=1xxxxx


Nun habe ich in der 2.Datei die 100002. Wie komme ich nun am schnellsten zu dem Index 3 ?

Meine Überlegung, hier mit einer Schleife alle Datensätze zu durchsuchen, ist ja nicht effektiv.
Mittlerweile bin ich auch auf die binäre Suche gekommen, die ja schon wesentlich effektiver sein würde.
Aber letztendlich müsste auch hier das array bei jedem Datensatz der 2.Datei durchsucht werden.

Geht das nicht anders ?

Ich habe mal folgende Idee:
Beim Einlesen der ersten Datei schreibe ich die Fremdnummer, über die ja verknüpft wird, als eigene Section in ein INI-Datei
ausblenden Quelltext
1:
ini.WriteString('100000','Index','1');					

Wenn ich nun in der 2. Datei auf einen Datensatz mit 100000 treffe, finde ich den Index mit
ausblenden Quelltext
1:
ini.readString('100000','Index','0');					

sofort heraus, ohne dass Array durchsuchen zu müssen.
Oder ist das totaler Quatsch und man kommt um eine Suche im Array nicht herum ?

_________________
mfg
Jocke
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Fr 12.09.08 14:13 
Das mit der ini ist noch langsamer. Nimm doch einfach Tstringlist, in die Strings kopierst du den Text und bei Object die Fremdnummer. Tstringlist bietet schon Methoden zum Sortieren!
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Fr 12.09.08 14:27 
Hi, so kannst dus schnell auslesen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure LoadCSV(FileName: String; Divisor: Char); //Divisor=,
var CSV: TextFile; S: String; Part: String;
begin
  AssignFile(CSV,FileName);
  Reset(CSV);
  
  while not EoF(CSV) do //EoF=End of File
    begin
      ReadLn(CSV,S);



      while Pos(Divisor,S)>0  do
        begin 
          Part:=Copy(S,1,Pos(Divisor,S)-1); //bis zum , abschneiden
          S:=Copy(S,Pos(Divisor,S)+1,Length(S));  //reststring=ab dem ,
        end;
      Part:=S; //falls in deiner CSV das letzte Zeichen kein , ist
    end;

  CloseFile(CSV);
end;


Part kannst du dann in ein array of array of String schreiben, das hab ich der übersichtlichkeit wegen weggelassen

Wenn du dann 2 von diesen Arrays hast (2 Dateien):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
for F1:= 0 to High(Arr1[0]) do
  for F2:= 0 to High(Arr2[0]) do
     if (Arr1[0,F1]=Arr2[0,F2] then
        {Feld1 von Datei 1 = Feld1 von Datei 2. Jetzt einfach eine neue Row in einem StringGrid nehmen und die beiden Array-Spalten eintragen => Fertig}

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 12.09.08 14:55 
Ein ähnliches Problem (was CSVs angeht) gabs vor Kurzem, dort wurde auf diese Klasse verwiesen, die dein Problem vereinfachen dürfte:
www.delphipraxis.net...+von+csvdateien.html