Viết một chương trình trắc nghiệm thật là thú vị, nhưng để trình bày chi tiết cho bạn trên một diện tích chật hẹp của eChíp thì e rằng quá tải ! Tôi xin trình bày một ví dụ thật đơn giản nhưng rất cơ bản để từ đó bạn có thể tự chíp ứng dụng theo ý đồ của mình. Ví dụ: số câu hỏi cho mỗi lần trắc nghiệm là 30 (được chọn ngẫu nhiên từ ngân hàng câu hỏi), chọn 1 trong 4 đáp án.
Giả sử ứng dụng Access có tên là DataTN.MDB. Bạn tạo một table có tên NganHangCauHoi để chứa ngân hàng các câu hỏi, có cấu trúc như trong bảng 1.
Bảng này chứa số lượng không hạn chế các câu hỏi, mỗi câu hỏi được đánh số tự động, và có 4 mục tin (
TraLoi1,
TraLoi2,
TraLoi3,
TraLoi4) chứa nội dung 4 câu trả lời mà thí sinh có thể chọn. Mục tin
DapAnDung chứa số thứ tự (từ
1 đến
4) của câu trả lời đúng. Mục tin
DaDuocChon dùng để đánh dấu câu hỏi nào (trong ngân hàng câu hỏi) đã được chọn trong quá trình lựa chọn ngẫu nhiên 30 câu hỏi dùng cho bộ đề. Bạn cần phải thiết kế một
form để nhập liệu vào bảng này.
Tương tự, bạn cần tạo bảng DeThiVaKetQua như trong bảng 2 để chứa bộ đề 30 câu hỏi.
Bảng này có mục tin
DapAnDuocChon cho biết thí sinh đã chọn câu trả lời nào trong 4 câu trả lời được phép. Giả sử: trả lời đúng được 1 điểm, trả lời sai được 0 điểm. Tạo một
query có tên
qryDeThiVaKetQua như
hình 2 để làm
Record Source cho
form trắc nghiệm.
Sau khi thiết kế xong cấu trúc các bảng dữ liệu, việc đầu tiên bạn nên làm là nhập
hơn 30 câu hỏi vào ngân hàng câu hỏi.
Bạn thiết kế biểu mẫu trắc nghiệm như trong hình 1. Khi thiết kế biểu mẫu này, cần lưu ý:
· Đặt thuộc tính AllowAdditions của form là No. Thuộc tính Locked của ô SoThuTu và NoiDung là Yes.
· Đặt tên cho frame chứa 4 đáp án là grpTraLoi. Đặt tên cho các label liên kết với mỗi option thuộc grpTraLoi lần lượt là lblTraLoi1, lblTraLoi2, lblTraLoi3, lblTraLoi4 theo thứ tự từ trên xuống.
· Đặt tên cho 2 nút lệnh Kết quả và Chọn đề là cmdKetQua và cmdChonDe.
Bây giờ bạn gõ tiếp các đoạn mã xử lý tình huống như dưới đây:
Private Sub Form_Current()
‘ Nội dung 4 đáp án liệt kê mỗi lần chuyển câu khác
lblTraLoi1.Caption = Me.TraLoi1
lblTraLoi2.Caption = Me.TraLoi2
lblTraLoi3.Caption = Me.TraLoi3
lblTraLoi4.Caption = Me.TraLoi4
grpTraLoi = Me.DapAnDuocChon
End Sub
Private Sub grpTraLoi_Click()
Me.DapAnDuocChon = grpTraLoi ‘ Khi thí sinh chọn đáp án
End Sub
Private Sub cmdChonDe_Click()
Dim db As Database, tbDeThi As Recordset, _
tbNganHang As Recordset, rsTamThoi As Recordset
Dim nSoLuongCau As Byte, I As Byte, sSQL As String
Dim nTongSoCauTrongNH As Long, nSoNgauNhien As Long
nSoLuongCau = 30 ' Giả sử 30 câu
Set db = CurrentDb
' Tạm thời không kiểm tra trường hợp số lượng câu hỏi
' cần chọn có lớn hơnhay bằng tổng số câu trong
' ngân hàng đề thi không
Set tbNganHang = db.OpenRecordset("NganHangCauHoi")
tbNganHang.MoveFirst
If tbNganHang.EOF Then
MsgBox "Không có câu hỏi trong ngân hàng đề thi !"
tbNganHang.Close
db.Close
Exit Sub
End If
' Xóa đề trước đó
sSQL = "DELETE * FROM DeThiVaKetQua;"
db.Execute sSQL
' Tính tổng số câu hỏi trong ngân hàng đề thi
sSQL = "SELECT Max(SoThuTu) AS TongSoCauHoi " & _
"FROM NganHangCauHoi"
Set rsTamThoi = db.OpenRecordset(sSQL)
rsTamThoi.MoveFirst
nTongSoCauTrongNH = rsTamThoi!TongSoCauHoi
rsTamThoi.Close
Set tbDeThi = db.OpenRecordset("DeThiVaKetQua")
' Tạo đề mới
tbNganHang.Index = "SoThuTu"
For I = 1 To nSoLuongCau
Do While True
‘ Chọn số thứ tự ngẫu nhiên
nSoNgauNhien = Int((nTongSoCauTrongNH * Rnd) + 1)
tbNganHang.Seek "=", nSoNgauNhien
If Not tbNganHang.NoMatch Then ' Tìm thấy
If Not tbNganHang!DaDuocChon Then ' Chưa chọn
tbDeThi.AddNew
tbDeThi!SoThuTu = I
tbDeThi!NoiDung = tbNganHang!NoiDung
tbDeThi!TraLoi1 = tbNganHang!TraLoi1
tbDeThi!TraLoi2 = tbNganHang!TraLoi2
tbDeThi!TraLoi3 = tbNganHang!TraLoi3
tbDeThi!TraLoi4 = tbNganHang!TraLoi4
tbDeThi!DapAnDung = tbNganHang!DapAnDung
tbDeThi!DapAnDuocChon = 0
tbDeThi.Update
' Đánh dấu đã chọn đưa vào bộ đề thi rồi
tbNganHang.Edit
tbNganHang!DaDuocChon = True
tbNganHang.Update
Exit Do
End If
End If
Loop
Next
tbDeThi.Close
' Đánh dấu chưa chọn các câu hỏi trong ngân hàng đề thi
tbNganHang.Close
sSQL = "UPDATE NganHangCauHoi SET " & _
"DaDuocChon = False WHERE DaDuocChon = True"
db.Execute (sSQL)
db.Close
' Bộ đề mới đã tạo xong, hiển thị lại trên biểu mẫu
Me.Requery
SoThuTu.SetFocus ‘ Để có thể disable nút Chọn đề
cmdChonDe.Enabled = False ‘ Không cho chọn đề khác nữa
End Sub
Private Sub cmdKetQua_Click()
Dim nTongDiem As Byte, rs As Recordset
Set rs = Me.Recordset
nTongDiem = 0
With rs
.MoveFirst
While Not .EOF
nTongDiem = nTongDiem + _
IIf(!DapAnDuocChon = !DapAnDung, 1, 0)
.MoveNext
Wend
.MoveFirst
End With
MsgBox "Tổng số điểm đạt được là: " & nTongDiem, _
vbInformation, Me.Caption
Set rs = Nothing
End Sub
Bạn cũng có thể mở rộng ý tưởng cho ứng dụng này như sau: các câu hỏi trong NganHangCauHoi được phân loại theo độ khó dễ (dễ ợt, hơi hơi dễ, hơi hơi khó, khó,…) kèm theo điểm tương ứng nếu trả lời đúng. Trong khi tạo bộ đề, yêu cầu người ra đề cho biết 30 câu hỏi sẽ gồm bao nhiêu câu dễ ợt, bao nhiêu câu hơi hơi dễ, bao nhiêu câu hơi hơi khó, bao nhiêu câu khó,… Bạn cũng có thể đưa hình ảnh minh họa vào nội dung câu hỏi cho sinh động hơn.
Đàm Văn Chương