Umfragen und Multiple-Choice-Tests - Teil 1

15.03.2006
Egal, ob Sie ein e-Learning-System erstellen möchten oder nur Umfragen zur Qualitätsverbesserung in Ihre Anwendung einbauen möchten – der Aufbau der dazu notwendigen Tabellen ist nahezu identisch. Wir zeigen Ihnen, wie Sie solche Umfragen und Tests mit Access realisieren.

Umfragen zeichnen sich genau wie Multiple-Choice-Tests dadurch aus, dass es eine Frage und eine fest definierte Anzahl vorgegebener Antworten gibt. Der Testkandidat kann dann unter den vorgegebenen Antworten eine wählen, die er für richtig hält. Der Unterschied zwischen Umfragen und Multiple-Choice-Tests besteht allerdings darin, dass es bei Umfragen keine richtigen und falschen Antworten gibt, da es sich ja um Meinungen der Benutzer handelt. Auch die Auswertung ist dann natürlich etwas anders. Hier interessiert nur, welche der möglichen Antworten wie oft angegeben wurde. Bei Tests ist dies natürlich anders. Jeder Benutzer sollte natürlich in der Auswertung erfahren, wie viele Fehler er gemacht hat. Zudem erfolgen Umfragen in der Regel anonym, werden dafür aber auf jeden Fall von vielen Benutzern verwendet. Daher machen Umfragen nur in Mehrbenutzerumgebungen Sinn, wenn die Daten in einer Backend-Datenbank gespeichert werden, die von mehreren Benutzern über ein Frontend gespeist wird.

Möchten Sie so etwas mit Access realisieren, sollten Sie als Allererstes klären, welche Anforderungen Ihre Datenbank erfüllen soll, denn davon hängt der Tabellenaufbau ab. Spätere Änderungen sind in diesem Fall nämlich enorm aufwändig.

Anforderungen an die Datenbank

Generell sind zwei Möglichkeiten denkbar, wie solche Umfragen erzeugt werden können.

Beide Möglichkeiten haben ihre Vor- und Nachteile. Im ersten Fall können Sie sehr variable Umfragen erstellen, weil Sie eben sowohl nur 2 als auch 20 mögliche Antworten zulassen können. Darüber hinaus wäre es möglich, auch mehrere richtige Antworten zu erlauben, indem Sie ein boolesches Feld für jede Antwort definieren, in dem Sie angeben können, ob dies eine richtige Antwort ist. Die erste Möglichkeit ist vor allem dann interessant, wenn es nur eine geringe Anzahl Antwortmöglichkeiten gibt und sie deren maximale Anzahl kennen. Wissen Sie beispielsweise, dass maximal 10 verschiedene Antworten möglich sind, würden Sie die Frage und 10 Antwortfelder einfach ein einer Tabelle speichern. Unpraktikabel ist dieses Vorgehen aber, wenn Sie mehr als eine mögliche Antwort definierten möchten. Dann müssten Sie für jedes Antwortfeld noch ein zusätzliches boolesches Feld definieren. Bei nur einer möglichen Antwort ist das jedoch kein Problem. Sie definieren dazu einfach ein zusätzliches Feld in der Tabelle, indem Sie die Nummer oder den Text der richtigen Antwort speichern.

Für Tests müssen Sie natürlich außerdem die Antworten des Benutzers speichern. Auch das ist abhängig von den Anforderungen. Falls mehrere Antworten pro Frage gewählt werden können, müssten Sie entweder in der Tabelle mit den Ergebnissen für jede mögliche Antwort ein Feld vorsehen oder, wenn Sie die maximale Zahl Antworten nicht kennen, für jede Antwort einen Datensatz erstellen.

Tabellen für die Umfrage

Die einfachste Tabelle ist die zur Speicherung der Umfragen. Sie benötigt ein Autowert-Feld für die ID der Umfrage sowie ein Textfeld mit der Frage (Bild 1). Außerdem benötigen Sie für jede mögliche Antwort ein Antwortfeld, in dem die mögliche Antwort gespeichert wird. Optional können Sie noch ein zusätzliches Memofeld Hilfe ergänzen, in dem Sie Erläuterungen zur Frage angeben. Für die Frage reicht in der Regel ein Textfeld der Länge 255 aus, für die Antworten genügen Textfelder der Länge 100.

Bild 1: Aufbau der Tabelle tabUmfragen zur Speicherung der Umfragen.
Bild 2: Aufbau der Tabelle tabUmfragenErgebnisse.

