Autor Beitrag
del1312
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 190



BeitragVerfasst: Fr 16.06.06 14:35 
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.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: 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: dsdt.info/tutorials/ini/

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
del1312 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 190



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 232

Win XP SP2, Ubuntu 6.06
Delphi 7 PE, Delphi 3 Prof
BeitragVerfasst: 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):

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:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 190



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 190



BeitragVerfasst: 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)
Einloggen, um Attachments anzusehen!
fidionael
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 232

Win XP SP2, Ubuntu 6.06
Delphi 7 PE, Delphi 3 Prof
BeitragVerfasst: 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:
ausblenden 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-1downto 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-1downto 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 190



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 232

Win XP SP2, Ubuntu 6.06
Delphi 7 PE, Delphi 3 Prof
BeitragVerfasst: Sa 17.06.06 15:38 
user profile iconecspooky 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:
ausblenden volle Höhe 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:
///////////////////////////////////////////////////////////////////////////
// Parsing Unit by Nikolas Jansen                                        //
//                                                                       //
// Der Funktion Parse wird ein Datei-Name und die ID des Gruppenleiters  //
// übergeben. Zurückgegeben wird dann die Anzahl von Usern in der Gruppe //
// des Leiters und die entsprechenden Usernamen.                         //
///////////////////////////////////////////////////////////////////////////
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
  // Initialisierung des Rückgabewertes
  with Result do begin
    Count:=0;
    SetLength(User,Count);
  end;

  // Öffnen der Datei
  AssignFile(f,filename);
  {$I-} Reset(f); {$I+}
  if ioResult = 0 then
    // Auslesen der Datei bis zur letzten Zeile
    while not eoF(f) do begin
      ReadLn(f,line);

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

        // Da das Ergebnis bereits gefunden wurde, brauchen wir die Datei
        // nicht mehr bis zum Ende auslesen und können die entsprechende
        // Schleife nun unterbrechen.
        Break;
      end;
    end;

  // Schließen der Datei
  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:
ausblenden 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-1do
    Listbox1.Items.Add(leader.User[i]);
end;
del1312 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 190



BeitragVerfasst: 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!!!!!!
Einloggen, um Attachments anzusehen!
fidionael
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 232

Win XP SP2, Ubuntu 6.06
Delphi 7 PE, Delphi 3 Prof
BeitragVerfasst: 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:
ausblenden volle Höhe 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:
///////////////////////////////////////////////////////////////////////////
// Parsing Unit by Nikolas Jansen                                        //
//                                                                       //
// Der Funktion Parse wird ein Datei-Name und die ID des Gruppenleiters  //
// übergeben. Zurückgegeben wird dann die Anzahl von Usern in der Gruppe //
// des Leiters und die entsprechenden Usernamen.                         //
///////////////////////////////////////////////////////////////////////////
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
  // Initialisierung des Rückgabewertes
  with Result do begin
    Count:=0;
    SetLength(User,Count);
  end;

  // Öffnen der Datei
  AssignFile(f,filename);
  {$I-} Reset(f); {$I+}
  if ioResult = 0 then
    // Auslesen der Datei bis zur letzten Zeile
    while not eoF(f) do begin
      ReadLn(f,line);

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

        // Da das Ergebnis bereits gefunden wurde, brauchen wir die Datei
        // nicht mehr bis zum Ende auslesen und können die entsprechende
        // Schleife nun unterbrechen.
        Break;
      end;
    end;

  // Schließen der Datei
  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:
ausblenden volle Höhe 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:
///////////////////////////////////////////////////////////////////////////
// Parsing Unit by Nikolas Jansen                                        //
//                                                                       //
// Der Funktion Parse wird ein Datei-Name und die ID des Gruppenleiters  //
// übergeben. Zurückgegeben wird dann die Anzahl von Usern in der Gruppe //
// des Leiters und die entsprechenden Usernamen.                         //
///////////////////////////////////////////////////////////////////////////
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
  // Initialisierung des Rückgabewertes
  with Result do begin
    Count:=0;
    SetLength(User,Count);
  end;

  // Öffnen der Datei
  AssignFile(f,filename);
  {$I-} Reset(f); {$I+}
  if ioResult = 0 then
    // Auslesen der Datei bis zur letzten Zeile
    while not eoF(f) do begin
      ReadLn(f,line);

      // 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)+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;

        // Da das Ergebnis bereits gefunden wurde, brauchen wir die Datei
        // nicht mehr bis zum Ende auslesen und können die entsprechende
        // Schleife nun unterbrechen.
        Break;
      end;
    end;

  // Schließen der Datei
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 232

Win XP SP2, Ubuntu 6.06
Delphi 7 PE, Delphi 3 Prof
BeitragVerfasst: 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:

