I am refactoring an old MS Access Database, where the code distributes a number of enrolled Students among a list of internship openings into a distribution table. The code was cluttered among several forms and modules and called three times. I consolidated the code into a class "Distribution" but encounter now a "Record deleted" error which i don't understand, as it is dependent on the location of the recordset initializiation.
The code before worked like this.
public sub distribute()
dim students as recordset
dim openings as recordset
dim distribution as recordset
set students = Currentdb.OpenRecordset("Einschreibung_studenten_liste_verteilung", db_open_dynaset)
set openings = Currentdb.OpenRecordset("Select*From pzeitraum_temp Order by Rnd(-Timer()*[id]",db_open_dynaset)
set distribution = Currentdb.OpenRecordset("praxiseinteilung_tmp", db_open_dynaset)
'do a bunch of stuff, comparing students and openings and insert into distribution if a set of requirements are met
The logic spanned about 200 lines and was nested to about 6 or 7 levels. I separated the logic into several smaller subs, which now get called from the distribute sub. I thought the easiest and most concise way to keep functionality was to make the recordsets class variables and set them during class initializiation:
Class "Distribution" Pseudocode:
dim students as recordset
dim openings as recordset
dim distribution as recordset
Private Sub Class_Intialize()
set students = Currentdb.OpenRecordset("Einschreibung_studenten_liste_verteilung", db_open_dynaset)
set openings = Currentdb.OpenRecordset("Select*From pzeitraum_temp Order by Rnd(-Timer()*[id]",db_open_dynaset)
set distribution = Currentdb.OpenRecordset("praxiseinteilung_tmp", db_open_dynaset)
End Sub
Public Sub Distribute()
'do stuff
routine1
routine2
'do some more Stuff
End Sub
Private Sub routine1()
'do stuff with recordset
routine3
'do some more Stuff
End Sub
Private Sub routine2()
'do stuff with recordset
End Sub
Private Sub routine3()
'do other stuff with recordset
End Sub
When I tested the code it ran, but didn't produce sensible results. During Debugging i noticed, that the first
openings.FindFirst("Key =" & Searchvalue)
resulted in a
openings.NoMatch = True
but the Record exists.I inserted a loop at the start of the distribute sub, going through all openings records simply printing the key.
With openings
Do While .EOF = False
Debug.Print(!key)
.MoveNext
Loop
End with
This failed at the very first record, prompting a runtime Error "Record Deleted".
When I inserted the same loop at the end of the Class_Initialize Sub it ran without error and printed all the keys in the openings table. If I set the recordsets in the distribute sub and not during class initialization the code works and the recordsets have no issues.
But Why?
Since my goal is to refactor the code into a version where it is clear what it does and why it does it for easy maintenance i am hesitant to compromise.
Declaring the recordsets as class variables should make them available to all subs in the class. They should therefore be set during intialization. Setting them in a certain Sub begs the question why in this sub and which subs do have now access to these recordsets and why? This is exactly that kind of apparent randomness i am trying to avoid.
Edit1. Added "End Sub" to Class_Initialize Edit2.Corrected the Pseudocode for the "FindFirst" Method