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

Achtung: Dies ist nicht der vollständige Artikel, sondern nur ein paar Seiten davon. Wenn Sie hier nicht erfahren, was Sie wissen möchten, finden Sie am Ende Informationen darüber, wie Sie den ganzen Artikel lesen können.

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

Gedrucktes Heft

Diesen Beitrag finden Sie in Ausgabe 3/2005.

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

Artikelverwaltung mit Inventurfunktion, Teil 2

André Minhorst, Duisburg

Im ersten Teil dieser Beitragsreihe haben Sie das Datenmodell und die wesentlichen Formulare der Artikelverwaltung kennen gelernt. Nun beschäftigen Sie sich mit den Inventuren: Welche Faktoren sind dafür wichtig? Wie werden bereits in einer Inventur berücksichtigte Daten bei folgenden Inventuren ausgeschlossen? Außerdem erfahren Sie in dieser Folge, wie Sie Berichte für die Ausgabe von Artikel- und Inventurdaten erstellen.

Hinweis

Die Musterlösung zu diesem Beitrag heißt Artikelverwaltung00.mdb und funktioniert mit Access 2000 und höher. Sie finden die Datenbank auf der Heft-CD oder im Internet unter http://
www.access-im-unternehmen.de (Shortlink 280). Der erste Teil dieses Beitrags steht an gleicher Stelle unter dem Shortlink 273 bereit. (

Inventur

Eine Inventur ist die Aufnahme des Bestands aller Vermögenswerte eines Unternehmens, also auch der vorhandenen Artikel. Die in die Artikelverwaltung integrierte Inventurfunktion ermöglicht dies ausschließlich für die Artikel; die Aufnahme aller für eine Inventur notwendigen Informationen würde den Umfang des Beitrags leider sprengen. Diese Inventurfunktion berücksichtigt lediglich die in der Datenbank gespeicherten Artikel. Die Menge der vorhandenen Artikel sowie deren Maßeinheiten sollten regelmäßig zum Bilanzstichtag bekannt sein, um eine ordnungsgemäße Buchhaltung zu ermöglichen. Der Artikelbestand muss allerdings nicht genau an diesem Tag gezählt werden.

Inventurarten

Abb. 1: Aufruf der Inventur

Es gibt mehrere Varianten von Inventuren, unter anderem die folgenden:

  • Stichtagsinventur: Findet innerhalb von zehn Tagen vor und zehn Tagen nach dem Abschluss-Stichtag statt. Das Ergebnis wird auf den Abschluss-Stichtag hochgerechnet.
  • Verlegte Inventur: Erfolgt zwischen drei Monaten vor und zwei Monaten nach dem Abschluss-Stichtag. Die Zählung der unterschiedlichen Artikel muss nicht an einem Tag erfolgen. Die Werte für jeden einzelnen Artikel werden auf den Abschluss-Stichtag hochgerechnet.
  • Permanente Inventur: Die Inventur erfolgt fast ausschließlich über die Bewertung der Ein- und Ausgänge eines Artikels. Der Soll- und der Ist-Zustand müssen einmal im Jahr abgeglichen werden.
  • Die Anwendung unterstützt alle genannten Inventurarten. Der einzige Unterschied zwischen den Arten ist der Zeitpunkt, an dem Soll- und Istwert des Bestands eines Artikels ermittelt werden müssen. Mit der Artikelverwaltung können Sie den Zeitpunkt der Zählung für jeden einzelnen Artikel festlegen.

    Wie arbeitet die Inventurfunktion?

    Die Inventurfunktion kann für jeden Artikel einzeln aufgerufen werden. Der Aufruf erfolgt über die Schaltfläche Inventur starten der Detailansicht eines Artikels im Formular frmArtikel (s. Abb. 1).

    Die dadurch ausgelöste Ereignisprozedur öffnet das Formular frmInventur für den aktuell im Artikelformular angezeigten Artikel (s. Abb. 2).

    Abb. 2: Eingabe des gezählten Bestands

    Dieses Formular zeigt folgende Informationen an:

  • Datum der letzten Inventur
  • Bestand bei der letzten Inventur
  • Datum der aktuellen Inventur
  • Berechneter Bestand (aktuelle Inventur)
  • Tatsächlicher Bestand (aktuelle Inventur)
  • Differenz zwischen tatsächlichem und berechnetem Bestand
  • Die mit einem roten Rahmen versehenen Informationen kann der Benutzer selbst ändern. Das Datum wird automatisch mit dem aktuellen Datum vorgelegt, es kann aber nachträglich geändert werden.

    Programmierung der
    Inventurfunktion

    Bei der Programmierung des Formulars frmInventur und der enthaltenen Funktionen sind einige Punkte zu beachten, die im nachfolgenden Abschnitt geklärt werden. Anschließend finden Sie eine Beschreibung der Funktion selbst.

    Wichtige Voraussetzungen

    Die Inventurfunktion startet mit dem Mausklick auf die Schaltfläche Inventur starten des Artikelformulars. Das Formular frmInventur zur Eingabe der Inventurdaten bezieht seine Daten über diverse Zugriffe auf die in der Datenbank enthaltenen Tabellen.

    So durchsucht das Formular die Tabelle tblInventuren, ob es bereits eine Inventur zu dem zu untersuchenden Artikel gibt, und liest gegebenenfalls das Datum der Inventur und den Bestand in die entsprechenden Felder des Formulars ein.

    Ist noch kein Inventurdatensatz vorhanden und dementsprechend noch keine Zählung des Artikels erfolgt, verwendet das Formular Standardwerte: als Datum den 1.1.1900 und als Bestand den Wert 0.

    Der im Feld Berechneter Bestand angezeigte Wert ist die Anzahl des Artikels, die sich aus dem Stand bei der letzten Inventur und den seitdem erfolgten Zu- und Abgängen berechnet.

    Dabei spielt natürlich das Datum der aktuellen Inventur eine wichtige Rolle: Beim Öffnen des Formulars zeigt dieses das aktuelle Datum und den Bestand zu diesem Datum an. Wenn der Benutzer das Datum verändert, wird auch der berechnete Bestand angepasst. Neben dem Inventurdatum muss der Benutzer auch die tatsächliche Anzahl des Artikels angeben. Erst dann wird die Differenz berechnet und die Inventurdaten können gespeichert werden.

    Private Sub Form_Current()

        Dim datLetzteInventur As Date

        Dim lngBestandLetzteInventur As Long

        Me!txtArtikel = Artikelbezeichnung(lngArtikelID)

        Call LetzteInventur(lngArtikelID, datLetzteInventur, lngBestandLetzteInventur)

        Me!txtDatumLetzteInventur = datLetzteInventur

        Me!txtBestandLetzteInventur = lngBestandLetzteInventur

        Me!txtDatumAktuelleInventur = Date

        Me!txtBestandAktuelleInventurBerechnet = lngBestandLetzteInventur + _
            BestandsaenderungSumme(lngArtikelID, Date)

    End Sub

    Quellcode 1

    Private Function Artikelbezeichnung(lngArtikelID As Long) As String

        Dim db As DAO.Database

        Dim rstArtikel As DAO.Recordset

        Set db = CurrentDb

        Set rstArtikel = db.OpenRecordset("SELECT Bezeichnung FROM tblArtikel " _
            & "WHERE ArtikelID = " & lngArtikelID, dbOpenDynaset)

        Artikelbezeichnung = rstArtikel!Bezeichnung

        Set db = Nothing

    End Function

    Quellcode 2

    Technische Umsetzung

    Die erste Prozedur, die bei der Verwendung des Formulars frmInventuren zum Zuge kommt, ist die Ereignisprozedur, die beim Öffnen des Formulars ausgelöst wird. Sie weist der modulweit deklarierten Variablen lngArtikel die per Öffnungsargument von der aufrufenden Instanz übergebene Artikelnummer zu.

    Private Sub Form_Open(Cancel As Integer)

        lngArtikelID = Me.OpenArgs

    End Sub

    Die Ermittlung der im Formular angezeigten Werte erfolgt in der Ereignisprozedur, die durch das Ereignis Beim Anzeigen ausgelöst wird (s. Quellcode 1). Die Prozedur ermittelt zunächst anhand des Werts des Feldes ArtikelID die Artikelbezeichnung und trägt diese in das Textfeld txtArtikel ein. Dazu verwendet sie die Prozedur aus Quellcode 2. Diese Prozedur liefert die Artikelbezeichnung für die als Parameter übergebene Artikel-ID. Dabei instanziert sie ein Database-Objekt und ein Recordset-Objekt und ermittelt über eine entsprechende Abfrage eine Datensatzgruppe mit dem gesuchten Artikeldatensatz.

    Performance statt Dlookup

    Statt dieser Funktion hätte man auch einen entsprechenden Aufruf der Dlookup-Funktion verwenden können (in einer Zeile):

    Me!txtArtikel = DLookup("Bezeichnung", "tblArtikel", "ArtikelID = " 
    & lngArtikelID)

    Das wäre zwar wesentlich platzsparender und damit auch übersichtlicher gewesen, allerdings ist die Performance der Domänenfunktionen relativ schlecht. Ein konkreter Test mit je 1000 Aufrufen jeder Funktion in einer Schleife brachte ein eindeutiges Ergebnis: Über mehrere Läufe hinweg war die DAO-Variante circa 50-100% schneller als die Dlookup-Funktion.

    Private Sub LetzteInventur(lngArtikelID As Long, datLetzteInventur As Date, _
        lngBestandLetzteInventur As Long)

        Dim db As DAO.Database

        Dim rstInventuren As DAO.Recordset

        Dim rstBestandsaenderungen As DAO.Recordset

        Set db = CurrentDb

        Set rstInventuren = db.OpenRecordset("SELECT TOP 1 Inventurdatum, " _
            & "Lagerbestand FROM tblInventuren WHERE ArtikelID = " & lngArtikelID _
            & " ORDER BY Inventurdatum DESC", dbOpenDynaset)

        If Not rstInventuren.EOF Then

            datLetzteInventur = rstInventuren!Inventurdatum

            lngBestandLetzteInventur = rstInventuren!Lagerbestand

        Else

            Set rstBestandsaenderungen = db.OpenRecordset("SELECT Datum " _
                & "FROM tblBestandsaenderungen WHERE ArtikelID = " & lngArtikelID _
                & " ORDER BY Datum DESC", dbOpenDynaset)

            If Not rstBestandsaenderungen.EOF Then

                datLetzteInventur = rstBestandsaenderungen!Datum

            Else

                datLetzteInventur = "1.1.1900"

            End If

            lngBestandLetzteInventur = 0

            rstBestandsaenderungen.Close

        End If

        rstInventuren.Close

        Set rstInventuren = Nothing

        Set rstBestandsaenderungen = Nothing

    End Sub

    Quellcode 3

    Daten der letzten Inventur ermitteln

    In einer weiteren externen Routine ermittelt die Prozedur Form_Current das Datum der letzten Inventur und den Bestand bei der letzten Inventur.

    Da die beiden zu ermittelnden Werte aus der gleichen Tabelle stammen und gleichzeitig mit einer Routine ermittelt werden sollen, können nicht beide per Rückgabewert an die aufrufende Prozedur übermittelt werden.

    Die betroffene Routine heißt LetzteInventur und hat drei Parameter, von denen einer als Eingangs- und zwei als Ausgangsparameter verwendet werden. Die Ausgangsparameter werden bereits in der aufrufenden Prozedur Form_Current deklariert und als Variable übergeben (in einer Zeile):

    Call LetzteInventur(lngArtikelID, datLetzteInventur, lngBestandLetzteInventur)

    Die beiden letzten Parameter dieses Aufrufs werden in der Prozedur LetzteInventur mit den gewünschten Daten gefüllt (s. Quellcode 3).

    Um diese Daten zu ermitteln, greift die Prozedur auf zwei Tabellen zu. Zunächst sucht sie in der Tabelle tblInventuren nach der aktuellsten Inventur für diesen Artikel. Die dazu verwendete Abfrage ist nach dem Inventurdatum sortiert und gibt durch die Option TOP 1 nur den ersten Eintrag der Datensatzgruppe zurück. Ist dieser Datensatz vorhanden, liest die Prozedur das Inventurdatum und den Lagerbestand aus der Tabelle aus und schreibt sie in die entsprechenden Rückgabeparameter.

    Private Function BestandsaenderungSumme(lngArtikelID As Long, _
        datAktuelleInventur As Date) As Long

        Dim db As DAO.Database

        Dim rstBestandsaenderungSumme As DAO.Recordset

        Set db = CurrentDb

        Set rstBestandsaenderungSumme = _
            db.OpenRecordset("SELECT Sum(Anzahl * Vorzeichen) AS LagerbestandGesamt " _
            & "FROM tblBestandsaenderungen WHERE ArtikelID = " & lngArtikelID _
            & " AND Inventur = False AND Datum <= " _
            & ISODatum(Me.txtDatumAktuelleInventur), dbOpenDynaset)

        BestandsaenderungSumme = Nz(rstBestandsaenderungSumme!LagerbestandGesamt, 0)

        rstBestandsaenderungSumme.Close

        Set rstBestandsaenderungSumme = Nothing

        Set db = Nothing

    End Function

    Quellcode 4

    Wenn die Datensatzgruppe leer ist, wurde noch keine Inventur für diesen Artikel durchgeführt. In dem Fall sind weitere Untersuchungen erforderlich, um halbwegs sinnvolle Werte zurückzugeben. Wenn noch keine Inventur stattgefunden hat, wäre der Stand vor der ersten Bestandsänderung der letzte bestätigte Stand - und der ist immer 0. Als Datum stellt die Prozedur in dem Fall das Datum der ersten Bestandsänderung ein. Wenn weder eine Bestandsänderung noch eine Inventur für einen Artikel stattgefunden hat, ist Fantasie gefragt: Als Datum wird dann der 1.1.1900 und als Bestand der Wert 0 zurückgegeben.

    Einstellen des Datums der aktuellen Inventur

    Als Datum für die aktuelle Inventur trägt die Prozedur Form_Current das aktuelle Datum ein.

    Sie haben das Ende des frei verfügbaren Teils des Artikels erreicht. Lesen Sie weiter, um zu erfahren, wie Sie den vollständigen Artikel lesen und auf viele hundert weitere Artikel zugreifen können.

    Sind Sie Abonnent?Jetzt einloggen ...
     

    Kompletten Artikel lesen?

    Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

    E-Mail:

    © 2003-2015 André Minhorst Alle Rechte vorbehalten.