ausblenden volle Höhe 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:
////////////////////////////////////////////////////////////////////////////////
// Parsing Unit by Nikolas Jansen (18. 06. 2006)
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
  // Initialisierung des Rückgabewertes
  with Result do begin
    Count:=0;
    SetLength(User,Count);
  end;

  // Öffnen der Datei
  AssignFile(f,filename);
  {$I-} Reset(f); {$I+}
  if ioResult = 0 then
    // Auslesen der Datei bis zur letzten Zeile
    while not eoF(f) do begin
      ReadLn(f,line);

      // 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)+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;

        // Da das Ergebnis bereits gefunden wurde, brauchen wir die Datei
        // nicht mehr bis zum Ende auslesen und können die entsprechende
        // Schleife nun unterbrechen.
        Break;
      end;
    end;

  // Schließen der Datei
  CloseFile(f);
end;

function Parse(filename: String; Ignore: TParseResult) : TParseResult; overload;
var f: Textfile;
    line: String;
    i: Integer;
begin
  // Initialisierung des Rückgabewertes
  with Result do begin
    Count:=0;
    SetLength(User,Count);
  end;

  // Öffnen der User-Datei
  AssignFile(f,filename);
  {$I-} Reset(f); {$I+}
  if ioResult = 0 then
    // Auslesen der Datei bis zur letzten Zeile
    while not eoF(f) do begin
      ReadLn(f,line);

      // Wenn der User in der entsprechenden Zeile der Datei nicht in der
      // Liste der ignorierten User steht, wird dieser in die Liste der
      // User aufgenommen.
      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;

    // Schließen der Datei
    CloseFile(f);
end;

end.


In deiner ButtonClick-Prozedur sieht das dann so aus:
ausblenden 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-1do
    Listbox1.Items.Add(leader.User[i]);
  for i:=0 to (spare_users.Count-1do
    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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 232

Win XP SP2, Ubuntu 6.06
Delphi 7 PE, Delphi 3 Prof
BeitragVerfasst: 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:

ausblenden volle Höhe 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:
////////////////////////////////////////////////////////////////////////////////
// Parsing Unit by Nikolas Jansen (18. 06. 2006)
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
  // Initialisierung des Rückgabewertes
  with Result do begin
    Count:=0;
    SetLength(User,Count);
  end;

  // Öffnen der Datei
  AssignFile(f,filename);
  {$I-} Reset(f); {$I+}
  if ioResult = 0 then
    // Auslesen der Datei bis zur letzten Zeile
    while not eoF(f) do begin
      ReadLn(f,line);

      // 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)+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;

        // Da das Ergebnis bereits gefunden wurde, brauchen wir die Datei
        // nicht mehr bis zum Ende auslesen und können die entsprechende
        // Schleife nun unterbrechen.
        Break;
      end;
    end;

  // Schließen der Datei
  CloseFile(f);
end;

function Parse(filename: String; ignore: TParseResult) : TParseResult; overload;
var f: Textfile;
    line: String;
    i: Integer;
begin
  // Initialisierung des Rückgabewertes
  with Result do begin
    Count:=0;
    SetLength(User,Count);
  end;

  // Öffnen der User-Datei
  AssignFile(f,filename);
  {$I-} Reset(f); {$I+}
  if ioResult = 0 then
    // Auslesen der Datei bis zur letzten Zeile
    while not eoF(f) do begin
      ReadLn(f,line);

      // Wenn der User in der entsprechenden Zeile der Datei nicht in der
      // Liste der ignorierten User steht, wird dieser in die Liste der
      // User aufgenommen.
      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;

    // Schließen der Datei
    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
  // Initialisierung des Rückgabewertes
  Result:=True;

  // Öffnen der Datei
  AssignFile(f,filename);
  {$I-} Reset(f); {$I+}
  if ioResult <> 0 then Result:=False
  else begin
    // Auslesen der Datei bis zur letzten Zeile. Alle Zeilen, außer der
    // modifizierten werden einfach kopiert.
    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-1do begin
          line:=line+userlist.User[i];
          if i<(userlist.Count-1then
            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
      // Überschreiben der Datei
      for i:=0 to High(buf) do
        WriteLn(f,buf[i]);
  end;

  // Schließen der Datei
  CloseFile(f);
end;

end.


In deiner Unit1 benutzt du die neue Funktion dann folgendermaßen (Button2 ist bei mir der Speicher-Button):
ausblenden 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-1do 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 190



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 190



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 232

Win XP SP2, Ubuntu 6.06
Delphi 7 PE, Delphi 3 Prof
BeitragVerfasst: 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:

user profile iconecspooky 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 190



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 190



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 232

Win XP SP2, Ubuntu 6.06
Delphi 7 PE, Delphi 3 Prof
BeitragVerfasst: 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:
user profile iconecspooky 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 190



BeitragVerfasst: 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
Einloggen, um Attachments anzusehen!