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/2008.

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

Zusammenfassung

Bauen Sie sich ein Versionierungssystem für Access-Objekte und -Module.

Techniken

VBA, Formulare

Voraussetzungen

Access 2000 und höher

Beispieldateien

AccVersion.mdb

Shortlink

610

Quellcode-Versionsverwaltung inside

André Minhorst, Duisburg

So, jetzt habe ich endgültig die Nase voll. Schon wieder ist es passiert: Mit letzter Kraft eine wichtige Routine zu Ende programmiert und jetzt nur noch Access schließen, den Rechner runterfahren und ab ins Bett. Und am nächsten Morgen die Ernüchterung: Die Änderungen sind nicht mehr da! Da habe ich wohl mal wieder mit "Nein" auf die Frage geantwortet, ob ich die geänderten Objekte speichern möchte ... Aber damit ist jetzt Schluss: Ich baue mir ein Tool, das regelmäßig meine Formulare, Berichte und Module speichert - und dabei auch noch alte Versionen aufbewahrt.

Es ist ein Kreuz: Es braucht unter Access nur ein wenig Ungeschicklichkeit, um eine Menge Arbeit zu vernichten. Wenn Sie mal ein umfangreiches Modul programmiert und dann die Datenbank oder das Modul geschlossen haben, ohne den neuen Stand zu speichern, wissen Sie, wovon ich spreche. Zwischenspeichern?

Wenn man gerade im Programmierrausch ist und eine Zeile nach der anderen schreibt, denkt man nicht unbedingt an das Zwischenspeichern, auch wenn es doch so einfach wäre, zwischendurch einfach mal Strg + S zu drücken.

Wie kommt man dem bei? Termine in Outlook setzen, die einen alle 15 Minuten daran erinnern, mal durchzupusten und den aktuellen Stand zu speichern?

So weit kommt es noch - wir sind schließlich Programmierer und die helfen sich selbst.

Wenn man sich aber schon an die Programmierung eines Tools macht, das regelmäßig für das Speichern geänderter Objekte sorgt, was sollte dieses Tool praktischerweise noch erledigen?

Das automatische Speichern ist nicht unbedingt immer eine perfekte Lösung: Immerhin zerstört man damit ja auch die Möglichkeit, zum Stand der letzten Speicherung zurückzukehren - und damit zur möglicherweise letzten funktionstüchtigen Version.

Unter Access und speziell im VBA-Editor ist das praktisch eine Lebensversicherung, wenn man mal größere Änderungen durchführt und diese dann doch nicht übernehmen möchte - man speichert sie dann einfach nicht.

Der VBA-Editor bietet nämlich auch in der aktuellen Version nur die Möglichkeit, 20 Schritte rückgängig zu machen - insgesamt, nicht pro Modul!

Es scheint also eine gute Idee, die gespeicherten Zwischenstände zu sichern. Aber wohin damit - und wie?

Bevor wir uns diesen technischen Feinheiten zuwenden, halten wir fest: Access soll den Stand der Entwicklung in regelmäßigen Abständen, zumindest aber beim Schließen der Anwendung, sichern.

Auf diese Weise sorgen Sie nicht nur dafür, dass Änderungen nicht verloren gehen, sondern können auch noch auf frühere Stände zurückgreifen.

Anwendung

Schauen wir uns an, wie das Ganze funktioniert: Nachdem Sie die Elemente der Anwendung wie im Kasten "Im Soforteinsatz" zu einer Datenbank hinzugefügt und dafür gesorgt haben, dass das Formular frmAccVersion angezeigt wird, können Sie schon loslegen.

Das Formular sehen Sie in Abb. 1. Es enthält ein Listenfeld zur Anzeige der Module und ein weiteres zur Auflistung der Versionen zum aktuell im ersten Listenfeld markierten Modul. Zu den Modulen gehören in dem Fall Formulare, Berichte, Standardmodule und Klassenmodule, aber auch Abfragen.

pic001.tif

