Autor Beitrag
PSLenny
Hält's aus hier
Beiträge: 13

Windows 7
Delphi 7
BeitragVerfasst: Mi 30.06.10 14:45 
Hallo liebe Community.

Ich wollte mir ein kleines Programm schreiben, dass mir meine Titel in der Musiksammlung 'schön benennt'.
Allerdings beendet sich das Programm, sobald ich die Größe der, vom Auslesen des Ordners erhaltene TStringList herausfinden möchte. Dies tue ich mittels TStringsVariable.Count.

Wie gesagt, weder der Delphi Debugger sagt etwas, noch erscheint eine Fehlermeldung. Ich würde mich freuen wenn mir jemand helfen könnte!

Hier mein Code:

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:
program Id3Changer;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes, FileCtrl, System, Dialogs;

type
  ID3Struct = record
    Signature: array[0..2of Char; { Should be: "TAG" }
    Title,
    Artist,
    Album: array[0..29of Char;
    Year: array[0..3of Char;
    Comment: array[0..29of Char;
    Genre: Byte;
  end;
  
const
 ID3Genre: array[0..125of string = (
    'Blues''Classic Rock''Country''Dance''Disco''Funk''Grunge',
    'Hip-Hop''Jazz''Metal''New Age''Oldies''Other''Pop''R&B',
    'Rap''Reggae''Rock''Techno''Industrial''Alternative''Ska',
    'Death Metal''Pranks''Soundtrack''Euro-Techno''Ambient',
    'Trip-Hop''Vocal''Jazz+Funk''Fusion''Trance''Classical',
    'Instrumental''Acid''House''Game''Sound Clip''Gospel',
    'Noise''AlternRock''Bass''Soul''Punk''Space''Meditative',
    'Instrumental Pop''Instrumental Rock''Ethnic''Gothic',
    'Darkwave''Techno-Industrial''Electronic''Pop-Folk',
    'Eurodance''Dream''Southern Rock''Comedy''Cult''Gangsta',
    'Top 40''Christian Rap''Pop/Funk''Jungle''Native American',
    'Cabaret''New Wave''Psychadelic''Rave''Showtunes''Trailer',
    'Lo-Fi''Tribal''Acid Punk''Acid Jazz''Polka''Retro',
    'Musical''Rock & Roll''Hard Rock''Folk''Folk-Rock',
    'National Folk''Swing''Fast Fusion''Bebob''Latin''Revival',
    'Celtic''Bluegrass''Avantgarde''Gothic Rock''Progressive Rock',
    'Psychedelic Rock''Symphonic Rock''Slow Rock''Big Band',
    'Chorus''Easy Listening''Acoustic''Humour''Speech''Chanson',
    'Opera''Chamber Music''Sonata''Symphony''Booty Bass''Primus',
    'Porn Groove''Satire''Slow Jam''Club''Tango''Samba',
    'Folklore''Ballad''Power Ballad''Rhythmic Soul''Freestyle',
    'Duet''Punk Rock''Drum Solo''Acapella''Euro-House''Dance Hall'
  );
{
function ReadID3Tag(sFileName:String):ID3Struct;
procedure WriteID3Tag(NewTag: ID3Struct; sFileName: string);
}

procedure ListFileDir(Path: string; FileList: TStrings);
var
  SR: TSearchRec;
begin
  if FindFirst(Path + '*.mp3', faAnyFile, SR) = 0 then
  begin
    repeat
      if (SR.Attr <> faDirectory) then
      begin
        FileList.Add(SR.Name);
      end;
    until FindNext(SR) <> 0;
    FindClose(SR);
  end;
end;


function ReadID3Tag(sFileName:String):ID3Struct;
var
fMP3: file of Byte;
Tag: ID3Struct;
begin
try
AssignFile(fMP3, sFileName);
Reset(fMP3);
try
Seek(fMP3, FileSize(fMP3) - 128);
BlockRead(fMP3, Tag, SizeOf(Tag))
finally

end;

finally
CloseFile(fMP3)
end;

if tag.Signature<>'TAG' then
begin

result:=tag;
end
else
begin

end;
result:=tag;
end;


function StringProper (const sIn : string) : string;
  var
    i : integer;
  begin
    Result:=LowerCase(sIn);
    if Result='' then exit;

    Result[1]:= UpCase(Result[1]);
    for i:= 2 to length(Result) do begin
      if Result[i - 1] = ' ' then begin
      Result[i]:= Upcase(Result[i]);
    end;
  end;
end;

var
  sDir: String;
  fList: TStrings;
  i: integer;
  aSize: integer;
  curTag: ID3Struct;
  newTitle: String;

begin
  if SelectDirectory('Please Select''C:\', sDir) then
  begin
    ListFileDir(sDir, fList);
    for i := 0 to fList.Count do
    begin
    ShowMessage('abc');
      curTag := ReadID3Tag(fList[i]);
      showMessage('a');
      if (curTag.Artist <> ''and (curTag.Title <> ''then
      begin
        newTitle := curTag.Artist + ' - ' + curTag.Title;
        newTitle := Trim(newTitle);
        newTitle := StringReplace(newTitle, '"''', [rfReplaceAll]);
        newTitle := StringProper(newTitle);
        WriteLn(newTitle);
      end;
    end;
  end;
end.


Vielen Dank im Voraus, ich bin für jede Hilfe Dankbar,

Lenny
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Mi 30.06.10 14:53 
Du hast zwar
ausblenden Delphi-Quelltext
1:
2:
3:
var
  sDir: String;
  fList: TStrings;

deklariert, es fehlt aber
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
fList:= TStrings.Create;
try
..
..
finally
fList.Free;
end;

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt
PSLenny Threadstarter
Hält's aus hier
Beiträge: 13

Windows 7
Delphi 7
BeitragVerfasst: Mi 30.06.10 15:05 
Hallo bummi und vielen Dank!

Das hat mir erstmal viel geholfen. Arbeite noch nicht so lang mit Delphi, deswegen sind mir solche Feinheiten noch nicht bekannt! ;)

Ich habe das so geändert:
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:
program Id3Changer;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes, FileCtrl, System, Dialogs;

type
  ID3Struct = record
    Signature: array[0..2of Char; { Should be: "TAG" }
    Title,
    Artist,
    Album: array[0..29of Char;
    Year: array[0..3of Char;
    Comment: array[0..29of Char;
    Genre: Byte;
  end;
  
const
 ID3Genre: array[0..125of string = (
    'Blues''Classic Rock''Country''Dance''Disco''Funk''Grunge',
    'Hip-Hop''Jazz''Metal''New Age''Oldies''Other''Pop''R&B',
    'Rap''Reggae''Rock''Techno''Industrial''Alternative''Ska',
    'Death Metal''Pranks''Soundtrack''Euro-Techno''Ambient',
    'Trip-Hop''Vocal''Jazz+Funk''Fusion''Trance''Classical',
    'Instrumental''Acid''House''Game''Sound Clip''Gospel',
    'Noise''AlternRock''Bass''Soul''Punk''Space''Meditative',
    'Instrumental Pop''Instrumental Rock''Ethnic''Gothic',
    'Darkwave''Techno-Industrial''Electronic''Pop-Folk',
    'Eurodance''Dream''Southern Rock''Comedy''Cult''Gangsta',
    'Top 40''Christian Rap''Pop/Funk''Jungle''Native American',
    'Cabaret''New Wave''Psychadelic''Rave''Showtunes''Trailer',
    'Lo-Fi''Tribal''Acid Punk''Acid Jazz''Polka''Retro',
    'Musical''Rock & Roll''Hard Rock''Folk''Folk-Rock',
    'National Folk''Swing''Fast Fusion''Bebob''Latin''Revival',
    'Celtic''Bluegrass''Avantgarde''Gothic Rock''Progressive Rock',
    'Psychedelic Rock''Symphonic Rock''Slow Rock''Big Band',
    'Chorus''Easy Listening''Acoustic''Humour''Speech''Chanson',
    'Opera''Chamber Music''Sonata''Symphony''Booty Bass''Primus',
    'Porn Groove''Satire''Slow Jam''Club''Tango''Samba',
    'Folklore''Ballad''Power Ballad''Rhythmic Soul''Freestyle',
    'Duet''Punk Rock''Drum Solo''Acapella''Euro-House''Dance Hall'
  );
{
function ReadID3Tag(sFileName:String):ID3Struct;
procedure WriteID3Tag(NewTag: ID3Struct; sFileName: string);
}

procedure ListFileDir(Path: string; FileList: TStrings);
var
  SR: TSearchRec;
begin
  if FindFirst(Path + '*.mp3', faAnyFile, SR) = 0 then
  begin
    repeat
      if (SR.Attr <> faDirectory) then
      begin
        FileList.Add(SR.Name);
      end;
    until FindNext(SR) <> 0;
    FindClose(SR);
  end;
end;


function ReadID3Tag(sFileName:String):ID3Struct;
var
fMP3: file of Byte;
Tag: ID3Struct;
begin
try
AssignFile(fMP3, sFileName);
Reset(fMP3);
try
Seek(fMP3, FileSize(fMP3) - 128);
BlockRead(fMP3, Tag, SizeOf(Tag))
finally

end;

finally
CloseFile(fMP3)
end;

if tag.Signature<>'TAG' then
begin

result:=tag;
end
else
begin

end;
result:=tag;
end;


function StringProper (const sIn : string) : string;
  var
    i : integer;
  begin
    Result:=LowerCase(sIn);
    if Result='' then exit;

    Result[1]:= UpCase(Result[1]);
    for i:= 2 to length(Result) do begin
      if Result[i - 1] = ' ' then begin
      Result[i]:= Upcase(Result[i]);
    end;
  end;
end;

var
  sDir: String;
  fList: TStrings;
  i: integer;
  aSize: integer;
  curTag: ID3Struct;
  newTitle: String;

begin
  fList := TStrings.Create;
  if SelectDirectory('Please Select''C:\', sDir) then
  ShowMessage('abc');
  begin
    ListFileDir(sDir, fList);
    try
      aSize := fList.Count;
      for i := 0 to aSize do
      begin
      ShowMessage('abc');
         curTag := ReadID3Tag(fList[i]);
        showMessage('a');
        if (curTag.Artist <> ''and (curTag.Title <> ''then
        begin
          newTitle := curTag.Artist + ' - ' + curTag.Title;
          newTitle := Trim(newTitle);
          newTitle := StringReplace(newTitle, '"''', [rfReplaceAll]);
          newTitle := StringProper(newTitle);
          WriteLn(newTitle);
        end;
      end;
    finally
      fList.Free; 
    end;
  end;
end.


Habe ich das 'Try' richtig eingebaut?
Und: Immernoch stürzt das Programm an der besagten Stelle ab, aber dieses mal mit Fehlermeldung:

---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt Id3Changer.exe ist eine Exception der Klasse EAbstractError aufgetreten. Meldung: 'Abstrakter Fehler'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK Hilfe
---------------------------

Ich habe schon herausgefunden, dass es wieder bei fList.Count auftritt, kann mir aber nicht erklären warum!

Vielen Dank im Voraus, ich bin für jeden Tipp dankbar!

lG, Lenny
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Mi 30.06.10 15:41 
Count ist in Strings virtual; abstract;
also nicht vorhanden.
Verwende statt dessen TStringList;


hier lauert der nächste Stolperstein
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure ListFileDir(Path: string; FileList: TStrings);
var
  SR: TSearchRec;
begin
  if FindFirst(IncludeTrailingBackSlash(Path) + '*.mp3', faAnyFile, SR) = 0 then
  begin
    repeat
      if (SR.Attr <> faDirectory) then
      begin
        FileList.Add(IncludeTrailingBackSlash(Path)+SR.Name);
      end;
    until FindNext(SR) <> 0;
    FindClose(SR);
  end;
end;
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Mi 30.06.10 15:41 
Klar, weil eine Stringlist mit dem Index bei 0 anfängt. Deswegen hört sie auch nicht bei StringList.Count auf, sondern bei StringList.Count-1. ;) Sonst greifst du auf ein element zu das nicht existiert.

lg elundril

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Mi 30.06.10 15:57 
ab Delphi 2009 muß die Deklaration forlgendermassen aussehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  ID3Struct = record
    Signature: array[0..2of AnsiChar; { Should be: "TAG" }
    Title,
    Artist,
    Album: array[0..29of AnsiChar;
    Year: array[0..3of AnsiChar;
    Comment: array[0..29of AnsiChar;
    Genre: Byte;
  end;


die Hauptschleife
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:
begin
  fList := TStringList.Create;
  if SelectDirectory('Please Select''C:\', sDir) then

  begin
    ListFileDir(sDir, fList);
    try
      aSize := fList.Count;
      for i := 0 to aSize -1 do
      begin

         curTag := ReadID3Tag(fList[i]);

        if (curTag.Artist <> ''and (curTag.Title <> ''then
        begin
          newTitle := curTag.Artist + ' - ' + curTag.Title;
          newTitle := Trim(newTitle);
          newTitle := StringReplace(newTitle, '"''', [rfReplaceAll]);
          newTitle := StringProper(newTitle);
          Memo1.Lines .add(newTitle);
        end;
      end;
    finally
      fList.Free;
    end;
  end;

end;


und ListDir
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure ListFileDir(Path: string; FileList: TStrings);
var
  SR: TSearchRec;
begin
  if FindFirst(IncludeTrailingBackSlash(Path) + '*.mp3', faAnyFile, SR) = 0 then
  begin
    repeat
      if (SR.Attr <> faDirectory) then
      begin
        FileList.Add(IncludeTrailingBackSlash(Path)+SR.Name);
      end;
    until FindNext(SR) <> 0;
    FindClose(SR);
  end;
end;
PSLenny Threadstarter
Hält's aus hier
Beiträge: 13

Windows 7
Delphi 7
BeitragVerfasst: Mi 30.06.10 22:41 
Hey und vielen Dank euch allen! Ohne euch hätte es wahrscheinlich noch ewig gedauert! :)

Super, jetzt läuft alles einwandfrei!

Hier mein kompletter Code, inklusive Neubenennung der Dateien:

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:
152:
153:
154:
program ID3Changer;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes, FileCtrl, System, Dialogs;

type
  ID3Struct = record
    Signature: array[0..2of Char; { Should be: "TAG" }
    Title,
    Artist,
    Album: array[0..29of Char;
    Year: array[0..3of Char;
    Comment: array[0..29of Char;
    Genre: Byte;
  end;
  
const
 ID3Genre: array[0..125of string = (
    'Blues''Classic Rock''Country''Dance''Disco''Funk''Grunge',
    'Hip-Hop''Jazz''Metal''New Age''Oldies''Other''Pop''R&B',
    'Rap''Reggae''Rock''Techno''Industrial''Alternative''Ska',
    'Death Metal''Pranks''Soundtrack''Euro-Techno''Ambient',
    'Trip-Hop''Vocal''Jazz+Funk''Fusion''Trance''Classical',
    'Instrumental''Acid''House''Game''Sound Clip''Gospel',
    'Noise''AlternRock''Bass''Soul''Punk''Space''Meditative',
    'Instrumental Pop''Instrumental Rock''Ethnic''Gothic',
    'Darkwave''Techno-Industrial''Electronic''Pop-Folk',
    'Eurodance''Dream''Southern Rock''Comedy''Cult''Gangsta',
    'Top 40''Christian Rap''Pop/Funk''Jungle''Native American',
    'Cabaret''New Wave''Psychadelic''Rave''Showtunes''Trailer',
    'Lo-Fi''Tribal''Acid Punk''Acid Jazz''Polka''Retro',
    'Musical''Rock & Roll''Hard Rock''Folk''Folk-Rock',
    'National Folk''Swing''Fast Fusion''Bebob''Latin''Revival',
    'Celtic''Bluegrass''Avantgarde''Gothic Rock''Progressive Rock',
    'Psychedelic Rock''Symphonic Rock''Slow Rock''Big Band',
    'Chorus''Easy Listening''Acoustic''Humour''Speech''Chanson',
    'Opera''Chamber Music''Sonata''Symphony''Booty Bass''Primus',
    'Porn Groove''Satire''Slow Jam''Club''Tango''Samba',
    'Folklore''Ballad''Power Ballad''Rhythmic Soul''Freestyle',
    'Duet''Punk Rock''Drum Solo''Acapella''Euro-House''Dance Hall'
  );
{
function ReadID3Tag(sFileName:String):ID3Struct;
procedure WriteID3Tag(NewTag: ID3Struct; sFileName: string);
}

procedure ListFileDir(Path: string; FileList: TStrings);
var
  SR: TSearchRec;
begin
  if FindFirst(IncludeTrailingBackSlash(Path) + '*.mp3', faAnyFile, SR) = 0 then
  begin
    repeat
      if (SR.Attr <> faDirectory) then
      begin
        FileList.Add(IncludeTrailingBackSlash(Path)+SR.Name);
      end;
    until FindNext(SR) <> 0;
    FindClose(SR);
  end;
end;


function ReadID3Tag(sFileName:String):ID3Struct;
var
fMP3: file of Byte;
Tag: ID3Struct;
begin
try
AssignFile(fMP3, sFileName);
Reset(fMP3);
try
Seek(fMP3, FileSize(fMP3) - 128);
BlockRead(fMP3, Tag, SizeOf(Tag))
finally

end;

finally
CloseFile(fMP3)
end;

if tag.Signature<>'TAG' then
begin

result:=tag;
end
else
begin

end;
result:=tag;
end;


function StringProper (const sIn : string) : string;
  var
    i : integer;
  begin
    Result:=LowerCase(sIn);
    if Result='' then exit;

    Result[1]:= UpCase(Result[1]);
    for i:= 2 to length(Result) do begin
      if Result[i - 1] = ' ' then begin
      Result[i]:= Upcase(Result[i]);
    end;
  end;
end;

var
  sDir: String;
  fList: TStrings;
  i: integer;
  aSize: integer;
  curTag: ID3Struct;
  newTitle: String;

begin
  fList := TStringList.Create;
  if SelectDirectory('Please Select''C:\', sDir) then

  begin
    ListFileDir(sDir, fList);
    try
      aSize := fList.Count;
      for i := 0 to aSize -1 do
      begin

         curTag := ReadID3Tag(fList[i]);

        if (curTag.Artist <> ''and (curTag.Title <> ''then
        begin
          newTitle := curTag.Artist + ' - ' + curTag.Title;
          newTitle := Trim(newTitle);
          newTitle := StringReplace(newTitle, '"''', [rfReplaceAll]);
          newTitle := StringProper(newTitle);
          if (fList[i] <> sDir + '\' + newTitle + '.mp3'then
          begin
            WriteLn('Old title: ' + #09 + fList[i]);
            WriteLn('New title: ' + #09 + sDir + '\' + newTitle + '.mp3' + #10);
            RenameFile(fList[i], sDir + '\' + newTitle + '.mp3');
          end;
        end;
      end;
    finally
      fList.Free;
    end;
  end;
  while true do
  begin
  end;
end.


Vllt. kann es ja nochmal jemand gebrauchen, würde mich ja freuen ;)

Ich habe das gleiche Programm übrigens auch in AutoIt geschrieben (Bis jetzt meine einzige Sprache, in der ich weitgehende Kenntnisse habe) und grade einmal verglichen: Für 100 Lieder braucht AutoIt geschätzt 20 Sekunden, Delphi ca. 2. Sehr gut zu sehen, warum es sich lohnt auf eine Programmiersprache umzusteigen!

Vielen Dank nochmal, lG,
Lenny