Expert guide
School Attendance Tracking Database in Microsoft Access
Registers in seconds, accurate percentages, and absence patterns spotted in week three, not at report time
Call us at +1 (385) 386-3860
Short answer: model attendance as Students, Classes, Enrolments, Sessions and Marks (one row per student per session with a code such as P, L, A, E). Generate sessions from each class timetable, take registers on a continuous form that defaults everyone to Present, then calculate attendance rate = attended ÷ expected sessions with queries. Flag students under your threshold weekly and produce parent letters from a report. We build these as custom Access databases.
Small independent schools, tutoring centres, language academies, apprenticeship providers and after-school programmes often track attendance in spreadsheets with a column for every day. By November the sheet is 90 columns wide, percentages are calculated differently on each tab, and nobody notices a student missing every Monday. A properly structured attendance database fixes the arithmetic and shows patterns.
The Tables
| Table | Key fields |
|---|---|
| tblStudents | StudentID, Name, DOB, Guardian contact, Status |
| tblClasses | ClassID, Name, Teacher, Room, Weekdays, StartTime, TermStart, TermEnd |
| tblEnrolments | StudentID, ClassID, EnrolledOn, WithdrawnOn |
| tblSessions | SessionID, ClassID, SessionDate, Cancelled (Y/N) |
| tblMarks | SessionID, StudentID, Code, MinutesLate, Note, MarkedBy, MarkedAt |
| tblCodes | Code, Description, CountsAsPresent, Authorised |
| Code | Meaning | Counts as present | Authorised |
|---|---|---|---|
| P | Present | Yes | n/a |
| L | Late | Yes (policy) | n/a |
| E | Excused / authorised absence | No | Yes |
| A | Unexcused absence | No | No |
| M | Medical | No | Yes |
Generating Sessions From the Timetable
Public Sub GenerateSessions(ByVal classID As Long)
Dim db As DAO.Database, rsC As DAO.Recordset, d As Date
Set db = CurrentDb
Set rsC = db.OpenRecordset("SELECT * FROM tblClasses WHERE ClassID=" & classID)
For d = rsC!TermStart To rsC!TermEnd
' Weekdays stored like "Mon,Wed,Fri"
If InStr(rsC!Weekdays, Format(d, "ddd")) > 0 Then
If DCount("*", "tblSessions", "ClassID=" & classID & _
" AND SessionDate=#" & Format(d, "yyyy-mm-dd") & "#") = 0 Then
db.Execute "INSERT INTO tblSessions (ClassID, SessionDate, Cancelled) " & _
"VALUES (" & classID & ", #" & Format(d, "yyyy-mm-dd") & "#, False)", _
dbFailOnError
End If
End If
Next d
End SubMark holidays and cancellations by setting Cancelled = True rather than deleting sessions, so the record shows what happened.
The Register Form
Teacher picks class and date; the form lists enrolled students for that session.
A button 'Mark all present' inserts P for everyone, then the teacher changes only exceptions.
Single-key entry: typing L, A or E in the code column moves to the next student.
Late minutes and notes optional; MarkedBy and MarkedAt filled automatically.
A register that has not been taken by a set time appears on the office dashboard.
Private Sub cmdAllPresent_Click()
CurrentDb.Execute "INSERT INTO tblMarks (SessionID, StudentID, Code, MarkedBy, MarkedAt) " & _
"SELECT " & Me.cboSession & ", e.StudentID, 'P', '" & Environ("USERNAME") & "', Now() " & _
"FROM tblEnrolments AS e INNER JOIN tblSessions AS s ON e.ClassID = s.ClassID " & _
"WHERE s.SessionID = " & Me.cboSession & _
" AND e.EnrolledOn <= s.SessionDate AND (e.WithdrawnOn Is Null OR e.WithdrawnOn > s.SessionDate)" & _
" AND e.StudentID Not In (SELECT StudentID FROM tblMarks WHERE SessionID = " & Me.cboSession & ")", _
dbFailOnError
Me.sfrmMarks.Requery
End SubAttendance Rate Query
qryAttendanceTermToDate:
SELECT st.StudentID, st.Name,
Sum(IIf(c.CountsAsPresent, 1, 0)) AS Attended,
Count(m.SessionID) AS Expected,
Sum(IIf(c.CountsAsPresent, 1, 0)) / Count(m.SessionID) AS Rate,
Sum(IIf(m.Code = "A", 1, 0)) AS Unexcused
FROM ((tblMarks AS m
INNER JOIN tblSessions AS s ON m.SessionID = s.SessionID)
INNER JOIN tblCodes AS c ON m.Code = c.Code)
INNER JOIN tblStudents AS st ON m.StudentID = st.StudentID
WHERE s.Cancelled = False AND s.SessionDate >= [Forms]![frmMenu]![txtTermStart]
GROUP BY st.StudentID, st.Name;Because marks only exist for sessions a student was enrolled in, the expected count automatically excludes sessions before enrolment and after withdrawal.
Early Warning Reports
Below threshold: rate under your target (for example 90%) term to date or over the last four weeks.
Streaks: three or more consecutive absences.
Day-of-week pattern: absences concentrated on one weekday.
Lateness: repeated lates or high total late minutes.
Unmarked registers: sessions with fewer marks than enrolled students.
Parent and Guardian Communication
An Access report produces letters or emails for students below threshold, listing the dates missed. AI can help draft a supportive message from the facts, which staff edit before sending; avoid sending student data to unapproved tools. The email automation pattern is in sending email from Access with Outlook VBA.
Training Providers and Funded Programmes
Apprenticeship and funded training providers often have to evidence attendance for each learner to receive funding. The same structure works, with sessions tied to course modules and an export in the format the funding body requires. Signed paper registers can be scanned and linked to each session as evidence.
Scanning registers into the database uses the approach in scanning documents into Access with AI. Similar session-and-attendance structures power church membership and attendance databases. For report design, see Access reports and forms.
FAQ
School attendance database FAQ
Structure, percentages and early warnings