Um die Antworten zu speichern, reicht eine Tabelle aus drei Feldern, einem AutoWert-Feld ID, einem Feld mit der ID der Umfrage, Umfrage und ein Feld Antwort, das den Text oder Wert der Antwort speichert (Bild 2). Letzteres sollte den gleichen Datentyp und die gleiche Länge haben wie die Antwort-Felder in der Tabelle tabUmfragen. Für das Feld Umfrage legen Sie den Datentyp Zahl mit der Feldlänge Long fest, da es die Werte aus dem AutoWert-Feld in der Tabelle tab-Umfragen speichern muss.

Tabellen für Multiple-Choice-Tests

Wenn Sie Multiple-Choice-Tests erstellen möchten, ist das schon etwas komplexer, zumal in diesem Fall eine beliebige Anzahl Antworten ermöglicht werden soll.

Zunächst einmal benötigen Sie dazu wieder eine Tabelle mit den Fragen. Sie muss ein Feld Frage für die Frage enthalten, das in der Regel mit einem Textfeld von 255 Zeichen Länge auskommen sollte. Bei Bedarf können Sie auch hier ein Feld Hilfe als Memo-Feld einfügen. Damit Sie der Frage die möglichen Antworten über eine 1:n- Beziehung zuordnen können, benötigen Sie außerdem eine AutoWert-Feld, das hier wieder ID heißt und als Primärschlüssel dient.

Außerdem benötigen Sie eine zweite Tabelle Antworten. Sie braucht ein Feld Frage, in dem Sie die ID der Frage aus der Tabelle tabFragen speichern, zu der die Antwort gehört. Außerdem benötigen Sie ein Feld Antwort für den Text oder den Wert der Antwort und ein Ja/Nein-Feld, in dem Sie angeben können, ob dies eine richtige Antwort ist. Beide Tabellen verknüpfen Sie über die Felder tabFragen.ID und tabAntworten.Frage (Bild 3).

Bild 3: Tabellen zur Speicherung von Fragen und Antworten für Multiple-Choice-Tests.

Für die Beziehung sollten Sie referenzielle Integrität mit Löschweitergabe aktivieren, damit die Antworten gelöscht werden, wenn die Frage gelöscht wird.

Tabellen verknüpfen

Um die Tabellen zu verknüpfen, öffnen Sie die Frontend-Datenbank beziehungsweise erstellen eine neue, leere Datei. Im Datenbankfenster wählen Sie aus dem Kontextmenü der Kategorie Tabellen den Eintrag Tabellen verknüpfen aus. Anschließend wählen Sie die Backend-Datenbank aus und markieren dort die zu verknüpfenden Tabellen.

Die Testergebnisse speichern

Jetzt fehlt noch die Tabelle für die Testergebnisse. Hier wird es jetzt richtig kompliziert. Da zu einer Frage möglicherweise mehrere richtige Antworten gehören können, müssen Sie natürlich auch diese Antworten speichern. Generell gibt es dafür drei alternative Vorgehensweisen.

Betrachtet man die Datenmenge, ist sicherlich die erste Alternative die beste, weil hier die wenigsten Datensätze erstellt werden müssen. Allerdings hat sie den Nachteil, dass die Auswertung mittels Abfragen nicht möglich ist. Die letzte Alternative erzeugt die meisten Datensätze. Antworten, die nicht angekreuzt wurden, müssen schließlich gar nicht erst in der Ergebnismenge für den Benutzer auftauchen. Optimal für Datensatzanzahl und Auswertungsmöglichkeiten ist daher die zweite Alternative. Um sie zu verwirklichen, benötigen Sie eine Tabelle tabErgebnisse, die neben einer ID als AutoWert-Feld ein Feld Frage mit der ID der Frage und ein Feld Antwort mit der ID der gewählten Antwort enthält. Außerdem müssen Sie natürlich auch den Namen des Benutzers speichern. Hier wird dazu ein Textfeld Benutzer mit einer Länge von 20 Zeichen erstellt. Die Felder Frage und Antwort bekommen beide den Datentyp Zahl mit der Feldlänge long.

Zum Schluss definieren Sie noch die Beziehungen (Bild 4) zwischen den Feldern Frage, Antwort und den Tabellen tabFragen und tabAntworten.

Bild 4: Beziehungen zwischen der Tabelle tabErgebnisse und den Tabellen tabFragen und tabAntworten.

