Wie definiere ich dann "i" ? Ist es durch die Fragenanzahl zu ersetzen? 
Ja, aber du weißt im Allgemeinen doch nicht, wieviele Fragen in der Datei stehen. Am besten arbeitest du mit einem dynamischen Array (aFragen: array of fragen), startest mit Array-Länge 0 und erhöhst die Array-Lange vor jedem Datensatz um 1 (es geht auch besser, aber das würde dich hier nur verwirren). Und beachte, dass die Indizierung eines dynamischen Arrays bei 0 beginnt. So sollte die Leseroutine in unit3 funktionieren (nicht getestet):
Code: Alles auswählen
 
var
  afrage: array of fragen
 
procedure TForm3.B_starttestClick(Sender: TObject);
var i:integer;
 begin
   SetLength(afragen, 0);  // wp
   RG_frage.visible:=true;
   RB_1.Visible:=true;
   RB_2.Visible:=true;
   RB_3.Visible:=true;
   B_starttest.visible:=false;
   punkte:=0;                         //Punkte-Startwert festlegen
   fnr:=1;                            //FragenNummer auf 1 setzen
   assignfile(datei,'fragen.db');     //die .db-Datei wird der Variable "datei" zugewiesen
   reset(datei);                      //Öffnen der Datei zum Lesen
   i:=0;
   seek(datei,0);
   while not eof(datei) do begin     //Auslesen der "fragen.db"-Datei mit Schleife
         seek(datei,i);              //Datensatzzeiger setzen
         read(datei,datensatz);      //Lesen eines Datensatzes
         SetLength(afragen, i+1);    // wp: Platz im Array für neue Frage schaffen
         afragen[i].frtext:=datensatz.frtext; //Belegung des zuvor definierten Records mit den Daten aus der "fragen.db"-Datei
         afragen[i].a1:=datensatz.a1;
         afragen[i].a2:=datensatz.a2;
         afragen[i].a3:=datensatz.a3;
         afragen[i].richtig:=datensatz.richtig;
         fnr:=1;
         punkte:=0;
         i:=i+1;            // wp: Zähler hochzählen. Steht jetzt am Ende, weil die Indizierung des Arrays bei 0 beginnt.
   end;
   closefile(datei);                    //Datei schließen
 
   // wp: Im folgenden wird Index 1 durch 0 ersetzt
   RG_frage.Caption:=afragen[0].frtext; //Füllen der Überschrift der RadioGroup mit der Frage Nr. 1 aus der Datei
   RB_1.Caption:=afragen[0].a1;         //Füllen des 1. Radiobuttons mit der Antwort Nr. 1 zur Frage 1 aus der Datei
   RB_2.Caption:=afragen[0].a2;         //Füllen des 2. Radiobuttons mit der Antwort Nr. 2 zur Frage 1 aus der Datei
   RB_3.Caption:=afragen[0].a3;         //Füllen des 3. Radiobuttons mit der Antwort Nr. 3 zur Frage 1 aus der Datei
   B_pruefen.Visible:=true;
 end;
 
       
Zur 2. Frage: Ich würde alles in eine Datei schreiben, ein Record pro Teilnehmer. Wenn du die Ergebnisse eines Teilnehmers abspeichern willst, musst du zuerst suchen ob dieser schon eingetragen ist und den Datensatz überschreiben. Es gibt bessere Methoden, aber du hast mit klassischen Dateien angefangen, dann könntest du so vorgehen:
Code: Alles auswählen
 
procedure TForm3.B_auswertungClick(Sender: TObject);
const
  DATEINAME = 'ergebnisse.txt';  // wird öfter verwendet!
 
type 
  // Das ist der Record, der in die Datei geschrieben wird. Wichtig ist, dass die Größe konstant ist
  TAntworten = record  
    vname:string[30];
    nname:string[40];
    ant_geg:string[30];
    punkte_err:integer;
  end;
 
var
  p: Integer; 
  antworten: TAntworten;
 
