Rezepte verwalten mit Access

André Minhorst, Duisburg

Verwalten von Rezepten – das hört sich gar nicht nach einer Musterlösung für Unternehmen an. Oder sind nur Hotelköche angesprochen Nein. Neben dem Anspruch, ein Muster für eine Vielzahl von Anwendungen zu bieten, soll die vorliegende Musterlösung auch von einer Vielzahl von Anwendern auf ihre eigenen Bedürfnisse zugeschnitten werden können.

Schließlich gibt es zu vielen Tätigkeiten „Rezepte“ bzw. Verfahrensvorschriften, deren Durchführung auch noch die Verwendung bestimmter Zutaten – z. B. bestimmter Formulare – erfordert.

Neben der Verwaltung von Rezepten, Zutaten usw. werden Sie hier mit der Programmierung einer Schnittstelle konfrontiert. Diese dient dem Einlesen von fertigen Rezepten, von denen es im Internet Tausende gibt.

Wenn Sie sich z. B. einmal unter dem Stichwort Meal-Master die in Google registrierten deutschsprachigen Seiten ausgeben lassen, finden Sie zurzeit etwa 1.200 Einträge. Von vielen Seiten können Sie Dateien herunterladen, die teilweise hunderte von Rezepten enthalten.

Meal-Master ist ein amerikanisches Programm zur Verwaltung von Rezepten, das ein international anerkanntes Format für den Austausch von Rezepten enthält – die meisten verfügbaren Rezeptverwaltungen besitzen eine Funktion für den Import dieses Formats.

In diesem Zusammenhang lernen Sie auch, wie Sie mit einer Schnittstelle Daten von anderen Anwendungen in Ihre Datenbank importieren können. Der hier vorgestellte Vorgang lässt sich allerdings nicht mit denjenigen Assistenten vergleichen, die beispielsweise den Import von Daten aus Excel- oder CSV-Dateien erleichtern. Vielmehr zeigt dieser Beitrag, wie Daten in eine komplexe Datenstruktur eingearbeitet werden können.

Die Rezeptverwaltung soll neben ihrer eigentlichen Aufgabe, der Verwaltung von Rezepten, auch den Import und Export im Meal-Master-Format erlauben. Daher berücksichtigt das Datenmodell auch dessen weltweit gültiges Format, das in den folgenden Abschnitten kurz vorgestellt werden soll.

Das Meal-Master-Format