Abb. 1: Das Formular zur Verwaltung der Versionen

Beim ersten Öffnen des Formulars sind diese Listenfelder natürlich noch leer, was sich aber nach einem Klick auf die Schaltfläche Neue Version aller geänderten Objekte speichern ändert. Die Versionsverwaltung durchläuft dann alle Objekte der genannten Typen und legt zunächst das Modul im ersten Listenfeld und dann die Version im zweiten Listenfeld an.

Damit hat man schon einmal einen Zwischenstand, mit dem man sich ganz unbeschwert an den Code heranwagen kann, denn mit der Schaltfläche Bestehendes Objekt mit dieser Version überschreiben können Sie sich ganz leicht eine ältere Version zurückholen.

Falls Sie sich nicht sicher sind, welche Version die richtige ist, stellen Sie einfach die Version wieder her, hinter der Sie die richtige vermuten - und zwar mit der Schaltfläche Objekt wiederherstellen als <Name>_yyyymmdd_hhnnss, die bestehende Objekte nicht überschreibt, sondern unter einem Namen anlegt, der den Zeitpunkt der Speicherung enthält.

Die Schaltfläche Version löschen dient schließlich dazu, eine oder mehrere Versionen zu entsorgen - wenn man einen Versionsstand erreicht hat, bei dem alles funktioniert, braucht man selbstverständlich keine Altlasten mehr mit sich herumzutragen.

Schließlich gibt es im unteren Bereich noch die Steuerelemente zum Festlegen der regelmäßigen Sicherung von Versionsständen. Mit dem Kontrollkästchen Geänderte Objekte alle x Minuten als neue Version sichern aktivieren Sie diese Funktion, in das Textfeld Intervall [min] tragen Sie ein, in welchem Abstand die Sicherung erfolgen soll.

Schließen ohne zu speichern

Wenn der Benutzer die Datenbankanwendung beendet, schließt er auch das Formular frmAccVersion. Dieses sorgt dann mit seiner letzten Aktion noch einmal dafür, dass nicht gespeicherte Module in den Versionierungstabellen gespeichert werden.

Wenn Sie also ein Modul namens mdlTest bearbeiten, die Änderungen nicht speichern und dann die Anwendung schließen, speichert frmAccVersion trotzdem die aktuelle Version des Moduls.

Beim nächsten Öffnen der Datenbank erscheint eine Meldung, die den Benutzer darauf hinweist, dass es Module oder Objekte gibt, die vor dem letzten Schließen geändert, aber nicht gespeichert wurden (s. Abb. 2).

pic004.tif

Abb. 2: Diese Meldung macht den Benutzer auf ungespeicherte Elemente aufmerksam.

Im Anschluss erscheint das Formular frmAccVersion und zeigt das nicht gespeicherte Objekt unter dem Originalobjekt an - versehen mit einer GUID. Mit einem Klick auf die Schaltfläche Objekte wiederherstellen als <Name>_yyyymmdd_hhnnss erzeugen Sie dann eine Kopie des Objekts mit dem ungespeicherten Stand beim letzten Schließen der Anwendung (s. Abb. 3).

pic005.tif

Abb. 3: Nicht gespeicherte Änderungen lassen sich mit AccVersion zurückholen.

Nebenwirkungen

Für manche Objekte ist es wichtig, diese vor dem Versionieren zu speichern. Dies gilt für Abfragen, Berichte und Formulare. Standard- und Klassenmodule stehen ohne weitere Schritte zum Versionieren bereit.

Das ist allerdings ein Problem, denn dieses Tool soll ja gerade auch dann, wenn der Benutzer es versäumt, ein Objekt vor dem Beenden der Datenbank zu speichern, geradestehen und die seit dem letzten Speichern getätigten Änderungen sichern.

Ganz einfach ist das allerdings nicht, ohne den Benutzer nicht doch noch zu einem Klick auf die Ja-Schaltfläche der Speichern?-Frage zu nötigen - warum, erfahren Sie weiter unten.

Datenmodell

