Mein Favorit wäre aber nach wie vor das PostRecalc-Ereignis, um nicht auf die Anzahl der vorhanden Felder zu achten, würde ich eine Schleife in dieser Art schreiben:
Dim i%, fName$
i = 1
If ws.CurrentDocument.Document.HasItem("feld_" & i) Then fName = "feld_" & i
Do Until fName = ""
If ws.CurrentDocument.Document.GetFirstItem(fName).text = "OK" Then ws.CurrentDocument.save
i = i + 1
If ws.CurrentDocument.Document.HasItem("feld_" & i) Then fName = "feld_" & i Else fName = ""
Loop
Dann würde bei einem Postrecalc das Dokument 15 mal gespeichert, wenn alle 15 Felder auf OK stehen. Ich habe es so verstanden, dass nur beim Exiting des Feldes gespeichert werden soll, wenn dieses OK ist. Wobei die Frage erlaubt ist, was passieren soll, wenn ein Feld schon vorher OK war, dann der Cursor in das Feld gesetzt und das Feld danach unverändert verlassen wird. Dann ist das Feld zwar OK, m.E. soll dann aber nicht gespeichert werden. Entweder müsste man die Veränderung selbst feststellen, oder auf das OnChange-Event ausweichen.
Ohne es aktuell getestet zu haben, vermute ich, dass das CurrentField im Postrecalc das nächste Feld ausweist, und damit das falsche, denn das gerade eben verlassene Feld ist ja eigentlich relevant.
Wenn ich mich recht erinnere, habe ich vor vielen Jahren erfolglos versucht, etwas ähnliches allgemeingültig zu schreiben, und passe seither solche Scripte je Feld an. Ist ja in der Regel nur der Feldname zu aktualisieren.
Möglicherweise könnte man mit einem @ThisName im Entering etwas erreichen, das gab es damals noch nicht. Habe aber keine Ahnung, ob das über Evaluate einen sinnvollen Rückgabewert ergibt. Im Entering den aktuellen Feldnamen irgendwo hinschreiben, und im Exiting nach der Aktion wieder entfernen. Theoretisch immerhin denkbar.
EDIT: @ThisName ist natürlich nicht notwendig, sollte ja über CurrentField gehen, wie schon geschrieben wurde