Umfragen verwalten

Um die Umfragen verwalten zu können, benötigen Sie zunächst nur ein einfaches Formular frmUmfragenverwalten, das an die Tabelle tab-Umfragen gebunden ist. Dieses erstellen Sie allerdings in der Frontend-Datenbank, in der Sie zuvor die Tabellen tabUmfragen und tabUmfragenErgebnisse verknüpft haben.

Das Formular können Sie einfach mit dem Formularassistenten von Access erstellen und dieses später anpassen, indem Sie die Beschriftungen der Antwortfelder anpassen.

Abstimmung ermöglichen

Komplizierter wird es, wenn Sie dem Benutzer die Umfrage anzeigen möchten, damit er daran teilnehmen kann. Dann müssen Sie nämlich nicht nur die Frage und eventuell den Hilfetext anzeigen, sondern auch die möglichen Antworten. Hier gibt es mehrere Möglichkeiten, alle erfordern jedoch etwas VBA-Code. Verhältnismäßig einfach funktioniert die Sache mit einem Formular und einem Unterformular.

1. Zunächst erstellen Sie dazu ein Formular frmUmfragen mit dem Assistenten. Darin müssen mindestens die Felder Frage und Hilfe aus der Tabelle tabUmfragen angezeigt werden.

2. Nutzen Sie nicht die Tabelle tabUmfragen als Datenquelle, sollte die Abfrage zusätzlich das Feld ID beinhalten, weil Sie das für die Verknüpfung des Unterformulars benötigen.

3. Für alle Steuerelemente des Formulars setzen Sie dann die Eigenschaft Gesperrt auf Ja, damit der Benutzer die Feldwerte nicht ändern kann.

4. Erstellen Sie außerdem ein zweites Formular frmUmfrAntwortauswahl, das später als Unterformular dient und als Datenquelle die Tabelle tabUmfragenErgebnisse verwendet.

5. Alle Steuerelemente des Formulars fügen Sie im Formularkopf ein. Es sollte ausschließlich die Felder Umfrage und Antwort enthalten. Beide Eingabefelder können Sie ausblenden, indem Sie die Eigenschaft Sichtbar auf Nein setzen.

6. Zusätzlich fügen Sie in das Formular eine Schaltfläche mit dem Namen bttAbstimmen ein und beschriften sie mit "abstimmen".

7. Ergänzen Sie die Schaltfläche durch eine Ereignisprozedur für das Click-Ereignis (Listing 1). Sie sorgt dafür, dass das Formular geschlossen und die Daten gespeichert wird. Auf diese Weise kann der Benutzer nur einmal und nicht mehrfach hintereinander abstimmen.

Private Sub bttAbstimmen_Click()
Me.Filter=""
DoCmd.Close acForm, Me.Parent.Name, acSaveYes
End Sub
Private Sub cmbAntworten_Change()
Me.Antwort.Value = Me.cmbAntworten.Value
End Sub

8. Zuletzt fügen Sie noch ein ungebundenes Kombinationslistenfeld hinzu und nennen es cmbAntworten. Für dieses Feld erstellen Sie eine Ereignisprozedur für das Ergebnis Bei Änderung (Change) (Listing 1). Beim Ändern der Auswahl in der Liste wird deren Wert in das gebundene Textfeld Antwort geschrieben.

9. Speichern und schließen Sie das Unterformular. Zu guter Letzt sind noch ein paar kleine Ergänzungen am Formular frmUmfragen notwendig.

10. Als Erstes fügen Sie das zuvor erstellte Formular als Unterformular in das Formular frmUmfragen ein und verknüpfen es über dessen Feld Umfrage mit dem Feld ID des Formulars frmUmfragen. Das Steuerelement, in dem das Unterformular angezeigt wird, sollten Sie frmUfo nennen (Bild 5).

Bild 5: Das Formular für die Abstimmung.

11. Sorgen Sie nun noch dafür, dass beim Anzeigen der Frage, das Kombinationslistenfeld im Unterformular mit den möglichen Antworten gefüllt wird. Dafür erstellen Sie eine Ereignisprozedur für das Ereignis Beim Anzeigen (Form_Current).

12. Innerhalb dieser Prozedur löschen Sie zunächst die alten Einträge aus dem Kombinationslistenfeld, indem Sie so lange mit der RemoveItem-Methode den ersten Eintrag mit dem Index 0 löschen, bis die Liste leer ist.

