It turns out that I was failing to recognize that the Go To Record Next command was not necessary when a deleted record was successful. Everything moved up on it's own.
So I produced this simple little script that works:
But, it is so sloooooooooooooow. Watching paint dry is faster.
What can I do to speed up the loop?
When doing a large amount of looping deletes like this it's better to 'flag' the records you want to delete, rather than delete in the loop.
Create a new field "MarkedForDeletion", which you set to True when you detect a duplicate.
Then after your loop, just do a Find for all the "MarkForDeletion = True" records, and Delete All.
When you delete records one by one, as you are doing, the record indexing needs to be updated with each delete. Deleting all records with a single Delete will only redo the indexing once.
As another minor speed improvement, replace AND logic with Case where possible:
If $KV = #NextKV and $KM=NextKM and not isEmpty($KV) and not isEmpty($KM)
This can be made more efficient via a Case statement:
isEmpty( $KM ) ; 0 ;
isEmpty( $KV ) ; 0 ;
$KV = #NextKV and $KM=NextKM ; 1 ;
This means if $KM or $KV is empty, we don't need to do the slower text comparison step.
Concatenated "AND" statements do NOT exit out when a False is reached. Everything is calculated and the overall statement is then evaluated as True/False.