begin
  Showmessage('Congratulations! You reached '+inttostr(punkte)+' points.');
 
  assignfile(datei_antworten,DATEINAME);
 
  // Wenn's die Antwortendatei bereits gibt, zuerst zum Lesen öffnen und die Position des Datensatzes suchen
  if FileExists(DATEINAME) then begin
    resetfile(datei_antworten, SizeOf(TAnworten));
    while not EoF(datei_antworten)  do begin
      p := FilePos(datei_antworten);
      Read(datei_antworten, antworten);
      if (antworten.vname = vname) and (antworten.nname=nname) then  
      // Hier ist der Datensatz gefunden. "p" hat sich die Position in der Datei gemerkt.
        break;
    end;
    closeFile(datei_antworten);
  end else
    p := 0;
 
  // Nun die Datei ein 2. Mal zum schreiben öffnen und an Position "p" den neuen Datensatz schreiben
  rewriteFile(datei_antworten, Sizeof(TAntworten));
  Seek(datei_antworten, p);
  antworten.vname := vname;
  antworten.nname := nname;
  // usw - die Felder des Record füllen...
  Write(datei_antworten, antworten);  // Hier wird der bisherige Record in der Datei überschreiben. Weil alle Records gleich groß sind, wird nichts zerstört!
  closeFile(datei_antworten);
 
[EDIT] Ich habe schon seit Urzeiten nichts mehr mit klassischen Dateien gemacht... Bin nicht mehr sicher, ob nicht die Datei bei "rewrite" gelöscht wird. --> ausprobieren. Und es fehlt oben noch die Deklaration der Dateivariablen:
Generell würde ich das Programm nicht mit klassischen Dateien angehen. Schon eine einfache INI-Datei für Fragen und Ergebnisse würde manches einfacher und klarer machen:
Code: Alles auswählen
 
uses
  IniFiles;
 
type
  TFrage = record
    Frage: String;
    Antwort1: String;
    Antwort2: String;
    Antwort3: String;
    Richtig: Integer;
  end;
 
var
  FragenArray: Array of TFrage;
 
procedure TForm3.B_starttestClick(Sender: TObject);
var
  ini: TIniFile;
  L: TStringList;
  key: String;
begin
  ini := TIniFile.Create('fragen.txt');   // Die Endung ".db" klingt zu sehr nach Datenbank
  L := TStringList.Create;
  try
    ini.ReadSection('Fragen', L);
    SetLength(FragenArray, L.Count);
    for i:=0 to L.Count-1 do begin
      key := 'Frage' + IntToStr(i+1);
      Fragen[i].Frage := ini.ReadString(key, 'Frage', '');
      Fragen[i].Antwort1 := ini.ReadString(key, 'Antwort1', '');
      Fragen[i].Antwort2 := ini.ReadString(key, 'Antwort2', '');
      Fragen[i].Antwort3 := ini.ReadString(key, 'Antwort3', '');
      Fragen[i].Richtig := ini.ReadInteger(key, 'Richtig', -1);
    end;
  finally
    L.Free;
    ini.Free;
  end;
 
  RG_frage.Caption:=Fragen[0].Frage; //Füllen der Überschrift der RadioGroup mit der Frage Nr. 1 aus der Datei
  RB_1.Caption:=Fragen[0].Antwort1;   //Füllen des 1. Radiobuttons mit der Antwort Nr. 1 zur Frage 1 aus der Datei
  RB_2.Caption:=Fragen[0].Antwort2;   //Füllen des 2. Radiobuttons mit der Antwort Nr. 2 zur Frage 1 aus der Datei
  RB_3.Caption:=Fragen[0].Antwort3;   //Füllen des 3. Radiobuttons mit der Antwort Nr. 3 zur Frage 1 aus der Datei
  B_pruefen.Visible:=true;
end;
 
Diese Ini-Datei ist eine Text-Datei, die du mit jedem Editor erstellen und ändern kannst - bei deinen eigenen Dateien geht das nicht. Hier wäre eine Beispiel:
Code: Alles auswählen
 
[Frage1]
Frage=How do you do?
Antwort1=Wie geht es Ihnen?
Antwort2=Wie alt sind Sie?
Antwort3=Was tun Sie da?
Richtig=1
 
[Frage2]
.... usw