Zur Hauptseite ... Zum Onlinearchiv ... Zum Abonnement ... Zum Newsletter ... Zu den Tools ... Zum Impressum ... Zum Login ...

Gedrucktes Heft

Diesen Beitrag finden Sie in Ausgabe 4/2003.

Unser Angebot für Sie!

Lesen Sie diesen Beitrag und 500 andere sofort im Onlinearchiv, und erhalten Sie alle zwei Monate brandheißes Access-Know-how auf 72 gedruckten Seiten! Plus attraktive Präsente, zum Beispiel das bald erscheinende Buch 'Access 2010 - Das Grundlagenbuch für Entwickler'!

Diesen Beitrag twittern

Schulungen und Kurse verwalten (Teil 2)

Mit den Anleitungen des ersten Teils dieses Beitrags aus der letzten Ausgabe können Sie eine Schulungsverwaltung erstellen, mit der Schulungsprogramme sowie die angemeldeten Teilnehmer und deren Abschlüsse verwaltet werden. In dieser Ausgabe lernen Sie, wie Sie die Software um eine Raum- und Kursleiterplanung erweitern können. Außerdem erfahren Sie, wie Sie ein Auswahlformular zum Druck von Stunden- und Raumbelegungsplänen entwerfen können.

Raum- und Kursleiterplanung

In der bisherigen Version der Kursverwaltung können Sie zu jedem Kurs mehrere Starttermine jeweils mit einem Kursleiter und einer Raumnummer angeben. Pro Termin lassen sich dabei mehrere Kurseinheiten mit Start- und Enddatum erfassen (s. Abb. 1).

Abb. 1: Alte Version der Kursverwaltung

Mit dieser Variante haben Sie programmtechnisch aber nicht die Möglichkeit zu prüfen, ob für eine angegebene Kurseinheit der gewählte Raum bzw. Kursleiter frei ist.

Folglich kann es passieren, dass Räume doppelt belegt werden oder Kursleiter zwei Kurse gleichzeitig halten müssten.

Anpassung der Datenstruktur

Um einen Prüfmechanismus einbauen zu können, ergänzen Sie die Datenstruktur so, dass zusätzlich zu jeder in der Tabelle tblTermindetails gespeicherten Kurseinheit der Raum und der Kursleiter gespeichert werden.

Fügen Sie dazu in der Tabelle tblTermindetails die Felder RaumID und KursleiterID ein.

Verknüpfen Sie anschließend die Felder mit den entsprechenden Primärschlüsseln der Tabellen tblRaeume und tblKursleiter unter Verwendung der referenziellen Integrität.

Abb. 2 zeigt die neue Datenstruktur für den entsprechenden Teilbereich.

Das neue Formular
frmTermineBearbeiten

Abb. 2: Neue Datenstruktur für die Kursverwaltung

Abb. 3: Das neue Formular frmTermineBearbeiten

Im nächsten Schritt passen Sie zunächst das Unterformular frmTerminDetails an. Fügen Sie dazu die zwei Kombinationsfelder KursleiterID und RaumID ein, über die die Auswahl des Kursleiters und des Raumes zu einer Kurseinheit erfolgt.

Praxis-Tipp