13. Anschließend füllen Sie die Liste mit den Feldwerten der Felder A1 bis A5 der Datenquelle des übergeordneten Formulars (Listing 2).

Private Sub Form_Current()
Dim objFrm As Form_frmUmfAntwortauswahl
Set objFrm = Me.frmUfo.Form
'Liste leeren
Do While objFrm.cmbAntworten.ListCount > 0
objFrm.cmbAntworten.RemoveItem (0)
Loop
'Liste füllen
objFrm.cmbAntworten.AddItem _
Me.RecordsetClone.Fields("A1").Value
objFrm.cmbAntworten.AddItem _
Me.RecordsetClone.Fields("A2").Value
objFrm.cmbAntworten.AddItem _
Me.RecordsetClone.Fields("A3").Value
objFrm.cmbAntworten.AddItem _
Me.RecordsetClone.Fields("A4").Value
objFrm.cmbAntworten.AddItem _
Me.RecordsetClone.Fields("A5").Value
End Sub
Private Sub Form_Load()
Dim lngZahl As Long
If Me.Filter = "" Then
'Zufallszahl ermitteln
lngZahl = getZZ()
Me.Filter = "ID=" & lngZahl
Me.FilterOn = True
End If
End Sub
Private Sub Form_Close()
Me.Filter = ""
Me.FilterOn = False
End Sub

Das Formular optimieren

Ganz optimal ist das Formular aber noch nicht. Sie sollten für beide Formulare die Scrollleisten, Trennlinien, Navigationsschaltflächen und so weiter ausblenden. Das ist vor allem für das übergeordnete Formular frmUmfragen notwendig, sonst kann sich der Benutzer nämlich durch die Umfragen bewegen und auch in Umfragen abstimmen, die vielleicht schon abgeschlossen oder nicht für diesen Benutzer bestimmt sind.

Welche Umfrage angezeigt werden soll, können Sie festlegen, indem Sie beim Aufruf des Formulars über das DoCmd-Objekt einen entsprechenden Filter-Ausdruck übergeben, wie dies die Prozedur Umfrageanzeigen in Listing 3 zeigt. Hier wird die Umfrage mit der ID 22 angezeigt.

Sub Umfrageanzeigen()
DoCmd.OpenForm "frmUmfragen", acNormal, , "Umfrage=22"
End Sub
Sub UmfrageAuswertung()
DoCmd.OpenForm "frmUmfrageErgebnis", acNormal, , "Umfrage=23"
End Sub

Alternativ können Sie natürlich auch eine Umfrage zufällig auswählen. Auch beides zu kombinieren ist kein Problem. Innerhalb des Formulars prüfen Sie dazu einfach in der Ereignisprozedur für das Load-Ereignis des Formulars (Listing 2), ob die Filter-Eigenschaft eine leere Zeichenfolge enthält. Wenn ja, wurde kein Filterausdruck übergeben und Sie können eine Zufallszahl berechnen und verwenden. Dazu rufen Sie einfach die Funktion getZZ auf. Sie ist in einem normalen Modul der Datenbank definiert (Listing 4) und berechnet eine Zufallszahl. Dabei berücksichtigt die Funktion die ID der ersten und der letzten Umfrage als Grenzwerte, so dass bei fortlaufenden Nummern immer eine gültige ID zurückgegeben wird. Wichtig ist aber, dass Sie nach Zuweisung des Filterausdrucks an die Filter-Eigenschaft die FilterOn-Eigenschaft auf True setzen, damit der Filter aktiviert wird.

Function getZZ() As Long
'Ermittelt eine Zufallszahl zwischen
'der ersten und letzten ID der Umfragen
Dim lngZahl As Long
Dim lngMin As Long
Dim lngMax As Long
lngMin = DMin("ID", "tabUmfragen")
lngMax = DMax("ID", "tabUmfragen")
Do
lngZahl = CLng(Rnd() * 100)
Loop Until (lngZahl >= lngMin) And (lngZahl <= lngMax)
getZZ = lngZahl
End Function

Damit das auch noch funktioniert, wenn Sie das Formular zum zweiten Mal aufrufen, sollten Sie in der Ereignisprozedur für das Ereignis Beim Schließen die Filter-Eigenschaft wieder auf eine leere Zeichenfolge setzen und die FilterOn-Eigenschaft auf False zurücksetzen (Listing 2).

Umfrageergebnisse auswerten