Die Anwendung braucht genau zwei Tabellen: Eine zum Speichern der Informationen zu den Modulen selbst und eine für die einzelnen Versionen der Module. Abb. 4 zeigt die Tabellen und ihre Beziehung.

pic002.tif

Abb. 4: Datenmodell für die Verwaltung von Modulen und deren Versionen

Die Tabelle tblModule enthält neben dem Feld Modulname mit der Bezeichnung des Moduls nur noch ein Feld namens Modultyp. Dieses enthält einen Zahlenwert, der einer der Konstanten der VBA-Enumeration acObjectType entspricht. In diesem Zusammenhang kommen die folgenden Typen vor (Zahlenwert in Klammern):

  • acQuery (1)
  • acForm (2)
  • acReport (3)
  • acModule (5)

Unter acModule fallen dabei sowohl Klassen- als auch Standardmodule.

Die zweite Tabelle heißt tblVersionen und ist über ein Fremdschlüsselfeld namens ModulID mit der Tabelle tblModule verknüpft. Auf diese Weise können die Datensätze dieser Tabelle den Modulen aus der Tabelle tblModule zugeordnet werden.

Die Tabelle enthält weitere Felder zum Speichern des eigentlichen Inhalts des Moduls (Modulinhalt) und des Speicherdatums (Speicherdatum).

Das Feld Modulinhalt ist dabei als Memofeld ausgelegt, weil es sehr lange Texte erfassen können muss.

Datenmodell automatisch erstellen

Der Benutzer soll so wenige Objekte wie möglich in seine Anwendung importieren müssen, um mit der Versionsverwaltung arbeiten zu können. Daher soll das Hauptformular von AccVersion - so soll das Tool heißen - beim Laden prüfen, ob die benötigten Tabellen schon vorhanden sind und diese anderenfalls anlegen. Ist das der Fall, kommt die Prozedur aus Listing 1 zum Einsatz.

Listing 1: Anlegen der für die Versionsverwaltung benötigten Tabellen per SQL

Public Sub TabellenAnlegen()

Dim cnn As Object

Set cnn = CurrentProject.Connection

cnn.Execute "CREATE TABLE tblModule(ModulID COUNTER CONSTRAINT PK PRIMARY KEY, " _

& "Modulname VARCHAR(255), Modultyp INT)", dbFailOnError

cnn.Execute "CREATE TABLE tblVersionen(VersionID COUNTER CONSTRAINT PK PRIMARY KEY, " _

& "Modulinhalt LONGTEXT, Speicherdatum DATETIME, ModulID INT)", dbFailOnError

cnn.Execute "ALTER TABLE tblVersionen ADD CONSTRAINT FKModulID FOREIGN KEY (ModulID) " _

& "REFERENCES tblModule ON DELETE CASCADE ON UPDATE CASCADE", dbFailOnError

Application.RefreshDatabaseWindow

End Sub

Diese Routine erzeugt zunächst die Tabelle tblModule, dann tblVersionen und schließlich das Fremdschlüsselfeld mit referentieller Integrität sowie Lösch- und Aktualisierungsweitergabe.

Tabelleninhalt

Der Inhalt der meisten Felder der Tabellen des Datenmodells bedarf keiner Erklärung, das Feld Modulinhalt aber sehr wohl. Wer sich ein Modul (sei es ein einfaches Klassenmodul, ein Standardmodul oder auch das Klassenmodul eines Formulars oder Berichts) einmal angesehen hat, sieht zunächst nur den darin enthaltenen Code.

Nur diesen zu speichern, würde zwar schon weiterhelfen, denn somit könnten Sie zumindest den Verlust umfangreicher Codeänderungen verhindern.

Wer aber einmal ein Formular oder einen Bericht mit einer Menge Steuerelemente und entsprechenden Anpassungen der Eigenschaften gebaut hat und später alles noch einmal neu bauen musste, weil er im falschen Moment die falsche Schaltfläche angeklickt hat, wird sich über Folgendes freuen: Auch die Definition sämtlicher Eigenschaften von Formularen und Berichten und den darin enthaltenen Steuerelementen liegt in Textform vor und Sie können sogar darauf zugreifen!