Am einfachsten erstellen Sie die Kombinationsfelder, indem Sie diese aus dem Formular frmTermineBearbeiten kopieren. Die Kombinationsfelder sind absolut identisch und das Anlegen ist mit nur zwei Mausklicks erledigt. (

Nun ordnen Sie die Steuerelemente im Formular frmTermineBearbeiten noch neu an. Verbreitern Sie das Unterformular-Steuerelement, damit die neuen Felder in der Liste sichtbar sind, und platzieren Sie die Schaltflächen unterhalb der Liste. Das neue Formular könnte wie in Abb. 3 gezeigt aussehen.

Verfügbarkeit prüfen

Die Verfügbarkeit eines Raumes oder Kursleiters kann jetzt für jede Kurseinheit separat geprüft werden. Die Überprüfung erfolgt an zwei Stellen: zum einen in der Prozedur TermindetailsAnlegen, die über die Schaltfläche Einheiten anlegen aufgerufen wird und in einem Schritt mehrere Kurseinheiten einfügt; zum anderen nach der manuellen Änderung von Werten direkt in den Kombinationsfeldern für den Raum und den Kursleiter.

Hinweis

Die Prüfmechanismen werden im Folgenden nur noch für Räume beschrieben, da sie mit denen für Kursleiter identisch sind. Dabei muss lediglich das Feld RaumID durch das Feld KursleiterID ersetzt werden. (

Der Prüfmechanismus

Die eigentliche Verfügbarkeitsprüfung erfolgt über die Funktion IstRaumVerfügbar (s. Quellcode 1). Der Funktion werden die Raumnummer und der zu prüfende Zeitraum mit Start- und Enddatum übergeben.

Public Function IstRaumVerfügbar(RaumID, Startdatum, Enddatum) As Boolean

    Dim WhereKlausel As String

    If IsNull(Startdatum) Or IsNull(Enddatum) Then

        IstRaumVerfügbar = False

    Else

        WhereKlausel = "RaumID = " & Nz(RaumID, 0) _

            & " AND ((" & SQLDatum(Startdatum) _
            & " Between DateAdd(""s"",1,[Startdatum]) " _
            & "And DateAdd(""s"",-1,[Enddatum]))" _

            & " OR (" & SQLDatum(Enddatum) & " Between " _
            & "DateAdd(""s"",1,[Startdatum]) And DateAdd(""s"",-1,[Enddatum]))" _
            & " OR (" & SQLDatum(Startdatum) & "=[Startdatum])" _

            & " OR (" & SQLDatum(Enddatum) & "=[Enddatum]))"

        If IsNull(DLookup("TermindetailID", "tblTermindetails", WhereKlausel)) Then

            IstRaumVerfügbar = True

        Else

            IstRaumVerfügbar = False

        End If

    End If

End Function

Quellcode 1

Die Besonderheit liegt bei der Datumsbetrachtung. Die Prozedur schaut in der Tabelle tblTermindetails nach, ob das zu prüfende Start- bzw. Enddatum für die angegebene Raumnummer bereits innerhalb eines anderen in der Tabelle gespeicherten Zeitraums liegt. Der folgende Ausdruck dient dabei (exemplarisch für das Startdatum) als Bedingung:

SQLDatum(Startdatum) & " Between DateAdd("s",1,[Startdatum]) And DateAdd("s",-1,[Enddatum])"

In der Bedingung werden nicht die exakten Datumswerte geprüft, da sonst ein Kurs, der um 14:00 Uhr endet, mit einem zu prüfenden Kurs, der um 14:00 Uhr beginnt, zusammenfallen würde.

Die Abfrage würde dann als Ergebnis liefern, dass um 14:00 Uhr bereits ein Kurs vorhanden ist. Um das zu vermeiden, wird beim Startdatum eine Sekunde addiert und beim Enddatum eine Sekunde subtrahiert.

Folglich würde der Kurs, der um 14:00 Uhr endet, mit dem Wert 13:59:59 Uhr geprüft.

Hinweis

Alternativ zur DateAdd-Funktion können Sie auch mit Größer- und Kleiner-Zeichen arbeiten. Die Bedingung sähe dann wie folgt aus:

Hinweis

SQLDatum(Startdatum) & ">Startdatum And " & SQLDatum(Startdatum) & "<Enddatum" (

Ferner prüft die gesamte Bedingung, ob Start- oder Enddatum für den Raum schon vorhanden sind. Diese Fälle müssen ebenfalls ausgeschlossen werden.

Liefert die Gesamtbedingung für die Tabelle tblTermindetails keine Ergebnisse zurück, dann ist der Raum verfügbar.

Einbau in die Funktion TermindetailsAnlegen

Die Funktion IstRaumVerfügbar kann jetzt beim Anlegen von Kurseinheiten mittels der Funktion TermindetailsAnlegen eingesetzt werden. Über die Abfrage aus Quellcode 2 wird zunächst die Raumnummer ermittelt, die beim Anlegen einer neuen Kurseinheit verwendet werden soll.

If IstRaumVerfügbar(RaumID, MyStartdatum, MyEnddatum) = False Then

    MyRaumID = "Null"

    RaumErrorstring = RaumErrorstring & MyStartdatum & " - " & MyEnddatum & vbCrLf

Else

    MyRaumID = RaumID

End If

Quellcode 2

Errorstring = ""

If RaumErrorstring <> "" Then

    Errorstring = Errorstring & "Bei den folgenden Kursentermine konnte kein " & _

    "Raum angelegt werden, da der vorgegebene Raum bereits belegt war:"

    Errorstring = Errorstring & vbCrLf & vbCrLf & RaumErrorstring & vbCrLf & vbCrLf

End If

If KursleiterErrorstring <> "" Then

    Errorstring = Errorstring & "Bei den folgenden Kursentermine konnte kein " & _

    "Kursleiter angelegt werden, da der vorgegebene Kursleiter bereits einen " & _
    "anderen Kurs hat:"

    Errorstring = Errorstring & vbCrLf & vbCrLf & KursleiterErrorstring

End If

If Errorstring <> "" Then

    MsgBox Errorstring, vbOKOnly + vbExclamation, "Fehler..."

End If

Quellcode 3

Wenn der Raum verfügbar ist, wird die RaumID verwendet, die bei den Termindaten als Standard definiert wurde. Im anderen Fall setzt die Prozedur den Wert auf Null. Der Raum wird also freigelassen. Außerdem merkt sich die Prozedur den geprüften Zeitraum in der Variablen RaumErrorstring, um dem Anwender nach Anlage aller Kurseinheiten eine Übersicht über die Kurse zu geben, für die der Standardraum nicht festgelegt werden konnte.

Diese Meldung wird wie folgt zusammengesetzt und zeigt zusätzlich die Kursleiter an, die nicht eingefügt werden konnten (s. Quellcode 3).

Abb. 4: Fehlermeldung beim automatischen Anlegen von Kurseinheiten

Abb. 4 zeigt eine solche Fehlermeldung. Dabei wurden die Kurseinheiten einfach doppelt angelegt, ohne die schon bestehenden vorher zu löschen.

Prüfen bei Änderung von Kursdaten

Abb. 5: Fehlermeldung bei manueller Eingabe von Kurseinheiten

Abb. 6: Tabellenstruktur für die Abfrage qryWochenplanDrucken

If IstRaumVerfügbar(Me!RaumID, Me!Startdatum, _
    Me!Enddatum) = False Then

    MsgBox "Der ausgewählte Raum ist zum angegebenen " _
        & "Zeitraum bereits besetzt. Bitte wählen " _
        & "Sie einen anderen Raum aus.", _

        vbOKOnly + vbExclamation, "Fehler..."

    Cancel = True

End If

Quellcode 4

Da im Terminformular die Kurseinheiten nachträglich vom Anwender verändert oder auch komplett manuell eingegeben werden können, müssen Sie die Verfügbarkeit auch im Formular frmTermindetails abprüfen.

Verwenden Sie dazu das Ereignis Vor Aktualisierung des Kombinationsfeldes RaumID, um ggf. eine ungültige Eingabe per Programm abzubrechen.

Die Ereignisprozedur prüft erst, ob Start- und Enddatum eingegeben sind. Fehlt einer der beiden Werte, kann die Verfügbarkeit nicht ermittelt werden und die Prozedur bricht die Eingabe mit einem Hinweis für den Anwender ab.

Sind beide Datumswerte vorhanden, verwendet die Prozedur wieder die Funktion IstRaumVerfügbar.

Falls der eingegebene Raum nicht verfügbar ist, erhält der Anwender eine Meldung und die Eingabe wird mit dem Ausdruck Cancel=True abgebrochen (s. Abb. 5).

Wochenpläne
drucken

Nachdem Sie die Erfassung der Kurseinheiten nun vervollständigt haben, können Sie auf Basis der Kursdaten sowohl Wochenpläne für die Kursleiter als auch Raumbelegungspläne drucken.

Beide Berichte basieren auf den gleichen Daten, lediglich die Anordnung der Steuerelemente und die Gruppierung ist eine andere.

Die Datenquelle für die Berichte

Erstellen Sie zunächst die Basisabfrage für die Berichte. Die Abfrage verwendet die in Abb. 6 gezeigten Tabellen.

Die folgenden Felder werden benötigt: RaumID und -name, KursleiterID und -name, Start- und Enddatum sowie die Kursnummer und
-bezeichnung.

Abb. 7: Der Wochenbericht in der Entwurfsansicht

Zusätzlich enthält die Abfrage drei berechnete Felder. Das Feld AnzahlTeilnehmer ermittelt mit der bereits bekannten Funktion GetAnzahlAngemeldeteTeilnehmer die Anzahl der angemeldeten Teilnehmer für einen Kurs:

AnzahlTeilnehmer: GetAnzahlAngemeldeteTeilnehmer([tblTermindetails].[TerminID])

Die Felder Kalenderwoche und KalenderwocheJahr werden zur Filterung benötigt.

Kalenderwoche: Format([tblTermindetails].[Startdatum];"ww")

KalenderwocheJahr: Jahr([tblTermindetails].[Startdatum])

Über diese Felder können Sie später gezielt eine Woche oder einen Wochenbereich auswählen. Die fertige Abfrage finden Sie in der Musterlösung unter dem Namen qryWochenplanDrucken.

Erstellen der Berichte

Als Nächstes entwerfen Sie die Berichte auf Basis der eben erstellen Abfrage qryWochenplanDrucken.

Wochenplan für Kursleiter

Legen Sie für den Wochenplan einen Bericht an, den Sie nach den Feldern Leiter, Woche von Startdatum und Tag von Startdatum gruppieren, um eine wöchentliche Auswertung pro Kursleiter zu erhalten. Im Detailbereich fügen Sie die Felder Kursnummer, Kursbezeichnung, Raumnummer und AnzahlTeilnehmer ein.

Die Uhrzeit der Kurseinheit ermitteln Sie aus dem Start- und Enddatum mit dem folgenden Ausdruck:

=Format([Startdatum];"hh:nn") & " - " & Format([Enddatum];"hh:nn")

Legen Sie ein Textfeld mit dem Namen txtZeitraum an und tragen Sie den Ausdruck bei der Eigenschaft Steuerelementinhalt ein.

Den fertigen Bericht repWochenplanDrucken_Kursleiter sehen Sie in Abb. 7 in der Entwurfsansicht.

Raumbelegungsplan

Den Bericht für die Raumbelegung können Sie aufgrund der gleichen Datenbasis beider Berichte einfach kopieren.

Speichern Sie den Bericht repWochenplanDrucken_Kursleiter unter dem Namen repWochenplanDrucken_Raeume ab. Ändern Sie dann die erste Gruppierung von Leiter in Raumnummer und passen Sie den Text im Gruppierungsbereich an. Zum Schluss müssen Sie nur noch im Detailbereich das Feld Raumnummer gegen Leitername austauschen.

Das Auswahlformular

Damit der Anwender die Wochenpläne komfortabel aufrufen kann, erstellen Sie ein Formular, über das vor dem Öffnen des Berichts der Zeitraum und der Kursleiter bzw. die Raumnummer ausgewählt werden können.

Das Formular frmWochenplanDrucken ist in Abb. 8 dargestellt. Es ist in drei Bereiche aufgeteilt. Über den ersten Bereich erfolgt die Auswahl des Zeitraums mittels Jahr und Kalenderwoche. Im zweiten Bereich können Sie einen Kursleiter wählen und die zugehörigen Wochenpläne drucken, während der dritte Bereich dem Druck der Raumbelegungspläne dient.

Sub JahreslisteFuellen()

    Me!cmbJahr.RowSource = GetJahresliste()

    Me!cmbJahr.Requery

    Me!cmbJahr = Year(Date)

End Sub

Quellcode 5

Function GetJahresliste() As String

    Dim i As Integer

    Dim Jahresliste As String

    For i = Year(Date) - 20 To Year(Date) + 5

        Jahresliste = Jahresliste & CStr(i) & ";"

    Next i

    GetJahresliste = Jahresliste

End Function

Quellcode 6

Datumsauswahl

Die Auswahl des Zeitraums erfolgt über drei Kombinationsfelder. Alle Felder werden vom Programm automatisch beim Öffnen des Formulars jeweils mit einer Werteliste gefüllt.

Das Füllen des Kombinationsfeldes zur Auswahl des Jahres erfolgt mittels der Funktion JahreslisteFuellen (s. Quellcode 5).

Die Prozedur setzt über die Funktion GetJahresliste (s. Quellcode 6) die Werteliste zusammen, weist sie dem Kombinationsfeld zu und fragt es neu ab. Anschließend wird noch das aktuelle Jahr im Formular angezeigt.

Die Werteliste wird über eine For Next-Schleife in der Funktion GetJahresliste zusammengefügt. Dabei werden rückwirkend die letzten 20 Jahre genauso wie die nächsten fünf Jahre berücksichtigt.

Abb. 8: Das Auswahlformular frmWochenplanDrucken

Die Einschränkung des Zeitraums erfolgt weiter durch die Kombinationsfelder zur Auswahl der Kalenderwochen. Die Zusammenstellung der Wertelisten für diese Kombinationsfelder ist prinzipiell mit der für die Jahre identisch.

In einer Schleife werden die Zahlen 1 bis 52 mit Semikolon getrennt zur Werteliste zusammengefügt.

Allerdings sollen zusätzlich zur Kalenderwoche auch die genauen Daten der Woche im folgenden Format angezeigt werden:

25 (16.06.2003 - 22.06.2003)

Leider bietet Access keine eingebaute Funktion, um für eine Kalenderwoche das Datum eines bestimmten Tages der Woche auszugeben - für den vorliegenden Fall den Montag. Deshalb benötigen Sie eine eigene Funktion, die diese Aufgabe erledigt. Die Funktion hat den Namen GetKWMontag (Quellcode 7).

Public Function GetKWMontag(MyKW, MyJahr)

    Dim Wochendatum As Variant

    Dim Wochentag As Variant

    Wochendatum = DateSerial(MyJahr, 1, 1) + 7 * (MyKW - 1)

    Wochentag = WeekDay(Wochendatum, vbMonday)

    GetKWMontag = Wochendatum - Wochentag + 1

End Function

Quellcode 7

For i = 1 To 52

    Wochentag = GetKWMontag(i, Nz(Me!cmbJahr, Date))

    KWliste = KWliste & CStr(i) & ";" & CStr(i) & _

        " (" & Wochentag & "-" & DateAdd("d", 6, Wochentag) & ");"

Next i

Quellcode 8

Sub KWlistenFuellen()

    Me!cmbKWVon.RowSource = GetKWListe()

    Me!cmbKWVon.Requery

    Me!cmbKWVon = Format(Date, "ww")

    Me!cmbKWBis.RowSource = GetKWListe()

    Me!cmbKWBis.Requery

    Me!cmbKWBis = Format(Date, "ww")

End Sub

Quellcode 9

Als Übergabeparameter erwartet die Funktion eine Kalenderwoche und eine Jahreszahl. Mit diesen beiden Parametern berechnet die Funktion zunächst einen beliebigen Tag in der angegebenen Woche, ausgehend vom 01.01. des gewünschten Jahres.

Anschließend ermittelt die Funktion den Wochentag des zuvor berechneten Datums. Nachdem ein Datum der Woche und der Wochentag bekannt sind, müssen Sie zur Bestimmung des Montags-Datums lediglich beide Werte voneinander subtrahieren.

Die Funktion GetKWMontag verwenden Sie jetzt, um die Werteliste nach dem gewünschten Muster zusammenzustellen. Die Funktion GetKWListe erstellt in einer Schleife eine zweispaltige Werteliste. Pro Kalenderwoche bestimmt die Funktion das Montags-Datum der Woche und fügt es zusammen mit dem Sonntags-Datum in die Liste ein (s. Quellcode 8).

Zum Schluss müssen Sie noch die Werteliste den beiden Kombinationsfeldern cmbKWVon und cmbKWBis zuweisen und die aktuelle Woche einstellen (s. Quellcode 9).

Kursplan drucken

Die Auswahl des Kursleiters, für den Sie Wochenpläne drucken möchten, erfolgt über ein Kombinationsfeld, in dem alle Kursleiter alphabetisch aufgelistet sind.

Wenn kein Kursleiter ausgewählt worden ist, werden alle Kursleiter im Bericht ausgegeben (s. Abb. 9).

Damit der Anwender das Kombinationsfeld nicht manuell leeren muss, befindet sich auf dem Formular die Schaltfläche btnAlleKursleiter. Die Ereignisprozedur löscht den Inhalt des Kombinationsfeldes und besteht nur aus einer Zeile:

Me!cmbKursleiter = Null

Abb. 9: Drucken der Wochenpläne

Private Sub btnKursplanDrucken_Click()

    Dim SQL As String

    If IsNull(Me!cmbJahr) Or IsNull(Me!cmbKWVon) Or IsNull(Me!cmbKWBis) Then

        MsgBox "Bitte füllen SIe die Felder Jahr, Von KW und Bis KW aus.", _

                vbOKOnly + vbInformation, "Fehler..."

    Else

        If IsNull(Me!cmbKursleiter) Then

            SQL = "KursleiterID Is Not Null AND Kalenderwoche Between " & _

                  Me!cmbKWVon & " And " & Me!cmbKWBis & _

                  " AND Kalenderwochejahr=" & Me!cmbJahr

        Else

            SQL = "KursleiterID=" & Me!cmbKursleiter & _

                  " AND Kalenderwoche Between " & Me!cmbKWVon & " And " & _

                  Me!cmbKWBis & " AND Kalenderwochejahr=" & Me!cmbJahr

        End If

        DoCmd.OpenReport "repWochenplanDrucken_Kursleiter", acViewPreview, , SQL

    End If

End Sub

Quellcode 10

Abb. 10: Wochenplan für einen Kursleiter

Die Prozedur prüft zunächst, ob alle Felder zur Bestimmung des Zeitraums ausgefüllt sind. Anschließend wird, abhängig vom Inhalt des Kombinationsfeldes, die Bedingung für den Bericht zusammengesetzt. Wenn ein Kursleiter ausgewählt ist, wird über die KursleiterID gefiltert, damit nur der gewählte Leiter berücksichtigt wird. Im anderen Fall werden alle Kurseinheiten ausgegeben, bei denen ein beliebiger Kursleiter eingetragen ist. Den Druck startet der Anwender über die Schaltfläche btnKursplanDrucken. Die Ereignisprozedur der Schaltfläche ist in Quellcode 10 abgebildet.

Abb. 11 zeigt beispielhaft einen Wochenplan über mehrere Kalenderwochen für einen Kursleiter.

Raumbelegungsplan drucken

Der Druck der Raumbelegungspläne ist mit dem Druck der Wochenpläne nahezu identisch. Die Auswahl erfolgt wieder über ein Kombinationsfeld, in dem alle Raumnummern aufgeführt werden (s. Abb. 12). Außerdem können Sie den Belegungsplan entweder für einen Raum oder für alle Räume drucken.

Für die Ausgabe wird der Bericht repWochenplanDrucken_Raeume verwendet. Ein mögliches Ergebnis sehen Sie in Abb. 13.

Abb. 11: Wochenplan für einen Schulungsleiter

Abb. 12: Drucken der Raumbelegung

Zusammenfassung

In diesem Beitrag haben Sie die Schulungsverwaltung um eine Raum- und Kursleiterplanung ergänzt. Der Schwerpunkt lag dabei auf der Prüfung der Verfügbarkeit eines Raumes bzw. Kursleiters, um Doppelbuchungen zu vermeiden.

Abb. 13: Belegungsplan für den Raum 7B01

Ferner haben Sie aufbauend auf dem neuen Datenmodell ein Formular zum Druck von Stundenplänen für Kursleiter und Raumbelegungsplänen entwickelt, über das sich ein Kursleiter schnell die benötigten Informationen zusammenstellen kann.

Ausblick

Neben den hier beschriebenen Ergänzungen können insbesondere Auswertungen zusätzlich in die Software integriert werden. So ist zum Beispiel eine Auslastungsübersicht wünschenswert, bei der alle Kurse mit Teilnehmerzahl, Verhältnis der Zahl der Teilnehmer zur maximalen Teilnehmerzahl und der durchschnittlichen Teilnehmerzahl pro Kurs aufgeführt werden.

Ebenso wichtig ist eine Erfolgsübersicht, in der Sie sich die Kursliste eines Mitarbeiters mit Durchschnittsnote und der Erfolgsquote (Bestanden/nicht bestanden) ausgeben lassen können.

Download

Download

Die .zip-Datei enthält folgende Dateien:

Schulungsverwaltung2_97.mdb

Schulungsverwaltung2_00.mdb

Beispieldateien downloaden

© 2003-2018 André Minhorst Alle Rechte vorbehalten.