Meal-Master verwendet herkömmliche Textdateien. Es gibt eine genaue Spezifikation zur Festlegung der einzelnen Abschnitte eines Rezeptes. Ein Rezept besteht demnach aus den folgenden Angaben:

  • Rezeptname
  • Kategorien
  • Anzahl der Portionen
  • Zutaten mit Einheit und Anzahl
  • Anleitung
  • Aus diesen Informationen können Sie das Datenmodell zur Abbildung der Rezepte in einem relationalen Datenbanksystem – wie es Access ist – direkt ableiten.

    Abb. 1: Datenmodell der Rezeptverwaltung

    Das Rezept als Hauptobjekt des Datenmodells benötigt eine eigene Tabelle zur Speicherung der rezeptspezifischen Daten. In diese Tabelle gehören der Rezeptname, die Anzahl der Portionen und die Anleitung – Informationen, die für jedes Rezept genau einmal auftauchen.

    Anders verhält es sich mit den Kategorien und Zutaten: Jedes Rezept kann einer oder mehreren Kategorien zugeordnet werden und für jedes Rezept benötigen Sie in der Regel mehrere Zutaten.

    Das gilt in beiden Fällen sicher auch umgekehrt: Sie ordnen jeder Kategorie ein oder mehrere Rezepte zu und auch jede Zutat taucht in einem oder in mehreren Rezepten auf.

    Sie benötigen also zwei m:n-Beziehungen – sowohl zwischen Rezepten und Kategorien als auch zwischen Rezepten und Zutaten.

    Die erste Beziehung realisieren Sie mit einer einfachen Verknüpfungstabelle. Die zweite zwischen Rezepten und Zutaten ist etwas komplizierter. Hier müssen Sie zusätzlich noch Informationen über Einheit und Anzahl der Zutaten hinzufügen.

    Da diese Informationen sich unter Umständen bei jeder Kombination aus Rezepten und Zutaten unterscheiden, können Sie diese nur in der Verknüpfungstabelle zwischen den Tabellen der Rezepte und der Zutaten unterbringen.

    Die Tabelle tblRezepte

    Der Rezeptname, die Anleitung und die Anzahl der Portionen für die angegebenen Zutatenmengen speichern Sie in einer Tabelle namens tblRezepte. Da die Anleitung vermutlich oft länger als 255 Zeichen ist, verwenden Sie für diese Information ein Memo-Feld.

    Die Tabelle tblZutaten

    Alle in der Datenbank verwendeten Zutaten speichern Sie in der Tabelle tblZutaten. Neben der Bezeichnung der Zutat enthält die Tabelle ein Bemerkungsfeld.

    Die Tabelle tblKategorien

    Die Tabelle tblKategorien dient dem Speichern der Kategorien. Auch hier ist ein Bemerkungsfeld vorgesehen.

    Die Tabelle tblEinheiten

    Da es im Meal-Master-Format fest vorgegebene Einheiten gibt, die immer wieder auftauchen, sollen sie in einer separaten Tabelle gespeichert werden. Da die Bezeichnungen sich der Herkunft des Formats entsprechend auf amerikanische Einheiten beziehen, soll die Tabelle neben der englischen Bezeichnung auch noch eine deutsche Bezeichnung für die Ausgabe enthalten.

    Die TabelletblRezepteZutaten

    Diese Tabelle speichert alle Zuordnungen zwischen Rezepten und Zutaten. Zusätzlich soll die Tabelle zu jeder Zuordnung die Einheit, die Anzahl der Einheiten und Bemerkungen speichern. Die Einheiten werden als Zahlenwert eingegeben, der sich auf die verknüpfte Tabelle tblEinheiten bezieht.

    Abb. 2: Beispiel eines Rezeptes im Meal-Master-Format

    Die beiden Felder RezeptID und ZutatID dienen als Fremdschlüsselfelder zu den entsprechenden Tabellen. Sie bilden allerdings keinen gemeinsamen Primärschlüssel.

    Die Tabelle tblRezepteKategorien

    Die Tabelle zur Herstellung der Beziehung zwischen Rezepten und Kategorien ist eine einfache Verknüpfungstabelle mit den Fremdschlüsselfeldern RezeptID und KategorieID zu den Tabellen tblRezepte und tblKategorien.

    Die Beziehungen

    Die Beschreibung der verwendeten Tabellen enthält bereits die wichtigsten Informationen zu den Beziehungen zwischen den Tabellen. Abb. 1 zeigt eine Zusammenfassung der Tabellen und der Beziehungen zwischen den Tabellen. Für alle Beziehungen soll referentielle Integrität bestehen.

    Die Eingabe von Test- und anderen Daten ist in der Regel wenig unterhaltsam – zumindest, wenn Sie die Daten stur von einer Vorlage übernehmen müssen.

    Daher sorgen Sie nun zunächst einmal für eine Schnittstelle zum Import von bestehenden Daten im Meal-Master-Format.

    Hinweis

    Zwar ist auch das Erstellen von Schnittstellen nicht gerade beflügelnd, aber deren anschließende Anwendung und die daraus resultierende Zeitersparnis ist ein guter Grund, diese Arbeit in Kauf zu nehmen.

    Das Import-Format

    Die Dateien mit den Meal-Master-Rezepten sind reine Textdateien. Glücklicherweise haben Sie eine einigermaßen regelmäßige Struktur – was bei einem weltweit verwendeten Format vorausgesetzt werden kann. Die Frage, warum ein solch verbreitetes Format nicht auf dem Stand der Zeit ist – beispielsweise in Form einer XML-Datei -, ist wohl ebenfalls mit der weltweiten Verwendung und der Beliebtheit zu erklären. Je mehr Anwender mit einem Produkt arbeiten, desto mehr Widerstand regt sich gegen die Einführung neuer Standards.

    Eine Meal-Master-Datei besteht aus einem oder mehreren Rezepten, die untereinander in die Datei eingetragen sind. Jedes Rezept hat eine fest definierte erste und letzte Zeile. Die erste Zeile beginnt mit fünf großen M oder fünf Minuszeichen (-) und beinhaltet irgendwo dahinter die Zeichenfolge Meal-Master. Die letzte Zeile beginnt ebenso, ist aber nach diesen fünf Zeichen bereits zu Ende.

    Dazwischen befinden sich drei Abschnitte: Im ersten, fest definierten Teil stehen Angaben zum Namen des Rezepts, zur Anzahl der Portionen für die angegebene Menge Zutaten und zu den Kategorien, denen das Rezept zugeordnet werden kann.

    Im zweiten Teil befinden sich die Zutaten. Die Zutaten werden in ein oder zwei Spalten aufgelistet, wobei feste Bereiche der Zeile für die Informationen Menge, Einheit und Zutat vorgesehen sind.

    Der dritte Teil beinhaltet schließlich die eigentliche Anleitung. Abb. 2 zeigt ein Beispielrezept im Meal-Master-Format.

    Diese Darstellung kann als einfachste Ausführung eines Rezeptes in diesem Format angesehen werden. Umfangreichere Rezepte besitzen weitere Zeilen, die z. B. die Zutaten nach den einzelnen Bestandteilen des Rezeptes aufteilen oder die einfach als Kommentarzeilen – beispielsweise zur Angabe der Herkunft eines Rezeptes – dienen. Solche Besonderheiten spart die im Folgenden erstellte Import-Routine aus Gründen der übersichtlichkeit allerdings aus.

    Daten importieren

    Function RezepttexteEinlesen(Quelldatei As String)
        Dim Zeile As String
        Dim Rezepttext As String
        Dim Rezeptnummer As Integer
        Dim Zeilennummer As Integer
        Dim db As Database
        Dim rstRezepttexte As Recordset
        On Error GoTo RezepttexteEinlesen_Err
        Set db = CurrentDb
        Set rstRezepttexte = _        db.OpenRecordset("tblRezepttexte", _        dbOpenDynaset)
        Open Quelldatei For Input As #1
        Do While Not EOF(1)
            Line Input #1, Zeile
            If (Left(Zeile, 5) = "MMMMM" _            Or Left(Zeile, 5) = "-----") _            And InStr(1, Zeile, "Meal-Master") > 0 Then
                Zeilennummer = 1
                Rezeptnummer = Nz(DMax("Rezeptnummer", _                "tblRezepttexte"), 0) + 1
            End If
            rstRezepttexte.AddNew
            rstRezepttexte!Rezepttext = Zeile
            rstRezepttexte!Rezeptnummer = Rezeptnummer
            rstRezepttexte!Zeilennummer = Zeilennummer
            rstRezepttexte!EingelesenAm = Date
            rstRezepttexte.Update
            Zeilennummer = Zeilennummer + 1
        Loop
        Close #1
        Exit Sub
    RezepttexteEinlesen_Err:
        If Err.Number = 76 Then
            MsgBox "Die Datei konnte nicht gefunden " _            & "werden.", vbExclamation + vbOKOnly, _            "Dateifehler"
            Exit Function
        Else
            MsgBox "Fehler: " & Err.Number & " " _            & Err.Description
        End If
    End Function

    Quellcode 1

    Die übernahme von Daten aus Textdateien, die auf anderen Formaten als XML oder CSV basieren, bringt in der Regel Nacharbeit mit sich. Da die Dateien teilweise sehr große Mengen Rezepte enthalten – tausend und mehr sind keine Seltenheit -, soll die Datenbank den Inhalt der Datei zunächst einmal einlesen. Anschließend kann der Anwender dann bestimmen, welche Rezepte er in seine eigene Sammlung aufnehmen möchte.

    Für die Zwischenspeicherung der Daten benötigen Sie eine Tabelle namens tblRezepttexte. Die Tabelle speichert die Daten so lange, bis der Anwender sie in seine Sammlung übernimmt.

    Die Prozedur aus Quellcode 1 liest die Daten aus der Textdatei zeilenweise in die Tabelle tblRezepttexte ein.

    Nach dem Deklarieren und Initialisieren der Objektvariablen öffnet die Prozedur mit der Open-Anweisung die Datei mit dem in dem Parameter Quelldatei angegebenen Namen.

    Anschließend liest sie die Datei bis zum Erreichen des Dateiendes zeilenweise ein. Dabei berücksichtigt die Prozedur, ob ein neues Rezept beginnt, und setzt die Variable Rezeptnummer auf den Wert, der um 1 größer als der größte bisher vergebene Wert ist. Die Variable Zeilennummer wird mit jeder Zeile um 1 erhöht.

    Beide Variablen werden mit dem Inhalt der Zeile und dem Datum des Einlesens in je einem Datensatz für jede Zeile in der Tabelle tblRezepttexte gespeichert.

    Nach dem Einlesen ist kein weiterer Zugriff auf die Datei mehr erforderlich. Von nun an können alle benötigten Informationen zu den einzelnen Rezepten aus der Tabelle tblRezepttexte gelesen werden.

    Abb. 3: Formular zur übernahme von Rezepten

    Die Funktion beinhaltet eine kleine Fehlerbehandlung, die bei Nichtvorhandensein der Datei mit dem übergebenen Namen eine entsprechende Meldung ausgibt.

    Daten übernehmen

    Der Import von Daten ist mit dem Einlesen der Daten in die Tabelle tblRezepttexte abgeschlossen, da nunmehr kein weiterer Zugriff auf die verwendete Datei mehr erforderlich ist. Im weiteren Verlauf sollen die Daten allerdings noch in das beschriebene Datenmodell übernommen werden. Zur komfortablen Auswahl der gewünschten Rezepte und zur Einleitung der anschließenden Konvertierung der vorhandenen Daten in das Datenmodell verwenden Sie ein geeignetes Formular.

    Daten aus einer Textdatei in einer weiter verwertbaren Form in eine Datenbank zu bugsieren, ist keine besondere Kunst. Viel interessanter ist die übernahme der eingelesenen Daten in ein Datenmodell, das aufgrund seiner relationalen Struktur zwar wesentlich komplexer ist als der Ursprung der Daten, aber auch vielfältigere Möglichkeiten bietet.

    Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
    Hier geht es zur Bestellung des Jahresabonnements des Magazins Access im Unternehmen:
    Zur Bestellung ...
    Danach greifen Sie sofort auf alle rund 1.000 Artikel unseres Angebots zu - auch auf diesen hier!
    Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

    Schreibe einen Kommentar