Entwickler-Ecke
Dateizugriff - Text in einer Datei suchen und auslesen lassen!
del1312 - Fr 16.06.06 14:35
Titel: Text in einer Datei suchen und auslesen lassen!
Hallo Leute,
ich habe eine Datei wo Gruppenleiter drin stehen und dazu die jeweiligen User. Nun möchte ich gern das ein Gruppenleiter sich anmeldet am Programm und dort automatisch seine eingetragen User angezeigt werden. Außerdem soll er die Möglichkeit haben seiner Gruppe User zu löschen oder hinzuzufügen. Wie lese ich nun die Gruppenleiterzeile aus und auch die User?
Hab bis jetzt:
| Zitat: |
| memo1.Lines.LoadFromFile(dateipfad); |
aber da wird ja nur die ganze Datei angezeit.
Als Beispiel sieht die Datei so aus:
| Zitat: |
gruppenleiter_1::101:user1,user2,user10
gruppenleiter_2::102:user2,user10,user30
gruppenleiter_3::103:user1,user5,user34
|
Wäre supi wenn mir einer helfen könnte :o) Vielen Dank schonmal!!!
Marco D. - Fr 16.06.06 15:08
Arbeite lieber mit ini-Files:
| Zitat: |
[gruppenleiter1]
1=peter
2=klaus
[gruppenleiter]2
1=anneliese
2=uschi
|
Guck mal hier:
http://dsdt.info/tutorials/ini/
del1312 - Fr 16.06.06 15:25
Danke für den Tipp, aber das geht leider nicht. Ich lese da nen Group-File von nem Unix-Server aus. Ich muss so das Format nehmen nur halt wenn sich jetzt Gruppenleiter_1 anmeldet dann soll halt die Zeile ausgelesen werden, die User aus der Zeile ebenfalls zerstückelt werden so das dann für den Gruppenleiter da steht:
Hallo Gruppenleiter_1
Angemeldet in deiner Gruppe sind: user1
user2
user3
fidionael - Fr 16.06.06 16:38
Dann wirst du, denke ich, selber parsen müssen. Schreibe doch eine Funktion, die als Parameter den Namen oder die Ordnungszahl des Gruppenleiter erwartet und dann erstmal die entsprechende Zeile ausliest. Diese kannst du dann ja noch, immer wenn ein Komma vorkommt in einzelne User aufteilen.
Folgender Quelltext ist sehr quick and dirty, aber er funktioniert (inklusive Usernamentrennung):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| var f: Textfile; line,user: String; i: Integer; begin AssignFile(f,'datei.txt'); {$I-} Reset(f); {$I+} if ioResult <> 0 then MessageBox(Handle,'Fehler beim Öffnen der Datei!',pChar(Caption), MB_ICONERROR) else while not eoF(f) do begin ReadLn(f,line); if Pos(Edit1.Text,line) > 0 then begin Delete(line,1,Length(Edit1.Text)+2); while Length(line)>0 do begin if Pos(',',line) > 0 then begin User:=Copy(line,1,Pos(',',line)-1); Delete(line,1,Pos(',',line)); end else begin User:=line; Delete(line,1,Length(line)); end; ListBox1.Items.Add(User); end; end; end;
CloseFile(f); end; |
Hoffe das hilft dir. Mfg.
Edit1: Quelltext geändert.
del1312 - Fr 16.06.06 18:08
danke .... puh .... kannste mir das ganze vielleicht etwas erklären? was genau macht da jede zeile? bastle zwar schon ne weile in delphi rum aber man lernt ja immer wieder neues :o) und das ist grad neues gelände.
del1312 - Fr 16.06.06 18:44
vielen dank das hat mich schon nen stückchen weiter gebracht. hab mal im anhang das komplette projekt drin. könntest es dir mal anschauen und mir erklären wie ich jetzt per klick die user von der einen listbox in die anndere bekomme und wie ich dann die veränderten user wieder speichere? danke schonmal deine hilfe war echt supi :o)
fidionael - Sa 17.06.06 14:09
Grüß dich.
Tut mir leid, dass ich erst jetzt schreibe, aber gestern Abend war ich leider verhindert. Also erstmal habe ich deine FormCreate-Prozedur vollständig entfernt - der ButtonClick auf Anmelden genügt hierbei.
Weiterhin habe ich erstmal deine "vom-einer-Listbox-in-die-andere-verschieben"-Knöpfe implementiert, dass sieht dann folgendermaßen aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure TForm1.ItemVerschiebenClick(Sender: TObject); var i: Integer; begin if Sender=Button2 then begin for i:=(Listbox1.Count-1) downto 0 do if Listbox1.Selected[i] then Listbox2.Items.Add(Listbox1.Items[i]); Listbox1.DeleteSelected; end;
if Sender=Button3 then begin for i:=(Listbox2.Count-1) downto 0 do if Listbox2.Selected[i] then Listbox1.Items.Add(Listbox2.Items[i]); Listbox2.DeleteSelected; end; end; |
Nun bin ich aber mal so auf einige Probleme gestoßen:
- Woher entnimmst du die Daten aus Listbox2? Wäre hier nicht eine Datei nötig, in welcher alle User, oder zumindest alle User, die bisher keiner Gruppe zugeordnet sind festgehalten werden? Falls eine solche Datei nicht vorhanden ist, musst du sicher gehen, dass vorm Speichern der Datei kein User mehr über ist, sonst würde dieser ja endgültig verloren gehen.
- Beim Laden der Datei und Füllen der Listbox1 (Button1Click) muss auch die Listbox2 wieder auf ihren Ausgangszustand zurückgesetzt werden, da sonst User doppelt eingetragen werden können.
Soviel erstmal, über dass du dir Gedanken machen kannst, ich gucke in der Zeit mal, ob ich dir eine gescheite Speicherprozedur geschrieben kriege.
Mfg
Edit1:
Vielleicht wäre auch noch eine Sortierung der Usernamen beim Verschieben sinnvoll. Aber das kannst du dir ja noch selbst überlegen - es erscheint mir jetzt nicht so essenziell; ist nur so ein Tipp von mir.
del1312 - Sa 17.06.06 14:39
hi fidionael,
kein prob bin ja voll froh das du mir so geduldig hilfst :o) ich hab noch ein wenig zeit das tool fertig zu basteln von daher kein stress :o) ich werde das gleich mal umbasteln wie du beschrieben hast.
ja genau da muß ne zweite datei her wo ich alles user drin hab. das ganze muss so funktionieren das ich user auch hinzufügen kann und die dann auch angezeigt werden. wie funktioniert das mit dem auslesen in der listbox um alle user anzuzeigen und als einzelnes listbox.itemindex anzugeigen damit man die dann auswählen kann?
vielen dank nochmal für deine hilfe!!!!!
fidionael - Sa 17.06.06 15:38
ecspooky hat folgendes geschrieben: |
| ja genau da muß ne zweite datei her wo ich alles user drin hab. das ganze muss so funktionieren das ich user auch hinzufügen kann und die dann auch angezeigt werden. wie funktioniert das mit dem auslesen in der listbox um alle user anzuzeigen und als einzelnes listbox.itemindex anzugeigen damit man die dann auswählen kann? |
Tut mir Leid, aber den kompletten Absatz verstehe ich nicht so richtig. Also ich bin ja schonmal froh, dass wir auf einer Wellenlinie sind, was die zweite Datei betrifft, aber ab der Frage "wie funktioniert..." verstehe ich nicht mehr was du meinst. Kannst du das vielleicht näher erläutern?
Weitere Frage: Hast du so eine Datei in der alle nicht zugeteilten User gespeichert sind, oder wie stellst du dir vor an eine solche Datei zu gelangen? Ist ja eigentlich nicht meine Angelegenheit, aber das klingt bei dir so, als müsstest du ein Programm schreiben zu einer Userdatenbank, auf die du vielleicht Lesezugriff hast, jedoch keine struktuellen Veränderungen machen kannst. Das kann dann beliebig kompliziert werden. Du musst mich in keine konkreten Sachverhalte einweihen, aber desto detaillierter du wirst, desto besser kann ich dir helfen.
Mfg.
PS: Ich habe dir mal eine Parsing-Unit für dein Format geschrieben, die etwas übersichtlicher und auch kommentiert ist. Außerdem wird das Auslesen der Datei nicht mehr mit der Darstellung dieser Auslesung vermischt. Statt dessen wird das Ergebnis des Parsings in einem eigenen Variablentyp TParsingResult zurückgegeben. Das macht die Sache wesentlich sauberer:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72:
| unit Parsing;
interface
type TParseResult = record Count: Integer; User: Array of String; end;
function Parse(filename, leader_id: String) : TParseResult;
implementation
function Parse(filename, leader_id: String) : TParseResult; var f: Textfile; line, arg: String; begin with Result do begin Count:=0; SetLength(User,Count); end;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult = 0 then while not eoF(f) do begin ReadLn(f,line);
if Pos(leader_id,line) > 0 then begin Delete(line,1,Length(leader_id)+2);
while Length(line) > 0 do begin if Pos(',',line) > 0 then begin arg:=Copy(line,1,Pos(',',line)-1); Delete(line,1,Pos(',',line)); end else begin arg:=line; Delete(line,1,Length(line)); end;
with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=arg; end; end;
Break; end; end;
CloseFile(f); end;
end. |
Edit1:
Benutzt wird die Unit übrigens, indem du sie - logisch - erstmal zu deinem Programm hinzufügst (Uses Parsing). Deine ButtonClick-Prozedur sähe mit Parsing-Unit dann etwa so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TForm1.Button1Click(Sender: TObject); var i: Integer; leader: TParseResult; begin Listbox1.Clear; leader:=Parse('datei.txt',Edit1.Text); for i:=0 to (leader.Count-1) do Listbox1.Items.Add(leader.User[i]); end; |
del1312 - Sa 17.06.06 19:06
Hi Fidionael,
danke für den Code, hab mal alles eingebaut und funzt auch soweit, siehe Anhang. Bin dank dir echt schon gut vorwärts gekommen. Ok das meiste war eh alles von dir und ich hab es nur zusammengesetzt ;o)
Also ich werd dir kurz erzählen wozu das Programm benötigt wird. Wir haben einen Server auf dem Projekte gespeichert werden. Nun hat da nicht jeder Zugriff drauf und nur der Projektleiter soll entscheiden können welcher User Zugriff bekommt und wer wieder ausgesperrt werden soll. Dazu gibt es auf dem Server die Datei group. Diese regelt das Ganze.
Nun lesen wir diese Datei aus und der Projektleiter sieht welche User auf dem Programm angemeldet, also seiner Gruppe dazugehört. Er soll nun die Möglichkeit haben User wieder auszusperren oder aus der zweiten Listbox weitere User hinzuzufügen. Da kommen wir dann auch schon zu der der zweiten Listbox. Die ist ja noch leer. Hab eine Datei angelegt "user.txt" wo alle user mal gelistet sind. Diese sollte beim start des Programms dann auch in der Listbox2 erscheinen. Mit einer kleinen Ausnahme! Das Programm liest erst Listbox1 und wenn dann Listbox2 gelesen wird und ein User bereits in Listbox1 stehe sollte er nicht in Listbox2 nochmal erscheinen.
Ich hab noch ne kleine Änderung eingebaut. Man muß als Projekt leiter nun nicht z.B u019 eingeben sondern u019::
Hat den Hintergrund das z.B der Projektleiter selber auch in anderen Projekten als User eingetragen ist und somit wird ausgeschlossen das u019 bereits woanders gefunden und angezeigt wird. Das kann man sicher später noch ändern in dem man einfach bei der Eingabe noch '::' hinzufügt hab aber noch nicht gefunden wie es klappt.
Die Listbox2 muss nicht gespeichert werden sondern wird nur ausgelesen und jenachdem welche User in Listbox1 stehen die restlichen User angezeigt. Listbox1 soll aber nach beenden des Programms so gespeichert werden.
Hoffe das hilft dir etwas weiter und wenn noch Zeit und Geduld hast, wäre schön wenn du mit noch helfen könntest!!!
NOCHMAL RIESEN DANKE!!!!!!
fidionael - So 18.06.06 00:20
Mit Speichern schick ich entweder heute Nacht noch ein Post oder morgen früh, aber dein Problem, dass die ID des Group Leaders noch an anderer Stelle auftreten könnte, ist sehr schnell behoben, das mach ich dann jetzt eben on the fly :)
1. Möglichkeit
Das wäre deine Idee, dass du an die gesuchte ID einfach
:: anhängst:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72:
| unit Parsing;
interface
type TParseResult = record Count: Integer; User: Array of String; end;
function Parse(filename, leader_id: String) : TParseResult;
implementation
function Parse(filename, leader_id: String) : TParseResult; var f: Textfile; line, arg: String; begin with Result do begin Count:=0; SetLength(User,Count); end;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult = 0 then while not eoF(f) do begin ReadLn(f,line);
if Pos(leader_id+'::',line) > 0 then begin Delete(line,1,Length(leader_id)+2);
while Length(line) > 0 do begin if Pos(',',line) > 0 then begin arg:=Copy(line,1,Pos(',',line)-1); Delete(line,1,Pos(',',line)); end else begin arg:=line; Delete(line,1,Length(line)); end;
with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=arg; end; end;
Break; end; end;
CloseFile(f); end;
end. |
Eigentlich recht trivial wenn man sich das so ansieht :P
2. Möglichkeit
Diese Variante ist ironischer Weise noch einfacher und entspricht vermutlich sogar eher dem, was du suchst:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72:
| unit Parsing;
interface
type TParseResult = record Count: Integer; User: Array of String; end;
function Parse(filename, leader_id: String) : TParseResult;
implementation
function Parse(filename, leader_id: String) : TParseResult; var f: Textfile; line, arg: String; begin with Result do begin Count:=0; SetLength(User,Count); end;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult = 0 then while not eoF(f) do begin ReadLn(f,line);
if Pos(leader_id,line) = 1 then begin Delete(line,1,Length(leader_id)+2);
while Length(line) > 0 do begin if Pos(',',line) > 0 then begin arg:=Copy(line,1,Pos(',',line)-1); Delete(line,1,Pos(',',line)); end else begin arg:=line; Delete(line,1,Length(line)); end;
with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=arg; end; end;
Break; end; end;
CloseFile(f); end;
end. |
Die markierte Zeile nimmt nun die gefundene ID nur wahr, wenn diese am Anfang der Zeile steht. Damit sollte das Problem ja gelöst sein.
Bitte beachte hierbei, dass in beiden Fällen die Änderungen beim Parsen gemacht wurden; der Gruppenleiter muss also nach wie vor nur die ID ohne
:: eingeben.
Mfg
fidionael - So 18.06.06 01:01
Ich muss gestehen, die Speicherung habe ich immer noch nicht fertig implementiert, aber das korrekte Auslesen der User-Datei schon. Ich habe das ganze mal einfach in meiner Parsing-Unit gemacht: Ich habe hierfür die Funktion Parse
overloaded. Das sieht dann so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106:
| unit Parsing;
interface
type TParseResult = record Count: Integer; User: Array of String; end;
function Parse(filename, leader_id: String) : TParseResult; overload; function Parse(filename: String; Ignore: TParseResult) : TParseResult; overload;
implementation
function Parse(filename, leader_id: String) : TParseResult; overload; var f: Textfile; line, arg: String; begin with Result do begin Count:=0; SetLength(User,Count); end;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult = 0 then while not eoF(f) do begin ReadLn(f,line);
if Pos(leader_id,line) = 1 then begin Delete(line,1,Length(leader_id)+2); Delete(line,1,Pos(':',line));
while Length(line) > 0 do begin if Pos(',',line) > 0 then begin arg:=Copy(line,1,Pos(',',line)-1); Delete(line,1,Pos(',',line)); end else begin arg:=line; Delete(line,1,Length(line)); end;
with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=arg; end; end;
Break; end; end;
CloseFile(f); end;
function Parse(filename: String; Ignore: TParseResult) : TParseResult; overload; var f: Textfile; line: String; i: Integer; begin with Result do begin Count:=0; SetLength(User,Count); end;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult = 0 then while not eoF(f) do begin ReadLn(f,line);
i:=0; while (i<Ignore.Count) and (line<>Ignore.User[i]) do inc(i); if i = Ignore.Count then with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=line; end; end;
CloseFile(f); end;
end. |
In deiner ButtonClick-Prozedur sieht das dann so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure TForm1.Button1Click(Sender: TObject); var leader, spare_users: TParseResult; i: Integer; begin Listbox1.Clear; Listbox2.Clear;
leader:=Parse('datei.txt',Edit1.Text); spare_users:=Parse('user.txt',leader);
for i:=0 to (leader.Count-1) do Listbox1.Items.Add(leader.User[i]); for i:=0 to (spare_users.Count-1) do Listbox2.Items.Add(spare_users.User[i]); end; |
Ich hoffe, das Problem ist damit beseitigt und nun wende ich mich dann *wirklich* dem Speichern zu. Achso, ich habe den Quelltext einfach mal so geschrieben und ihn nicht wirklich getestet; kompilieren tut er - ich kann aber nicht dafür garantieren, dass er einwandfrei läuft. Sollten diesbezüglich Schwierigkeiten auftreten melde dich einfach.
Mfg
Post Scriptum:
Ich habe mir grad mal deine angehängte Datei 'datei.txt' angeguckt:
Quelltext
1: 2: 3: 4: 5:
| u001::100:u001,u007,u049,u047,u077 u007::107:u007,u062,u049 u011::111:u011,u073,z001 u014::114:u014,u011,u047,u051 u019::119:u019,u045,u077,u047,u007,u022,u011,u049,u030 |
Haben die Zahlen hinter
:: etwas zu bedeuten, oder sollen die beim Parsen einfach ausgelassen werden?
Edit1:
Tut mir Leid, dass ich hier ja schon Spam-Qualitäten beweise, aber ich habe gerade System hinter den Zahlen entdeckt *g* und beschlossen, dass diese für das Parsing wohl eher irrelevant sind. Ich habe den Quelltext der Parsing-Unit schon so modifiziert, dass diese ignoriert werden. Falls du das aus irgendeinem Grund nicht möchtest, einfach die markierte Zeile in der Unit wieder löschen ;)
fidionael - So 18.06.06 02:23
Hallo zum 3. Mal am Stück - doch ich glaube um die Übersicht ein wenig zu wahren ist es sinnvoll, einen neuen Post zu öffnen, außerdem hatte ich dies ja auch weiter oben versprochen...
Ich habe also nun auch das Speichern der Userzusammenstellungen implementiert. Ich war allerdings heute Nacht zu faul alles noch großartig durchzutesten - wie oben: es kompiliert, mehr garantiere ich nicht. Ich habe die Funktion Parse für den Schreibzugriff übrigens einfach nochmals overloaded:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151:
| unit Parsing;
interface
type TParseResult = record Count: Integer; User: Array of String; end;
function Parse(filename, leader_id: String) : TParseResult; overload; function Parse(filename: String; ignore: TParseResult) : TParseResult; overload; function Parse(filename, leader_id: String; userlist: TParseResult) : Boolean; overload;
implementation
function Parse(filename, leader_id: String) : TParseResult; overload; var f: Textfile; line, arg: String; begin with Result do begin Count:=0; SetLength(User,Count); end;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult = 0 then while not eoF(f) do begin ReadLn(f,line);
if Pos(leader_id,line) = 1 then begin Delete(line,1,Length(leader_id)+2); Delete(line,1,Pos(':',line));
while Length(line) > 0 do begin if Pos(',',line) > 0 then begin arg:=Copy(line,1,Pos(',',line)-1); Delete(line,1,Pos(',',line)); end else begin arg:=line; Delete(line,1,Length(line)); end;
with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=arg; end; end;
Break; end; end;
CloseFile(f); end;
function Parse(filename: String; ignore: TParseResult) : TParseResult; overload; var f: Textfile; line: String; i: Integer; begin with Result do begin Count:=0; SetLength(User,Count); end;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult = 0 then while not eoF(f) do begin ReadLn(f,line);
i:=0; while (i<ignore.Count) and (line<>ignore.User[i]) do inc(i); if i = ignore.Count then with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=line; end; end;
CloseFile(f); end;
function Parse(filename, leader_id: String; userlist: TParseResult) : Boolean; overload; var f: Textfile; line: String; buf: Array of String; i: Integer; begin Result:=True;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult <> 0 then Result:=False else begin while not eoF(f) do begin ReadLn(f,line); if Pos(leader_id,line) = 1 then begin line:=leader_id+'::1'+Copy(leader_id,3,4)+':'; for i:=0 to (userlist.Count-1) do begin line:=line+userlist.User[i]; if i<(userlist.Count-1) then line:=line+','; end; end; SetLength(buf,High(buf)+2); buf[High(buf)]:=line; end;
{$I-} Rewrite(f); {$I+} if ioResult <> 0 then Result:=False else for i:=0 to High(buf) do WriteLn(f,buf[i]); end;
CloseFile(f); end;
end. |
In deiner Unit1 benutzt du die neue Funktion dann folgendermaßen (Button2 ist bei mir der Speicher-Button):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TForm1.Button2Click(Sender: TObject); var leader: TParseResult; i: Integer; begin with leader do begin Count:=0; SetLength(User,0);
for i:=0 to (Listbox1.Count-1) do begin inc(Count); SetLength(User,Count); User[Count-1]:=Listbox1.Items[Count-1] end; end;
if not Parse('datei.txt',Edit1.Text,leader) then MessageBox(Handle,'Es ist ein Fehler aufgetreten!', pChar(Caption),MB_ICONERROR); end; |
Achtung: Meine Button2Click-Prozedur ist unglaublich fehleranfällig und dient nur der Veranschaulichung. Das Problem in meiner Prozedur ist, dass trotzdem der User den Inhalt des Edit-Felds uneingeschränkt verändern kann, eben dieser Inhalt als Parameter an die Funktion übergeben wird. Viel sicherer wäre es, beim Laden die ID des Gruppenleiters private für Form1 in einer Variable zu speichern und diese Variable dann an die Funktion zu übergeben. Damit verhinderst du ohne viel Arbeitsaufwand, dass deine Anwender deine Datei zerstören können.
Mfg
del1312 - So 18.06.06 02:47
supi funzt echt klasse nur eins. das system der zahlen stimmt nicht ganz :o)
also es muss so sein, ich gebe z.b u019 ein und dann muß das system nach u019::xxx: suchen
hatte das immer so umgebastelt:
| Zitat: |
// Falls die ID des Gruppenleiters gefunden wurde, teile diese Zeile
// in die verschiedenen User auf und gib diese als Result zurück.
if Pos(leader_id+'::',line) = 1 then begin
Delete(line,1,Length(leader_id)+10);
Delete(line,1,Pos(':',line)); |
nach dem projektleiternamen u019 kommen die zwei :: danach kommt eine 3stellige groupid, die muss aber nicht mit 1 anfangen. das kann auch ne ganz andere zahl sein. (am besten wäre es wenn diese zahl vorher noch in einer variable gesichtert wird und dann wieder beim speichern dazwischen gesetzte wird) danach kommt nochmal ein : und hinterher der projektleiter selber nochmal, er muss ja selber auch drin stehen in der gruppe. damit der nicht beim programm mit angezeigt wird und sich ausversehen selber aus der gruppe wirft habe ich die zahl +10 geändert. damit schaut das prog nach u019 und zählt dazu 10 stellen weiter.
u019::119:u019, u001,u004,u034,u045
werde mir das ganze dann mal in ruhe anschauen um auch alles zu verstehen. ich lerne sowas immer ganz gut das ich den code ändere und schaue was passiert. hätte das nie ohne deine hilfe hinbekommen. vielen dank nochmal!
sobald alles steht bau ich eh noch ne kleine kennwortabfrage sein, damit auch nur ein projektleiter die datei ändern lann und auch nur seine gruppe und nicht die anderen ändern kann, von daher denke ich wird das mit der falscheingabe nicht so dramatisch :o)
nachtrag:
nochwas, ich hab da nen kleinen fehler geamcht. der syntax lautet nicht:
u019::119:u019,u001,u004,u034,u045
sondern z.b
re::234:u019,u001,u004,u034
also ganz vorne steht nur ne zweistellige id(re) aus buchstaben, dann die 3stellige zahlen id(234), dann der gruppenleiter(u019) und dann die ganzen user. hoffe das ist jetzt nicht noch viel kompliziert als es schon ist *rotwerd*
del1312 - So 18.06.06 03:59
ich bins nochmal, das ganze hat mir keine ruhe gelassen und ich hab ein wenig rumprobiert. das mit:
| Zitat: |
| Delete(line,1,Length(leader_id)+10); |
klappt doch nicht weil ja nicht zwingend nach
rd::345:
u019,u047
gleich die u019 kommt, sobald ich nen user eintrage der ne kleinere zahl hat steht der an der stelle und wird nicht mehr angezeigt.
rd::345:u001,u019
man da stecken doch noch ein paar problemchen drin. ich glaub es müßte so sein, das der gruppenname z.B rd gespeichert wird und der username der auch gleichzeitg der gruppenleiter ist. also ich würde das vorher so coden das
| Zitat: |
if edit1.text='rd' then leiter='u001'
if edit1.text='df' then leiter='u015'
if edit1.text='ht' then leiter='u045' |
dann darf halt der leiter nicht nicht in der listbox1 und listbox2 erscheinen. ich hoffe du verstehst das ganze noch wie ich es meine, läßt sich schwer erklären :l)
fidionael - So 18.06.06 10:51
Ui und ich dachte, dass das Projekt sich jetzt dem Ende zuneigen würde...
Du sagst es ist schwierig zu erklären und ich muss gestehen, dass ich auch nicht alles zu 100% verstanden habe. Also, bevor ich wieder irgendwas umschreibe, folgende Verständnisfragen:
ecspooky hat folgendes geschrieben: |
nochwas, ich hab da nen kleinen fehler geamcht. der syntax lautet nicht:
u019::119:u019,u001,u004,u034,u045
sondern z.b
re::234:u019,u001,u004,u034
also ganz vorne steht nur ne zweistellige id(re) aus buchstaben, dann die 3stellige zahlen id(234), dann der gruppenleiter(u019) und dann die ganzen user. hoffe das ist jetzt nicht noch viel kompliziert als es schon ist *rotwerd* |
Mit was soll der Text den der Anwender in Edit1 angibt denn nun verglichen werden?! Mit der ID
re oder immer dem ersten Argument der User, also in dem Falle dann
u019? Wenn du nach der ID suchst, wie findest du heraus, welche ID zu welchem Gruppenleiter gehört?
Und habe ich das richtig verstanden, dass der Gruppenleiter gar nicht zwingend als erster User aufgeführt wird? Dann wird es wirklich kompliziert :shock:
Da muss ich ja das Parsing quasi komplett wieder umwerfen und neu schreiben...
del1312 - So 18.06.06 11:19
sorry hoffe du hast noch etwas zeit und geduld fürs projekt. also ich versuch es nochmal genau zu erklären.
dei gruppenleiter melden sich am programm an, ich baue dazu noch eine kennwortabfrage ein. z.b
user: u019 <--- nr des gruppenleiters, nein name lautet z.b Peter Mustermann
kennwort: blabla
nun ereknnt das Programm das sich ein Gruppenleiter angemeldet hat und ordnen diesen User der Gruppe:
pm <---- so lautet die Gruppe, Anfangsbuchstaben des Projketleites halt zu
diese gruppen hab ich vorher angelegt nach dem schema, das der name der gruppe sich aus dem buchstaben der leiter
zusammensetzt, danache kommt :: und dann noch eine gruppenid. die muss sein und ist immer ne 3stellige zahl. jetzt kommt nochmal ein : und danach kommen die usereintragungen. da unser gruppenleiter jetzt die nr u019 hat steht er nicht immer gleich an erster stelle, sobald er andere user einträgt wie z.b u001 oder u010 usw. da das programm aber die user sortiert werden die halt alphabetisch eingtragen. könnte dann so aussehen:
pm::432:u001,u010,u019
dadurch ist der gruppenleiter nicht immer der erste user in der gruppe.
also paß auf, wenn das jetzt zu heftig wird, dann nehme ich halt die sortierung raus, das ist zwar nicht sehr andwenderfreundlich aber dann sollte es ja klappen. was meinste?
del1312 - So 18.06.06 11:23
wäre es nicht möglich, das man den gruppennamen, die gruppenid und den ersten user isoliert? also nur die user die danach kommen sortieren läßt und bevor man speichert gruppenname, id und erstenuser wieder davor schreibt?
fidionael - So 18.06.06 11:29
1. Möglichkeit
Du sortierst nicht in der Datei, sondern immer nur lokal nachdem du die Datei ausgelesen hast und gibst beim Speichern die Namen auch so wieder zurück, dass der Gruppenleiter immer an erster Stelle steht. Dann machst du also die komplette Sortierung in deiner Unit1 und merkst dir vorher am besten, wer Gruppenleiter ist und setzt diesen dann wieder an erste Stelle
2. Möglichkeit
Du hast eine Tabelle in welcher man auslesen kann, welche ID (ob du hier die 2-stellige oder 3-stellige nimmst sollte soweit ich das verstanden habe egal sein) zu welchem User-Namen gehört. Dann liest du beim Parsing halt nur die entsprechende ID aus und findest dann durch Überprüfen der Tabelle den zugehörigen User-Namen.
Ich bin mir ehrlich gesagt nicht so sicher, welches eigentlich die hübschere Variante ist - ich glaube die erste ist weniger Arbeit und Performance-sparender, doch wenn die Dateien auch von anderen als dir verändert werden können und auch nur die geringste Möglichkeit besteht, dass der Gruppenleiter irgendwann nicht mehr an erster Stelle steht ist die erste Möglichkeit - logischerweise - nicht mehr praktikabel.
Mfg
Post Scriptum:
ecspooky hat folgendes geschrieben: |
| wäre es nicht möglich, das man den gruppennamen, die gruppenid und den ersten user isoliert? also nur die user die danach kommen sortieren läßt und bevor man speichert gruppenname, id und erstenuser wieder davor schreibt? |
Geht auch, ist aber glaube ich aufwendiger als die erste Variante und läuft auf das Selbe hinaus.
Edit1:
Oh, ich sollte erst nachdenken, bevor ich schreibe *g* Wenn du den Usernamen des Gruppenleiters in Listbox1 ignorieren willst, hast du ja irgendwann ein TParseResult ohne ihn mit allen anderen. Dieses kannst du dann sortieren und fertig ist es. Das sollte ja genau das sein was du meintest ;)
del1312 - So 18.06.06 12:14
puh da qualmt mir echt noch der kopf, komme mit den ganzen befehlen im parsing nicht klar.
hab das ganze jetz mal so geschrieben das man sich anmelden muss. als tester hab ich
user: u019
kennwort: test
das programm erkennt ihn als user und die leader_id ist nun rh. so er zeigt mir nun auch alle user
ausser den gruppenleiter selber sortiert an. soweit so gut. bei speichern gibt es da das prob mit der gruppenid
und dem gruppeleiter an erster stelle. ich würde das jetzt so machen. die leader_id ist ja bekannt dann als zweites die gruppen id, also die 3stellige zahl auslesen und in einen wert legen, zb. gid und zum schluss den ersten user, also den gruppenleiter wieder festlegen, da der sich mit seiner id auch schon anmeldet, also mit u019 bräuchte man den wert nur nehmen und an erste stelle setzen, danach die anderen user also quasi so ungefähr:
leader_id + ':' + gid + '::'+ gruppenleiter + restliche user
leider weiß ich überhaupt nicht wo ich da anfangen soll :o(
hab das ganze nochmal mit hochgeladen
fidionael - So 18.06.06 12:55
Erstmal würde ich einen neuen Typ einführen in meiner Parse-Unit:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| type TGroupLeader = record Username: String[20]; ID: String[2]; GID: Integer; end; |
Nun kann man ja nach dem Usernamen des Gruppenleiters als erstes Argument in der Userkette suchen. Wurde dies gefunden, sucht man am Anfang der Zeile die ID und danach die GID, richtig? Wenn das so stimmt schreibe ich die Parsing-Unit eben dementsprechend um, aber dann poste hier nochmal bitte das
definitiv richtige Format einer Zeile in der Datei, denn
leader_id + ':' + gid + '::'+ gruppenleiter + restliche user
ist ja schon wieder etwas völlig anderes. Achte also auf jeden Fall auf die richtige Reihenfolge und die Anzahl der Doppelpunkte, etc. Dann sollte das alles recht schnell zu beheben sein.
Mfg
del1312 - So 18.06.06 18:50
ok also die genaue syntax lautet:
| Zitat: |
| pm:543::u019,u013,u034,u055 |
pm - ist der gruppenname, immer zweistellig
:
543 - Gruppen-ID und immer dreistellig
::
u019 - der gruppenleiter
,u013,u034 - das sind die user die in der gruppe mit drin sind
| Zitat: |
| Nun kann man ja nach dem Usernamen des Gruppenleiters als erstes Argument in der Userkette suchen. Wurde dies gefunden, sucht man am Anfang der Zeile die ID und danach die GID, richtig? |
mach es nicht so aufwendig. der gruppenleiter gibt ja seine user-nr ein hier als z.b u019 und dazu sein kennwort.
das programm erkennt nun aha u019 meldet sich an als ist er der eigentümer der gruppe pm. nun brauchst du nur nach pm suchen, dies ist einmalig in der datei und schon hast du die zeile. jetzt sollte man einfach den anfang der zeile abschneiden und in eimem wert speicher.
ganze zeile:
pm:543::u019,u013,u034,u055
anfang:
pm:543::u019,
abgeschnitten
u013,u034,u055
diese user sollen dann in der listbox erscheinen. nun kann ich weitere user aus der listbox2 hinzufügen oder austragen
wenn ich nun das programm speichern und beenden will wird einfach der
abgeschnittene teil (mit den usern) zu dem
anfang wieder drangebastelt und gespeichert.
sieht dann so aus:
pm:543::u019,u013,u034,u042,u049,u055
oh man, wenn wir das echt hinbekommen, schulde ich dir was, dann lass ich mir was einfallen :o)
fidionael - Mo 19.06.06 00:21
Hallo!
Pünktlich zu Beginn des neuen Tages stelle ich dir nun mal meine neue Parsing-Unit vor. Ich habe sie nochmal komplett umgeschmissen und neu geschrieben. Sie sollte nun alles beinhalten was du willst - ich kann jedoch nicht garantieren, dass sie fehlerfrei läuft: ich habe alles ohne wirkliche Planung so runter geschrieben; es wäre ein Wunder, wenn keine Bugs existierten. Nun will ich sie dir nicht länger vorenthalten:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214:
| unit Parsing;
interface
type TUserList = record Count: Integer; User: Array of String; end;
TGroup = record Name: String; ID: Integer; Leader: String; end;
function GetGroupByName(filename: String; Group_Name: String) : TGroup; function GetGroupByID(filename: String; Group_ID: Integer) : TGroup; function GetGroupByLeader(filename: String; Group_Leader: String) : TGroup;
function GetUsers(filename: String; Group: TGroup) : TUserList; function SaveUsers(filename: String; Group: TGroup; UserList: TUserList) : Boolean;
function GetSpareUsers(filename: String; ignore: TUserList) : TUserList;
implementation
uses SysUtils;
function GetGroupByName(filename: String; Group_Name: String) : TGroup; var f: Textfile; buf: String; begin with Result do begin Name:=''; ID:=0; Leader:=''; end;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult = 0 then while not eoF(f) do begin ReadLn(f,buf); if Pos(Group_Name,buf) = 1 then begin with Result do begin Name:=Group_Name; ID:=StrToInt(Copy(buf,5,3)); Leader:=Copy(buf,9,Pos(',',buf)-9); end; Break; end; end; CloseFile(f); end;
function GetGroupByID(filename: String; Group_ID: Integer) : TGroup; var f: Textfile; buf: String; begin with Result do begin Name:=''; ID:=0; Leader:=''; end;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult = 0 then while not eoF(f) do begin ReadLn(f,buf); if Pos(Format('%0.3d',[Group_ID]),buf) = 5 then begin with Result do begin Name:=Copy(buf,1,2); ID:=Group_ID; Leader:=Copy(buf,9,Pos(',',buf)-9); end; Break; end; end; CloseFile(f); end;
function GetGroupByLeader(filename: String; Group_Leader: String) : TGroup; var f: Textfile; buf: String; begin with Result do begin Name:=''; ID:=0; Leader:=''; end;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult = 0 then while not eoF(f) do begin ReadLn(f,buf); if Pos(Group_Leader,buf) = 9 then begin with Result do begin Name:=Copy(buf,1,2); ID:=StrToInt(Copy(buf,5,3)); Leader:=Group_Leader; end; Break; end; end; CloseFile(f); end;
function GetUsers(filename: String; Group: TGroup) : TUserList; var f: Textfile; buf: String; begin with Result do begin Count:=0; SetLength(User,0); end;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult = 0 then while not eoF(f) do begin ReadLn(f,buf); if Pos(Group.Name,buf) = 1 then begin Delete(buf,1,Pos(',',buf)); while Length(buf) > 0 do begin if Pos(',',buf) <> 0 then begin with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=Copy(buf,1,Pos(',',buf)-1); end; Delete(buf,1,Pos(',',buf)); end else begin with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=buf; end; Delete(buf,1,Length(buf)); end; end; end; end; CloseFile(f); end;
function SaveUsers(filename: String; Group: TGroup; UserList: TUserList) : Boolean; var f: Textfile; buf: Array of String; i: Integer; begin Result:=True; SetLength(buf,1);
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult <> 0 then Result:=False else begin while not eoF(f) do begin ReadLn(f,buf[High(buf)]); if Pos(Group.Name,buf[High(buf)]) = 1 then with Group do begin buf[High(buf)]:=Name+'::'+Format('%0.3d',[ID])+':'+Leader; if UserList.Count > 0 then buf[High(buf)]:=buf[High(buf)]+','; for i:=0 to (UserList.Count-1) do begin buf[High(buf)]:=buf[High(buf)]+UserList.User[i]; if i<(UserList.Count-1) then buf[High(buf)]:=buf[High(buf)]+','; end; end; SetLength(buf,High(buf)+2); end;
{$I-} Rewrite(f); {$I+} if ioResult <> 0 then Result:=False else for i:=0 to High(buf) do WriteLn(f,buf[i]); end; CloseFile(f); end;
function GetSpareUsers(filename: String; ignore: TUserList) : TUserList; var f: Textfile; buf: String; i: Integer; begin with Result do begin Count:=0; SetLength(User,Count); end;
AssignFile(f,filename); {$I-} Reset(f); {$I+} if ioResult = 0 then while not eoF(f) do begin ReadLn(f,buf); i:=0; while (i<ignore.Count) and (buf<>ignore.User[i]) do inc(i); if i = ignore.Count then with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=buf; end; end; CloseFile(f); end;
end. |
Sie funktioniert folgendermaßen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48:
| procedure TForm1.Button1Click(Sender: TObject); var group: TGroup; groupUser, spareUser: TUserList; i: Integer; begin Listbox1.Clear; Listbox2.Clear;
group:=GetGroupByName('datei.txt','pm'); groupUser:=GetUsers('datei.txt',group); for i:=0 to (groupUser.Count-1) do Listbox1.Items.Add(groupUser.User[i]); with groupUser do begin inc(Count); SetLength(User,Count); User[Count-1]:=group.Leader; end; spareUser:=GetSpareUsers('user.txt',groupUser);
for i:=0 to (spareUser.Count-1) do Listbox2.Items.Add(spareUser.User[i]); end;
procedure TForm1.Button2Click(Sender: TObject); var group: TGroup; groupUser: TUserList; i: Integer; begin group:=GetGroupByName('datei.txt','pm'); with groupUser do begin Count:=0; SetLength(User,0); end;
for i:=0 to (Listbox1.Count-1) do with groupUser do begin inc(Count); SetLength(User,Count); User[Count-1]:=Listbox1.Items[i]; end;
if not SaveUsers('datei.txt',group,groupUser) then MessageBox(Handle,'Speicherung fehlgeschlagen.', pChar(Caption),MB_ICONERROR); end; |
Zu meiner neuen Parsing-Unit sollte ich vielleicht noch kurz anmerken, dass du die Gruppe, da ich dir die Wahlmöglichkeit lassen wollte, sowohl by Name, als auch ID, als auch Username des Gruppenleiters suchen lassen kannst.
Ich hoffe, dass du dir das ungefähr so vorgestellt hast, bzw. das überhaupt alles funktioniert. Ich habe den Quelltext jetzt mal nicht kommentiert; das war mir zu stressig. Falls Fragen auftauchen sollten, frag einfach.
Mfg
Edit1:
Ich habe einige Bugs in der Parsing-Unit entfernt :)
Edit2:
So, die Schreib-Funktion ist nun auch wieder lauffähig und meine Testphase schließe ich hiermit offiziell ab. Mein laufendes Testprojekt hänge ich für dich mal an. BTW: Das Passwort-Feld soll nur schön aussehen - ist nicht implementiert *gg*
Edit3:
Hab doch noch einige kleine Bugs in der Parsing-Unit gefunden (z. B. hat diese beim Speichern die Group-ID zerschossen) und gefixed. Möglich, dass noch einige Nachträge dieser Art kommen, aber wir nähern uns dem "Stable Release" meiner Parsing-Unit ;)
Edit4:
Da das Problem ja gelöst ist und es sich um ein sehr spezifisches Projekt handelte, habe ich den Dateianhang wieder entfernt.
del1312 - Mo 19.06.06 07:18
super ich teste es grade und baue es noch ein wenig um. sieht aber schon sehr gut aus. werde es heute mal mit ein, zwei leuten testen und meld mich dann hier im laufe des tages nochmal! DANKE!
fidionael - Mo 19.06.06 12:05
Ich denke, dass ich nun die finale und stabile Fassung meiner Parsing-Unit (V1.5) veröffentlichen kann. Ich habe diese nun lang und ausgiebig getestet und keinen Fehler mehr gefunden.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244:
| unit Parsing;
interface
const MsgInternal = 'Es ist ein interner Fehler aufgetreten!';
type TUserList = record Count: Integer; User: Array of String; end;
TGroup = record Name: String; ID: Integer; Leader: String; end;
function GetGroupByName(filename: String; Group_Name: String) : TGroup; function GetGroupByID(filename: String; Group_ID: Integer) : TGroup; function GetGroupByLeader(filename: String; Group_Leader: String) : TGroup;
function GetUsers(filename: String; Group: TGroup) : TUserList; function SaveUsers(filename: String; Group: TGroup; UserList: TUserList) : Boolean;
function GetSpareUsers(filename: String; ignore: TUserList) : TUserList;
implementation
uses SysUtils, Dialogs;
function GetGroupByName(filename: String; Group_Name: String) : TGroup; var f: Textfile; buf: String; begin with Result do begin Name:=''; ID:=0; Leader:=''; end;
AssignFile(f,filename); Reset(f); try while not eoF(f) do begin ReadLn(f,buf); if (Pos(Group_Name,buf) = 1) and (buf[Pos(Group_Name,buf)+1]=':') then begin with Result do begin Name:=Group_Name; ID:=StrToInt(Copy(buf,Pos('::',buf)+2,3)); Delete(buf,1,Pos(IntToStr(ID),buf)+3); if Pos(',',buf) > 0 then Leader:=Copy(buf,1,Pos(',',buf)-1) else Leader:=Copy(buf,1,Length(buf)); end; Break; end; end; CloseFile(f); except MessageDlg(MsgInternal,mtError,[mbOK],0); end; end;
function GetGroupByID(filename: String; Group_ID: Integer) : TGroup; var f: Textfile; buf: String; begin with Result do begin Name:=''; ID:=0; Leader:=''; end;
AssignFile(f,filename); Reset(f); try while not eoF(f) do begin ReadLn(f,buf); if Pos(Format('%0.3d',[Group_ID]),buf) = 5 then begin with Result do begin Name:=Copy(buf,1,Pos('::',buf)-1); ID:=Group_ID; Delete(buf,1,Pos(IntToStr(ID),buf)+3); if Pos(',',buf) > 0 then Leader:=Copy(buf,1,Pos(',',buf)-1) else Leader:=Copy(buf,1,Length(buf)); end; Break; end; end; CloseFile(f); except MessageDlg(MsgInternal,mtError,[mbOK],0); end; end;
function GetGroupByLeader(filename: String; Group_Leader: String) : TGroup; var f: Textfile; buf: String; begin with Result do begin Name:=''; ID:=0; Leader:=''; end;
AssignFile(f,filename); Reset(f); try while not eoF(f) do begin ReadLn(f,buf); if Pos(Group_Leader,buf) = 9 then begin with Result do begin Name:=Copy(buf,1,Pos('::',buf)-1); ID:=StrToInt(Copy(buf,Pos('::',buf)+2,3)); Leader:=Group_Leader; end; Break; end; end; CloseFile(f); except MessageDlg(MsgInternal,mtError,[mbOK],0); end; end;
function GetUsers(filename: String; Group: TGroup) : TUserList; var f: Textfile; buf: String; begin with Result do begin Count:=0; SetLength(User,0); end;
AssignFile(f,filename); Reset(f); try while not eoF(f) do begin ReadLn(f,buf); if Pos(Group.Name,buf) = 1 then begin if Pos(',',buf) > 0 then Delete(buf,1,Pos(',',buf)) else Delete(buf,1,Length(buf)); while Length(buf) > 0 do begin if Pos(',',buf) <> 0 then begin with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=Copy(buf,1,Pos(',',buf)-1); end; Delete(buf,1,Pos(',',buf)); end else begin with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=buf; end; Delete(buf,1,Length(buf)); end; end; end; end; CloseFile(f); except MessageDlg(MsgInternal,mtError,[mbOK],0); end; end;
function SaveUsers(filename: String; Group: TGroup; UserList: TUserList) : Boolean; var f: Textfile; buf: Array of String; i: Integer; begin Result:=True; SetLength(buf,1);
AssignFile(f,filename); try Reset(f); while not eoF(f) do begin ReadLn(f,buf[High(buf)]); if Pos(Group.Name,buf[High(buf)]) = 1 then with Group do begin buf[High(buf)]:=Name+'::'+Format('%0.3d',[ID])+':'+Leader; if UserList.Count > 0 then buf[High(buf)]:=buf[High(buf)]+','; for i:=0 to (UserList.Count-1) do begin buf[High(buf)]:=buf[High(buf)]+UserList.User[i]; if i<(UserList.Count-1) then buf[High(buf)]:=buf[High(buf)]+','; end; end; SetLength(buf,High(buf)+2); end;
Rewrite(f); for i:=0 to High(buf) do WriteLn(f,buf[i]);
CloseFile(f); except Result := False; end; end;
function GetSpareUsers(filename: String; ignore: TUserList) : TUserList; var f: Textfile; buf: String; i: Integer; begin with Result do begin Count:=0; SetLength(User,Count); end;
AssignFile(f,filename); Reset(f); try while not eoF(f) do begin ReadLn(f,buf); i:=0; while (i<ignore.Count) and (buf<>ignore.User[i]) do inc(i); if i = ignore.Count then with Result do begin inc(Count); SetLength(User,Count); User[Count-1]:=buf; end; end; CloseFile(f); except MessageDlg(MsgInternal,mtError,[mbOK],0); end; end;
end. |
Im Gegensatz zur V1.4 kann diese übrigens nun auch damit umgehen, wenn in einer Zeile (außer dem Gruppenleiter) keine User angegeben sind. Ich denke, damit sollten all deine Probleme bezüglich Parsing in diesem Fall gelöst sein.
Noch viel Spaß beim Programmieren deines Tools!
Post Scriptum: Mein Testprojekt habe ich oben aktualisiert.
Edit: V1.6:
- Die Compileranweisungen
{$I-} und
{$I+} wurden mit
try except Blöcken ausgetauscht.
- Es wurde eine konstante Fehlermeldung hinzugefügt
- Die
function GetGroupByName gibt jetzt auch korrekte Werte zurück, wenn vor dem Auftreten des gesuchten Gruppennamens ein Gruppenname auftaucht, der den gesuchten beinhaltet (wenn z. B.
abc gesucht wird, vorher aber bereits
abcd auftaucht.
Edit: V1.6b:
- Die Erweiterung zu V1.6 zog einige Bugs bei der Gruppenerkennung mit sich, die nun behoben wurden.
del1312 - Di 20.06.06 08:24
supi mein problem ist gelöst, nochmal ein
riesen dankeschön an fidionael
fidionael - So 08.10.06 14:06
Tut mir Leid, dass ich so einen alten Thread nochmal aufmachen muss, aber da es sich hierbei um eine beträchtliche Änderung der Parsing-Unit handelt und das Projekt auch (entgegen dem letzten Posting) noch nicht abgeschlossen ist (Anfrage per PN), erscheint es mir als notwendig.
Version 2.0 (beta)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319:
| unit Parsing;
interface
type PString = ^TString; TString = record Content: String; Next: PString; end;
TGroup = class(TObject) private Name: String; ID: Integer; Leader: String;
Groupcount: Word; Groupusers: PString; Sparecount: Word; Spareusers: PString;
procedure GetGroupData(filename: String); procedure GetSpareData(filename: String); public constructor CreateByName(filename_accounts, filename_userlist: String; Group_Name: String); constructor CreateByID(filename_accounts, filename_userlist: String; Group_ID: Integer); constructor CreateByLeader(filename_accounts, filename_userlist: String; Group_Leader: String);
procedure UpdateFile(filename: String);
function GetGroupUser(index: Integer) : String; function GetSpareUser(index: Integer) : String; property Group_User_Count: Word read Groupcount; property Spare_User_Count: Word read Sparecount; end;
const MsgInternal = 'Es ist ein interner Fehler aufgetreten.';
implementation
uses SysUtils, Dialogs;
constructor TGroup.CreateByName(filename_accounts, filename_userlist: String; Group_Name: String); var f: Textfile; buf: String; begin Name := Group_Name; ID := 0; Leader := '';
AssignFile(f,filename_accounts); try Reset(f); while not EoF(f) do begin Readln(f,buf); if (Pos(Group_Name,buf) = 1) and (buf[Pos(Group_Name,buf)+1]=':') then begin Name:=Group_Name; ID:=StrToInt(Copy(buf,Pos('::',buf)+2,3)); Delete(buf,1,Pos(IntToStr(ID),buf)+3); if Pos(',',buf) > 0 then Leader:=Copy(buf,1,Pos(',',buf)-1) else Leader:=Copy(buf,1,Length(buf)); end; Break; end;
CloseFile(f); except MessageDlg(MsgInternal,mtError,[mbOK],0); end;
GetGroupData(filename_accounts); GetSpareData(filename_userlist); end;
constructor TGroup.CreateByID(filename_accounts, filename_userlist: String; Group_ID: Integer); var f: Textfile; buf: String; begin Name := '';; ID := Group_ID; Leader := '';
AssignFile(f,filename_accounts); try Reset(f); while not EoF(f) do begin Readln(f,buf); if Pos(Format('%0.3d',[Group_ID]),buf) = Pos('::',buf)+2 then begin Name:=Copy(buf,1,Pos('::',buf)-1); ID:=Group_ID; Delete(buf,1,Pos(IntToStr(ID),buf)+3); if Pos(',',buf) > 0 then Leader:=Copy(buf,1,Pos(',',buf)-1) else Leader:=Copy(buf,1,Length(buf)); end; Break; end; CloseFile(f); except MessageDlg(MsgInternal,mtError,[mbOK],0); end;
GetGroupData(filename_accounts); GetSpareData(filename_userlist); end;
constructor TGroup.CreateByLeader(filename_accounts, filename_userlist: String; Group_Leader: String); var f: Textfile; buf: String; begin Name := '';; ID := 0; Leader := Group_Leader;
AssignFile(f,filename_accounts); try Reset(f); while not EoF(f) do begin Readln(f,buf); if Pos(Group_Leader,buf) = Pos('::',buf)+6 then begin Name:=Copy(buf,1,Pos('::',buf)-1); ID:=StrToInt(Copy(buf,Pos('::',buf)+2,3)); Leader:=Group_Leader; Break; end; end; CloseFile(f); except MessageDlg(MsgInternal,mtError,[mbOK],0); end;
GetGroupData(filename_accounts); GetSpareData(filename_userlist); end;
procedure TGroup.GetGroupData(filename: String); var f: Textfile; buf: String; temp,current: PString; begin Groupcount := 0; Groupusers := nil;
AssignFile(f,filename); try Reset(f); while not EoF(f) do begin Readln(f,buf); if Pos(Name,buf) = 1 then begin if Pos(',',buf) > 0 then Delete(buf,1,Pos(',',buf)) else Delete(buf,1,Length(buf)); while Length(buf) > 0 do begin temp := New(PString); if Pos(',',buf) > 0 then temp^.Content := Copy(buf,1,Pos(',',buf)-1) else temp^.Content := buf; temp^.Next := nil; current := Groupusers; while current^.Next <> nil do current := current^.Next; current.Next := temp; inc(Groupcount); end; end; end; CloseFile(f); except MessageDlg(MsgInternal,mtError,[mbOK],0); end; end;
procedure TGroup.GetSpareData(filename: String); var f: Textfile; buf: String; i: Integer; temp, current: PString; begin Sparecount := 0; Spareusers := nil;
AssignFile(f,filename); try Reset(f); while not EoF(f) do begin Readln(f,buf); i := 0; current := Groupusers; while (current^.Next <> nil) and (current^.Next^.Content <> buf) do begin current := current^.Next; inc(i); end; if i = Groupcount then begin temp := New(PString); temp^.Content := buf; temp^.Next := nil; current := Spareusers; while current^.Next <> nil do current := current^.Next; current^.Next := temp; inc(Sparecount); end; end; CloseFile(f); except MessageDlg(MsgInternal,mtError,[mbOK],0); end; end;
procedure TGroup.UpdateFile(filename: String); var f: Textfile; buf: String; first,current,current2,temp: PString; i: Integer; begin first := nil;
AssignFile(f,filename); try Reset(f); while not EoF(f) do begin Readln(f,buf); temp := New(PString); temp^.Content := buf; temp^.Next := nil; current := first; while current^.Next <> nil do current := current^.Next; current^.Next := temp; end; CloseFile(f);
Rewrite(f); current := first; while current^.Next <> nil do begin current := current^.Next; if Pos(Name,current^.Content) = 1 then begin buf := Format('%s::%0.3d:%s',[Name,ID,Leader]); if Groupcount > 0 then begin current2 := Groupusers; for i := 1 to Groupcount do begin current2 := current2^.Next; buf := buf + ',' + current2^.Content; end; end; Writeln(f,buf); end else Writeln(f,current^.Content); end; except MessageDlg(MsgInternal,mtError,[mbOK],0); end; end;
function TGroup.GetGroupUser(index: Integer) : String; var i: Integer; current: PString; begin Result := '';
current := Groupusers; if index <= Groupcount then begin for i := 1 to index do current := current^.Next; Result := current^.Content; end; end;
function TGroup.GetSpareUser(index: Integer) : String; var i: Integer; current: PString; begin Result := '';
current := Spareusers; if index <= Sparecount then begin for i := 1 to index do current := current^.Next; Result := current^.Content; end; end;
end. |
Neuerungen:
- Eine Eingliederung in die Klasse
TGroup, welche sich schon seit mehreren Versionen anbot, jedoch nicht durchgeführt wurde, da sich das Projekt vermeintlich am Ende befand und dies eine größere Umstellung bedeuten würde, hat nun endlich statt gefunden.
- Im Zuge der Umstellung auf OOP (
objektorientierte Programmierung) wurden einige Methoden aus der alten Unit völlig überflüssig, es wurden alle überarbeitet. Eine Kurzerklärung befindet sich im Kommentar der Unit, eine ausführliche Dokumentation wird hier noch folgen.
Zu beachten ist, dass es sich um eine beta-Version handelt, welche vermutlich noch voller Fehler steckt. Sobald diese getestet ist und auch die Dokumentation mit Anwendungsbeispielen fertiggestellt ist, werde ich die Version dann offiziell freigeben.
Mfg.
del1312 - Mo 09.10.06 07:04
hallo fidionael,
ich danke dir für deine schnelle hilfe, werd es gleich mal ausprobieren :o)
fidionael - Di 20.03.07 17:57
Nach langer, langer Zeit habe ich meine Beta-Version nun doch nochmal überarbeitet und endlich, nachdem ich sie auch in Delphi testen konnte, soweit ich das bisher sehen konnte, fehlerfrei.
Ich hänge an diesen Post auch mal mein Testprogramm an. Mögliche Logins sind als Gruppenname z. B. aa, oder ab. Ansonsten einfach in die entsprechende Datei gucken.
Nun erstmal der Quelltext; kommentiert ist er bereits, aber eine ausführliche Dokumentation wird folgen.
Version 2.2
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455: 456: 457: 458: 459: 460: 461: 462: 463: 464: 465: 466: 467: 468: 469: 470: 471: 472: 473: 474: 475: 476: 477: 478:
| unit Parsing;
interface
type TListNode = class(TObject) private fvalue: String; public next: TListNode; constructor Create(val: String); property Value: String read fvalue; end;
TStringList = class(TObject) private dummy, current: TListNode; fcount: Word; public constructor Create; procedure Reset; procedure Advance; function EndPos : Boolean; procedure Add(val: String); procedure Delete; function Get : String; destructor Free; property Count: Word read fcount; end;
TUserList = class(TStringList) public procedure Delete(val: String); function Exists(val: String) : Boolean; end;
TGroup = class(TObject) protected procedure Init(filename_groups: String); procedure CreateLists(filename_users: String); function GetUserCount : Word; function GetSpareUserCount : Word; private fname, fleader: String; fid: Integer; fuser, fspare: TUserList;
ffilegroups: String; ferror : Boolean; public constructor CreateByName(filename_groups,filename_users: String; group_name: String); constructor CreateByLeader(filename_groups,filename_users: String; group_leader: String); constructor CreateByID(filename_groups,filename_users: String; group_id: Integer);
function AddUser(val: String) : Boolean; function DelUser(val: String) : Boolean; function GetUser(index: Word) : String; function GetSpareUser(index: Word) : String; procedure Save; destructor Free; property User_Count: Word read getUserCount; property SpareUser_Count: Word read getSpareUserCount; property ErrorFlag: Boolean read ferror;
property Name: String read fname; property Leader: String read fleader; property ID: Integer read fid; end;
implementation
uses SysUtils;
constructor TListNode.Create(val: String); begin fvalue := val; next := nil; end;
constructor TStringList.Create; begin dummy := TListNode.Create(''); current := dummy; fcount := 0; end;
procedure TStringList.Delete; var temp: TListNode; begin if not self.EndPos then begin temp := current.next; current.next := current.next.next; temp.Free; dec(fcount); end; end;
procedure TStringList.Reset; begin current := dummy; end;
procedure TStringList.Advance; begin if not self.EndPos then current := current.next; end;
function TStringList.EndPos : Boolean; begin Result := (current.next = nil); end;
procedure TStringList.Add(val: String); var temp: TListNode; begin temp := TListNode.Create(val); temp.next := current.next; current.next := temp; current := temp; inc(fcount); end;
function TStringList.Get : String; begin if not self.EndPos then Result := current.next.Value else Result := ''; end;
destructor TStringList.Free; begin self.Reset; Repeat self.Delete; Until self.EndPos; end;
procedure TUserList.Delete(val: String); var temp: TListNode; begin temp := current; self.Reset; while (not self.EndPos) and (self.Get <> val) do self.Advance; inherited Delete; current := temp; end;
function TUserList.Exists(val: String) : Boolean; var temp: TListNode; begin Result := False; temp := current; self.Reset; Repeat if self.Get = val then begin Result := True; break; end; Advance; Until self.EndPos; current := temp; end;
constructor TGroup.CreateByName(filename_groups,filename_users: String; group_name: String); var f: Textfile; buf: String; begin fname := group_name; fleader := ''; fid := 0; self.Init(filename_groups); AssignFile(f,filename_groups); Reset(f); try while not eof(f) do begin Readln(f,buf); if (Pos(group_name,buf) = 1) and (buf[Pos(group_name,buf) + Length(group_name)]=':') then begin fid := StrToInt(Copy(buf,Pos('::',buf)+2,3)); Delete(buf,1,Pos(IntToStr(fid),buf)+1); if Pos(',',buf) > 0 then fleader := Copy(buf,1,Pos(',',buf)-1) else fleader := Copy(buf,1,Length(buf)); break; end; end; CloseFile(f); except ferror := True; Exit; end; if (fid = 0) or (fleader = '') then begin ferror := true; Exit; end; self.CreateLists(filename_users); end;
constructor TGroup.CreateByLeader(filename_groups,filename_users: String; group_leader: String); var f: Textfile; buf: String; begin fname := ''; fleader := group_leader; fid := 0; self.Init(filename_groups); AssignFile(f,filename_groups); Reset(f); try while not eof(f) do begin Readln(f,buf); if Pos(group_leader,buf) = 9 then begin fname := Copy(buf,1,Pos('::',buf)-1); fid := StrToInt(Copy(buf,Pos('::',buf)+2,3)); break; end; end; CloseFile(f); except ferror := True; Exit; end; if (fname = '') or (fid = 0) then begin ferror := True; Exit; end; self.CreateLists(filename_users); end;
constructor TGroup.CreateByID(filename_groups,filename_users: String; group_id: Integer); var f: Textfile; buf: String; begin fname := ''; fleader := ''; fid := group_id; self.Init(filename_groups); AssignFile(f,filename_groups); Reset(f); try while not eof(f) do begin Readln(f,buf); if Pos(Format('%0.3d',[group_id]),buf) = 5 then begin fname := Copy(buf,1,Pos('::',buf)-1); Delete(buf,1,Pos(IntToStr(group_id),buf)+1); if Pos(',',buf) > 0 then fleader := Copy(buf,1,Pos(',',buf)-1) else fleader := Copy(buf,1,Length(buf)); break; end; end; CloseFile(f); except ferror := True; Exit; end; if (fname = '') or (fleader = '') then begin ferror := True; Exit; end; self.CreateLists(filename_users); end;
procedure TGroup.Init(filename_groups: String); begin fuser := TUserList.Create; fspare := TUserList.Create;
ffilegroups := filename_groups;
ferror := False; end;
procedure TGroup.CreateLists(filename_users: String); var f: Textfile; buf: String; begin AssignFile(f,ffilegroups); Reset(f); try while not eof(f) do begin Readln(f,buf); if Pos(fname,buf) = 1 then begin if Pos(',',buf) > 0 then Delete(buf,1,Pos(',',buf)) else Delete(buf,1,Length(buf)); while Length(buf) > 0 do begin if Pos(',',buf) > 0 then begin fuser.Add(Copy(buf,1,Pos(',',buf)-1)); Delete(buf,1,Pos(',',buf)); end else begin fuser.Add(buf); Delete(buf,1,Length(buf)); end; end; end; end; CloseFile(f); except ferror := True; Exit; end; AssignFile(f,filename_users); Reset(f); try while not eof(f) do begin Readln(f,buf); if (not fuser.Exists(buf)) and (buf <> fleader) then fspare.Add(buf); end; CloseFile(f); except ferror := True; Exit; end; end;
function TGroup.GetUserCount : Word; begin Result := fuser.Count; end;
function TGroup.GetSpareUserCount : Word; begin Result := fspare.Count; end;
function TGroup.AddUser(val: String) : Boolean; begin if fspare.Exists(val) then begin fspare.Delete(val); fuser.Add(val); Result := True; end else Result := False; end;
function TGroup.DelUser(val: String) : Boolean; begin if fuser.Exists(val) then begin fuser.Delete(val); fspare.Add(val); Result := True; end else Result := False; end;
function TGroup.GetUser(index: Word) : String; var i: Integer; begin fuser.Reset; for i := 1 to index do fuser.Advance; Result := fuser.Get; end;
function TGroup.GetSpareUser(index: Word) : String; var i: Integer; begin fspare.Reset; for i := 1 to index do fspare.Advance; Result := fspare.Get; end;
procedure TGroup.Save; var f: Textfile; buf: String; list: TStringList; begin list := TStringList.Create; AssignFile(f,ffilegroups); try Reset(f); while not eof(f) do begin Readln(f,buf); if (Pos(fname,buf) = 1) and (buf[Pos(fname,buf)+Length(fname)] = ':') then begin buf := fname+'::'+Format('%0.3d',[fid])+':'+fleader; fuser.Reset; while not fuser.EndPos do begin buf := buf+','+fuser.Get; fuser.Advance; end; end; list.Add(buf); end; Rewrite(f); list.Reset; while not list.EndPos do begin Writeln(f,list.Get); list.Advance; end; CloseFile(f); list.Free; except ferror := True; Exit; end; end;
destructor TGroup.Free; begin fuser.Free; fspare.Free; end;
end. |
Ich hoffe, es ist noch hilfreich.
Update zu Version 2.1: Bug (Groupname "ab" - "ablage") fixed.
Update zu Version 2.2: Bug in TGroup.Save fixed. Aufsplittung TUserList in TStringList und TUserList(derived). TGroup.Save wurde durch die Verwendung verketteter Listen anstatt dyn. Arrays effizienter gemacht (sowohl Geschwindigkeit als auch RAM-Nutzung).
del1312 - Di 20.03.07 21:23
ja auf jedenfall ist das noch aktuelle, ich danke dir :o)
del1312 - Mi 21.03.07 14:14
hab da leider doch noch nen bug gefunden. versuch mal mit der grupppendatei die im anhang hab und log dich mal als "ab" ein. da siehste dann ein paar user. jetzt logst du dich wieder aus und gleich mal wieder als "ab" ein und schwupps sind es plötzlich mehr geworden. ursache: in der gruppendatei gibt es eine gruppe die auch mit "ab" anfängt "ablage" und da liest er auch alles raus und kopiert das in die gruppe "ab" im prinzip muss vorher die abfrage so sein: wenn "ab:" dann führe aus sonst lass es einfach stehen. also die gruppen sind immer zweistellig von daher muß ein : hinterher kommen, wenn du die abfrage so ändern könntest das er noch da nachschaut sollte es keine verwechselungen mehr geben und klappen :o)
fidionael - Mi 21.03.07 19:18
Hallo,
das Problem lag gar nicht im Auslesen des Gruppennamens, sondern im Schreiben der Datei beim Ausloggen :-) Weil wir das Problem ja schonmal thematisiert hatten, hatte ich es auch in der Auslese-Methode durchaus berücksichtigt. Nur habe ich leider vergessen, auch beim Schreiben der Datei hierauf zu achten :-)
Falls es dich interessiert, fügte er tatsächlich gar keine neuen Nutzer hinzu, sondern machte nur aus "ablage" eine zweite, identische Gruppe "ab" wodurch sich dann die Anzahl Nutzer verdoppelt hat - was man endlos weiterspielen konnte.
Das Problem ist jedenfalls nun behoben, der neue Quelltext ist in meinem letzten Posting zu finden. Ich habe jedoch die Parsing-Unit im Demo-Projekt nicht verändert - das musst du selbst tun.
Falls sonst noch Probleme auftreten, melde dich bitte wieder.
del1312 - Mi 21.03.07 19:33
alles klar ich danke dir, bau mir das gleich mal so um wie ich es brauche. danke nochmal!
fidionael - Mi 21.03.07 22:55
Hallo, ich muss nochmal stören. Ich hab noch einen Fehler in meinem Quelltext (TGroup.Save) gefunden :oops: Dieser ist jedenfalls jetzt behoben und, da ich schonmal dabei war, habe ich die TUserList in TStringList und TUserList aufgeteilt um die dynamischen Arrays aus der Save-Prozedur rausschmeißen zu können. Nun ist diese viel effizienter. Der Vollständigkeit halber sollte man vielleicht noch erwähnen, dass ich auch die Listenfunktion des Einfügens verändert habe, nun ist die Liste (aus logischen Gründen) in der Reihenfolge angeordnet, in dem die einzelnen Elemente eingefügt wurden.
Der neue Quelltext ist wieder oben. Ich habe, da ja nun schon einige Änderungen vorgenommen wurden, auch das Projekt im Anhang aktualisiert. Tut mir Leid wegen der Umstände.
del1312 - Mi 21.03.07 23:19
hey kein prob, musst dich dafür doch nicht entschuldigen, find das super das du es noch verbesserst :o) bin grad dabei mir das tool so zu schreiben wie ich es brauch. mach jetzt erstmal weiter und schau mir dann morgen mal die änderungen an. das ist schon ganz schön unübersichtlich für mich geworden, muss das erstmal alles auseinanderpflücken und schauen wie das überhaupt alles so funzt :o)
del1312 - Do 22.03.07 12:55
hab jetzt aber nen prob mit der gruppen.txt. du hast das ja jetzt so gebaut, das die gruppen folgendermaßen aufgebaut sind:
aa::001: ....
ab::002: ....
die die stelle wo die zahlen 001 und 002 stehen, sind aber nicht in der reihenfolge sonder haben
zahlen quer durchs gemüsebeet. dadurch schreibt er jetzt ne fehler in die gruppen.txt.
so wie du das im download hast funktionier es aber sobald du mal ne zeile reinschreibst:
ac::765: ....
ad::876: ....
und im programm dann diesen gruppen mal user zu schreibst dann stehen da plötzlich falsche zeichen in der zeile wie z.b
ad::876:5: ....
kannst du mir das bitte nochmal ändern?
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!