Die Auswertung einer Umfrage ist im Prinzip ganz einfach. Sie benötigen dazu nur eine Abfrage abfUmfrageErgebnis, die für jeden möglichen Wert der Umfrage deren Anzahl berechnet. Sie gruppieren dazu einfach nach der Antwort und berechnen mit der Count-Funktion deren Anzahl. Für eine optimale Ausgabe ist es allerdings ganz gut, wenn Sie auch noch das Feld Antwort ausgeben. Die SQL-Anweisung für die Abfrage könnte wie in Listing 5 aussehen.

SELECT Count(tabUmfragenErgebnisse.Antwort) AS Wert,
tabUmfragenErgebnisse.Antwort, tabUmfragenErgebnisse.Umfrage
FROM tabUmfragenErgebnisse
GROUP BY tabUmfragenErgebnisse.Antwort, tabUmfragenErgebnisse.Umfrage;

Diese SQL-Anweisung verwenden Sie als Basis für ein Formular. Gerade wenn Sie die Umfrage als Diagramm darstellen möchten, ist es sinnvoll, den Formularassistenten Diagramm- Assistent zu verwenden, indem Sie im Datenbankfenster in der Kategorie Vorlagen auf Neu klicken und in der Liste des Dialogfeldes auf Diagramm-Assistent. Aus der Pulldownliste des Dialogfeldes wählen Sie die eben erstellte Abfrage als Datenquelle aus. Mit Hilfe des Assistenten, der nach Klicken auf Weiter startet, können Sie dann die Umfrageergebnisse als Diagramm präsentieren.

Bei Bedarf können Sie das Diagramm später noch in der Entwurfsansicht anpassen. Bevor Sie das Formular jedoch nutzen können, sind noch ein paar Anpassungen erforderlich.

Ereignisprozedur erstellen

Außerdem sollten Sie eine Ereignisprozedur für das Ereignis Beim Laden des Formulars erstellen. In dieser Ereignisprozedur weisen Sie dem Diagramm eine neue SQL-Anweisung als Datenquelle zu. Das ist wichtig, damit Sie auch für das Diagramm die Filter-Bedingung berücksichtigen, die Sie beim Aufruf an das Formular übergeben. Dazu weisen Sie dem Diagramm über die RowSource-Eigenschaft die Datenquelle zu. Die Requery-Methode sorgt dafür, dass die Datenquelle für das Diagramm neu gelesen wird, und mit der SetFocus-Methode legen Sie fest, dass das Diagramm den Fokus bekommt. Implizit ist damit gewährleistet, dass das Diagramm bei Bedarf neu gezeichnet wird.

Beim Aufruf des Formulars müssen Sie noch eine Filterbedingung übergeben, die festlegt, zu welcher Umfrage die Ergebnisse angezeigt werden. Dazu können Sie eine Prozedur Umfrage-Auswertung wie die in Listing 3 erstellen.

Beim Schließen des Formulars sollten Sie noch dafür sorgen, dass der Filter wieder deaktiviert wird. Dazu erstellen Sie eine Ereignisprozedur für das Ereignis Beim Schließen des Formulars (Listing 6).

Bild 6: Auswertung der Umfrage.

Private Sub Form_Load()
Me.objDiagramm.RowSource = _
& "SELECT Antwort, Sum(Wert) AS SummeVonWert FROM " & _
"abfUmfrageErgebnis WHERE " & Me.Filter & " GROUP BY Antwort;"
Me.objDiagramm.Requery
Me.objDiagramm.SetFocus
End Sub
Private Sub Form_Close()
Me.Filter = ""
Me.FilterOn = False
End Sub

Umfrage beim Start der Anwendung anzeigen

Wenn Sie möchten, können Sie jetzt noch beim Start der Datenbank eine zufällige Umfrage anzeigen lassen. Dazu legen Sie das Formular frmUmfragen über Extras/Start als Startformular fest.

Wie geht es weiter?

Nachdem die Umfragen nun schon funktionieren und gespeichert und ausgewertet werden können, beschäftigen sich die nächsten beiden Teile der Artikelfolge mit dem Multiple-Choice-Test. Der ist wesentlich komplexer. Der zweite Teil der Artikelfolge zeigt, wie Sie die Fragen anzeigen und die Antworten des Benutzers speichern. Im letzten Teil erfahren Sie dann, welche Möglichkeiten zur Auswertung Sie für Multiple-Choice-Tests haben.