Nun ist es nicht so, als ob diese Informationen offen herumliegen, aber über einen Zwischenschritt können Sie die komplette Definition von Objekten wie Formularen oder Berichten im Feld Modulinhalt der Tabelle tblVersionen speichern.

Dies macht die verborgene Methode SaveAsText von Access.Application möglich, die drei Parameter erwartet:

  • ObjectType: Typ des Objekts, entspricht einem Wert der weiter oben schon erwähnten VBA-Enumeration acObjectType
  • ObjectName: Name des Objekts, also beispielsweise frmBeispielformular
  • Filename: Speicherort- und Name, also etwa c:\frmBeispielformular.txt

Wenn Sie mit dieser Methode ein noch leeres Formular als Textdatei speichern und es anschließend in einem Texteditor ansehen, sieht das beispielsweise wie in Abb. 5 aus.

pic003.tif

Abb. 5: Die Definition eines leeren Formulars als Textdatei

Versionieren von Access-Objekten

Der schwierigste Teil von AccVersion ist das eigentliche Versionieren der Module.

Dabei durchläuft eine Routine alle Elemente der Anwendung, die einem der möglichen Typen entsprechen und unterzieht diese einer ganzen Reihe von Methoden.

Wie aufwendig das ist, verdeutlicht ein Blick auf das Flussdiagramm aus Abb. 6, dessen einzelne Schritte wir in den nächsten Abschnitten genau beleuchten werden.

Flussdiagramm.emf

Abb. 6: Ablauf beim Versionieren der Objekte einer Access-Anwendung

Der Hauptteil dieses Flussdiagramms läuft in der Routine ModuleSpeichern ab (s. Listing 2). Von dort aus werden noch eine Reihe weiterer Routinen aufgerufen. Den Rahmen bildet eine Do While-Schleife, die alle Datensätze der Tabelle MSysObjects durchläuft, die speziellen Anforderungen genügen.

Listing 2: Diese Routine steuert das Versionieren der Module.

Public Function ModuleSpeichern(bolZwischenspeichern As Boolean) As Boolean

    ...

    Set db = CurrentDb

    strSQL = "SELECT Name, Type FROM MSysObjects WHERE Type=1 Or Type=5 Or Type=8 Or Type=-32761 " _

    & "Or Type=-32764 Or Type=-32768;"

    Set rst = db.OpenRecordset(strSQL, dbOpenDynaset)

    FortschrittAnzeigen

    Do While Not rst.EOF

        If Not (Left(rst!Name, 2) = "__" Or Left(rst!Name, 1) = "~") Then

            strModulname = rst!Name

            Select Case rst!Type

            Case -32761 'Modul

            lngObjecttype = acModule

            Case -32764 'Report

            lngObjecttype = acReport

            Case -32768 'Form

            lngObjecttype = acForm

            Case 5

            lngObjecttype = acQuery

            Case Else 'andere Objekte

            strModulname = ""

            End Select

            If Not Len(strModulname) = 0 Then

                FortschrittAktualisieren "Versioniere " & rst!Name, _

                100 * rst.AbsolutePosition / rst.RecordCount

                strModulname_Original = strModulname

                If SaveModule(strModulname, lngObjecttype, bolZwischenspeichern) = True Then

                    strModulinhalt = LoadModule

                    If MustSaveObject(strModulname) Then

                        SaveObject strModulname, lngObjecttype

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:

Verwandte Beiträge:

Grundlagen der Quellcodeverwaltung

Datenbanken und Tabellen per SQL anpassen

SQL-Datenbankschema auslesen

Gruppensummen ohne Gruppen im Berichtsfuß

Termine in Berichten darstellen

Berichte manuell füllen

Benutzerdefinierte Formatierung

© 2003-2015 André Minhorst Alle Rechte vorbehalten.