{"id":55001556,"date":"2025-08-01T00:00:00","date_gmt":"2025-08-03T11:25:47","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1556"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Automatisches_Update_per_Startdatenbank","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/","title":{"rendered":"Automatisches Update per Startdatenbank"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg01.met.vgwort.de\/na\/f0f901044c4f429cbc7063a661dd7264\" width=\"1\" height=\"1\" alt=\"\"><b>Access-Datenbankanwendungen sind bekanntlich niemals fertig. Das ist an sich kein Nachteil, sondern stellt eher einen Vorteil dar: Im Gegensatz zu fertigen Anwendungen, bei denen Anpassungen entweder gar nicht m&ouml;glich sind oder viel Geld kosten, kann man Access-Datenbanken einfach selbst um neue Funktionen erweitern. Spannend wird das, wenn die Datenbank von mehreren Nutzern eingesetzt wird. Dann stellt sich die Frage: Wie bekomme ich die neue Version einer Datenbank am einfachsten auf die unterschiedlichen Arbeitspl&auml;tze? Das gelingt auf verschiedene Arten, und in diesem Beitrag schauen wir uns eine an, mit der das Update vom Arbeitsplatz des Benutzers aus getriggert werden soll.<\/b><\/p>\n<p>Wenn wir eine klassische Konstellation vorliegen haben, bei der jeder Benutzer einen eigenen Rechner hat, der an das Firmennetzwerk angeschlossen ist, ist die nachfolgende beschriebene Vorgehensweise perfekt geeignet. In diesem Fall agieren wir also als Entwickler in oder f&uuml;r das entsprechende Unternehmen. Es gibt noch einen anderen Fall, den wir in einem weiteren Beitrag besprechen wollen &#8211; hier ist der Entwickler selbst&auml;ndig und verteilt seine Anwendung an Anwender aus verschiedenen Unternehmen.<\/p>\n<p>Im ersten Fall w&uuml;rden wir die neue Version der Anwendung auf einem Server im Unternehmen platzieren, von wo aus diese dann heruntergeladen werden kann. Im zweiten Fall steht die Datenbankdatei im Internet zum Download bereit.<\/p>\n<p>Normalerweise startet der Benutzer seine Kopie der Datenbankanwendung, indem er eine entsprechende Verkn&uuml;pfung aufruft oder doppelt auf die Datenbankdatei klickt.<\/p>\n<p>Wir wollen diesen Ablauf so &auml;ndern, dass er nicht direkt die eigentliche Datenbankanwendung startet, sondern dass die Verkn&uuml;pfung eine Startdatenbank &ouml;ffnet. Diese pr&uuml;ft dann, ob es eine neue Version der eigentlichen Datenbank gibt und l&auml;dt diese gegebenenfalls herunter und kopiert sie &uuml;ber die vorhandene Version der Anwendung.<\/p>\n<p>Anschlie&szlig;end soll die Startdatenbank die eigentliche Datenbank starten. Wenn keine neue Version vorliegt, soll die Startdatenbank einfach die vorhandene Anwendung aufrufen.<\/p>\n<h2>Code automatisch aufrufen beim Start der Startdatenbank<\/h2>\n<p>Die erste Technik, die wir ben&ouml;tigen, ist ein automatischer Aufruf der Prozeduren zum Pr&uuml;fen auf Updates und der weiteren Schritte beim Start der Startdatenbank.<\/p>\n<p>Das erledigen wir zuverl&auml;ssig mit einem <b>AutoExec<\/b>-Makro. Wir legen also ein neues Makro an und speichern dieses unter dem Namen <b>AutoExec<\/b>. Dieses wird beim Starten von Access automatisch aufgerufen.<\/p>\n<p>Dem Makro weisen wir eine einzige Makroaktion zu. Diese hei&szlig;t <b>Ausf&uuml;hrenCode <\/b>und erh&auml;lt f&uuml;r den Parameter <b>Funktionsname <\/b>den Wert <b>=StartDb()<\/b>. Das Makro sieht in der Entwurfsansicht wie in Bild 1 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1556_001.png\" alt=\"AutoExec-Makro, das beim Start automatisch ausgef&uuml;hrt wird\" width=\"499,5589\" height=\"197,3144\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: AutoExec-Makro, das beim Start automatisch ausgef&uuml;hrt wird<\/span><\/b><\/p>\n<p>Die aufzurufende Funktion gestalten wir erst einmal wie folgt:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>StartDb()\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Start\"\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>Das Speichern aller &Auml;nderungen und das Schlie&szlig;en und erneute &Ouml;ffnen der Anwendung sollte nun die Anwendung &ouml;ffnen und das Meldungsfenster anzeigen.<\/p>\n<h2>Erkennen einer neuen Version<\/h2>\n<p>Bevor wir uns die Techniken ansehen, mit denen wir eine Datenbank durch eine neuere Version ersetzen, ben&ouml;tigen wir erst einmal die Merkmale, mit denen wir eine neue Version erkennen k&ouml;nnen.<\/p>\n<p>&Uuml;blicherweise verwendet man hier eine Versionsnummer, die auf unterschiedliche Arten gestaltet sein kann. Am einfachsten, auch f&uuml;r den hier vorgesehenen Zweck, ist ein einfacher <b>Long<\/b>-Wert f&uuml;r die Version. Damit k&ouml;nnen wir schnell und einfach vergleichen: Ist der Versionswert der aktuellen Version kleiner als der entsprechenden Version der Datenbank auf dem Serverlaufwerk?<\/p>\n<p>Gelegentlich verwendet man auch umfangreichere Versionsnummern wie <b>1.0.0.4<\/b>. Auch das k&ouml;nnen wir umsetzen, allerdings ist der Aufwand minimal h&ouml;her, da wir Stelle f&uuml;r Stelle vergleichen m&uuml;ssen.<\/p>\n<p>Wenn man davon ausgeht, dass es maximal eine neue Version pro Tag gibt, k&ouml;nnten wir auch einfach das Datum der jeweiligen Version heranziehen. Dann spielt es keine Rolle, ob wir nur einen einfachen <b>Long<\/b>-Wert als Versionsnummer verwenden oder einen Ausdruck wie <b>1.0.0.4<\/b>.<\/p>\n<p>Wir wollen an dieser Stelle Komplexit&auml;t herausnehmen und verwenden einfach ein Datumsfeld als Kriterium f&uuml;r die Notwendigkeit, die Anwendung mit einer neueren Version zu aktualisieren. Zus&auml;tzlich wollen wir die Versionsnummer in einem weiteren Feld speichern, dem wir den Datentyp <b>Kurzer Text <\/b>geben.<\/p>\n<p>Die folgende Tabelle <b>tblVersion <\/b>legen wir in der jeweiligen Produktdatenbank an.<\/p>\n<p>Die Tabelle <b>tblVersion<\/b> sieht in der Entwurfsansicht wie in Bild 2 aus. Hier kann man bei Bedarf noch weitere Felder hinzuf&uuml;gen, zum Beispiel zur Angabe von weiteren Informationen zu dieser Version wie den Neuerungen oder Fehlerkorrekturen, die in dieser Version enthalten sind.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1556_002.png\" alt=\"Tabelle zum Speichern der Versionsinformationen in der Entwurfansicht\" width=\"599,559\" height=\"356,3246\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Tabelle zum Speichern der Versionsinformationen in der Entwurfansicht<\/span><\/b><\/p>\n<p>Wechseln wir in dieser Tabelle zur Datenblattansicht, tragen wir beispielsweise Informationen wie in Bild 3 ein.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1556_003.png\" alt=\"Tabelle mit der Versionsnummer\" width=\"424,5589\" height=\"159,9109\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Tabelle mit der Versionsnummer<\/span><\/b><\/p>\n<p>F&uuml;r die Versionsnummer k&ouml;nnen wir nun ein beliebiges Format verwenden. Wir sollten nur sicherstellen, dass diese korrekt erh&ouml;ht werden, damit der Benutzer nicht pl&ouml;tzlich eine neue Version mit einer niedrigeren Versionsnummer vorfindet.<\/p>\n<h2>Standort der Startdatenbank und der Produktivdatenbank<\/h2>\n<p>Der Einfachheit halber sollten die Startdatenbank und die Produktivdatenbank immer im gleichen Verzeichnis liegen.<\/p>\n<p>So k&ouml;nnen wir von der Startdatenbank ganz einfach den Pfad zur Produktivdatenbank ermitteln, indem wir mit <b>CurrentProject.Path <\/b>den Pfad der beiden Datenbankdateien ermitteln und dann den Namen der Produktivdatenbank anh&auml;ngen.<\/p>\n<p>Die jeweils neuere Version, durch welche die aktuell auf dem Clientrechner vorliegende Version ersetzt werden soll, wird logischerweise nicht im gleichen Verzeichnis liegen, sondern an einer zentral zug&auml;nglichen Stelle auf einem Server im Unternehmen oder auch in der Cloud. Hier m&uuml;ssen wir daher den kompletten Pfad in der Startdatenbank speichern.<\/p>\n<p>Insgesamt ben&ouml;tigen wir also zwei Felder in einer Konfigurationstabelle, die wir der Startdatenbank hinzuf&uuml;gen. Diese Tabelle hei&szlig;t <b>tblKonfiguration<\/b> und enth&auml;lt den Entwurf aus Bild 4.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1556_004.png\" alt=\"Tabelle zum Speichern der Konfiguration der Startdatenbank\" width=\"599,559\" height=\"398,7405\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Tabelle zum Speichern der Konfiguration der Startdatenbank<\/span><\/b><\/p>\n<p>Das erste Feld namens <b>DatenbanknameClient <\/b>nimmt den Namen der aktuellen Version der Datenbankdatei im aktuellen Verzeichnis der Startdatenbank auf. Das zweite Feld hei&szlig;t <b>DatenbankpfadServer <\/b>und enth&auml;lt den vollst&auml;ndigen Pfad der zu pr&uuml;fenden, gegebenenfalls aktuelleren Version der Datenbankdatei. Beide haben den Datentyp <b>Kurzer Text<\/b>.<\/p>\n<p>Gegebenenfalls kommt es vor, dass die 255 Zeichen eines Feldes mit dem Datentyp <b>Kurzer Text <\/b>nicht ausreichen, um den vollst&auml;ndigen Pfad zu speichern. In diesem Fall haben wir zwei M&ouml;glichkeiten:<\/p>\n<ul>\n<li>Wir teilen das Feld <b>DatenbankpfadServer <\/b>auf zwei Felder auf, die das Verzeichnis und den Dateinamen speichern.<\/li>\n<li>Oder wir verwenden einfach den Felddatentyp <b>Langer Text<\/b>.<\/li>\n<\/ul>\n<h2>Grundstruktur der Aktualisierung<\/h2>\n<p>Bevor wir uns an die Details begeben, mit denen wir die verschiedenen Bedingungen pr&uuml;fen und Aktionen durchf&uuml;hren, bauen wir eine Grundstruktur f&uuml;r den Vorgang auf. <\/p>\n<p>Diese finden wir in Listing 1.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>DatenbankAktualisieren(ByRef strErgebnis<span style=\"color:blue;\"> As String<\/span>, ByRef bolFehler<span style=\"color:blue;\"> As Boolean<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strPfadClient<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strPfadServer<span style=\"color:blue;\"> As String<\/span>\r\n     strPfadClient = CurrentProject.Path & \"\\\" & DLookup(\"DatenbanknameClient\", \"tblKonfiguration\")\r\n     strPfadServer = DLookup(\"DatenbankpfadServer\", \"tblKonfiguration\")\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> DateiVorhanden(strPfadClient)<span style=\"color:blue;\"> Then<\/span>\r\n         strErgebnis = \"Client-Datei fehlt: \" & strPfadClient\r\n         bolFehler = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Exit Function<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> DateiVorhanden(strPfadServer)<span style=\"color:blue;\"> Then<\/span>\r\n         strErgebnis = \"Server-Datei fehlt: \" & strPfadServer\r\n         bolFehler = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Exit Function<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span>IstDatenbankGeoeffnet(strPfadClient)<span style=\"color:blue;\"> Then<\/span>\r\n         strErgebnis = \"Client-Datenbank ist ge&ouml;ffnet.\"\r\n         bolFehler = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Exit Function<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span>IstDatenbankGeoeffnet(strPfadServer)<span style=\"color:blue;\"> Then<\/span>\r\n         strErgebnis = \"Server-Datenbank ist ge&ouml;ffnet.\"\r\n         bolFehler = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Exit Function<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span>NeuereVersionVorhanden(strPfadClient, strPfadServer, strErgebnis)<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">If <\/span>KopiereServerdateiAufClient(strPfadClient, strPfadServer, strErgebnis)<span style=\"color:blue;\"> Then<\/span>\r\n             strErgebnis = \"Datenbank erfolgreich aktualisiert.\" & <span style=\"color:blue;\">vbCrLf<\/span> & strErgebnis\r\n             DatenbankAktualisieren = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             strErgebnis = \"Fehler beim Aktualisieren: \" & strErgebnis\r\n             bolFehler = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         strErgebnis = \"Es konnte keine neue Version gefunden werden.\" & <span style=\"color:blue;\">vbCrLf<\/span> & strErgebnis\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Hauptfunktion zum Aktualisieren einer Datenbankdatei<\/span><\/b><\/p>\n<p>Die Funktion liefert als Ergebnis den Wert <b>True <\/b>oder <b>False <\/b>und au&szlig;erdem mit dem Parameter <b>strErgebnis <\/b>eine Meldung mit weiteren Details. Da <b>strErgebnis <\/b>sowohl im Fehlerfall als auch bei Aktualisierung\/Nicht-Aktualisierung ohne Fehler geliefert wird, verwenden wir mit <b>bolFehler <\/b>einen weiteren Parameter, der angibt, ob ein Fehler aufgetreten ist. <b>bolFehler <\/b>wird immer auf <b>True <\/b>eingestellt, wenn ein Ereignis eintritt, das die Pr&uuml;fung der Versionen oder die Aktualisierung an sich verhindert.<\/p>\n<p>Zu Beginn deklariert die Funktion einige Variablen f&uuml;r die Versionsdaten der beiden Datenbankdateien und ihre Pfade.<\/p>\n<p>Danach lesen wir aus der Tabelle <b>tblKonfiguration <\/b>den Pfad der zu pr&uuml;fenden aktuellen Datenbankdatei auf dem Clientrechner aus. Dazu stellen wir den Pfad aus dem aktuellen Pfad der Startdatenbank und dem Namen der Datenbank aus der Tabelle zusammen und speichern diesen in der Variablen <b>strClientpfad<\/b>.<\/p>\n<p>Das Gleiche erledigen wir anschlie&szlig;end f&uuml;r den Pfad der Datenbank auf dem Server, die gegebenenfalls die Version auf dem Client ersetzen soll. Dieser Pfad landet in der Variablen <b>strServerpfad<\/b>.<\/p>\n<p>Danach folgt eine Reihe <b>If&#8230;Then<\/b>-Bedingungen. Die erste pr&uuml;ft, ob die Datei aus <b>strClientpfad <\/b>&uuml;berhaupt vorhanden ist. Dazu nutzen wir die Hilfsfunktion <b>DateiVorhanden<\/b>, die wir weiter unten beschreiben.<\/p>\n<p>Ist die Daten nicht vorhanden, endet die Funktion hier mit <b>Exit Function<\/b>, nachdem sie f&uuml;r <b>strErgebnis <\/b>eine entsprechende R&uuml;ckmeldung eingetragen hat. Anderenfalls wird die Funktion fortgesetzt.<\/p>\n<p>Die nachfolgende Bedingung ist identisch aufgebaut und pr&uuml;ft das Vorhandensein der zu pr&uuml;fenden Version der Datenbank auf dem Server. Auch hier gilt: Ist diese Datenbank nicht vorhanden, endet die Funktion mit einer entsprechenden Meldung.<\/p>\n<p>Damit ist nun sichergestellt, dass beide betroffenen Datenbankdateien vorhanden sind.<\/p>\n<p>Nun folgt eine weitere wichtige Pr&uuml;fung f&uuml;r die beiden Datenbankdateien. Diese untersucht, ob diese nicht ge&ouml;ffnet sind. Das ist zumindest bei der aktuellen Clientdatenbank essenziell, da diese sonst nicht durch eine eventuell vorhandene neue Version ersetzt werden kann.<\/p>\n<p>Diese Pr&uuml;fung nehmen wir in zwei aufeinanderfolgenden <b>If&#8230;Then<\/b>-Bedingungen vor, die jeweils die Funktion <b>IstDatenbankGeoeffnet <\/b>nutzen.<\/p>\n<p>Liefern beide Pr&uuml;fungen den Wert <b>True<\/b>, geht es weiter, ansonsten endet die Funktion hier wiederum mit entsprechenden Eintr&auml;gen f&uuml;r den Parameter <b>strErgebnis<\/b>.<\/p>\n<p>Sind die Grundvoraussetzungen geschaffen, k&ouml;nnen wir endlich mit der Funktion <b>NeuereVersionVorhanden <\/b>pr&uuml;fen, ob die unter <b>strServerPfad <\/b>gespeicherte Datenbankdatei in einer neueren Version vorhanden ist als die unter <b>strClientPfad <\/b>gespeicherte.<\/p>\n<p>Auch diese Funktion beschreiben wir weiter unten im Detail. Erwartungsgem&auml;&szlig; f&uuml;hrt ein negatives Ergebnis zum Abbruch der Funktion mit entsprechendem Eintrag f&uuml;r <b>strErgebnis<\/b>.<\/p>\n<p>Schlie&szlig;lich sind alle Bedingungen erf&uuml;llt und die Routine ruft die Funktion <b>DatenbankAktualisiert <\/b>auf. Dieser &uuml;bergeben wir die Pfade zu den beiden Datenbanken. Sie soll das eigentliche Ersetzen der alten durch die neue Version erledigen.<\/p>\n<p>Nachfolgend beschreiben wir nun die verwendeten Funktionen.<\/p>\n<h2>Pr&uuml;fen, ob Dateien vorhanden sind<\/h2>\n<p>Die Funktion <b>DateiVorhanden <\/b>nimmt mit dem Parameter <b>strPfad <\/b>den Pfad der Datei entgegen, deren Vorhandensein wir pr&uuml;fen wollen.<\/p>\n<p>Sie verwendet einen verschachtelten Aufruf der beiden Funktionen <b>Len <\/b>und <b>Dir<\/b>. Wenn wir der <b>Dir<\/b>-Funktion einen Dateipfad &uuml;bergeben, liefert sie bei Vorhandensein den Namen der Datei selbst zur&uuml;ck. Wenn nicht, liefert sie eine leere Zeichenkette.<\/p>\n<p>Dieses Ergebnis unterziehen wir der <b>Len<\/b>-Funktion. Bei einer leeren Zeichenkette liefert diese den Wert <b>0<\/b>, anderenfalls einen Wert ungleich <b>0<\/b>.<\/p>\n<p>Im Falle des Wertes <b>0 <\/b>lautet das Ergebnis der Funktion <b>True<\/b>, sonst <b>False<\/b>. Da der Standardwert einer Funktion mit dem R&uuml;ckgabedatentyp <b>Boolean <\/b>gleich <b>False <\/b>ist, k&ouml;nnten wir uns die explizite Zuweisung von <b>DateiVorhanden <\/b>sparen. Allerdings wollen wir hier einmal alle Pfade abbilden.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>DateiVorhanden(strPfad<span style=\"color:blue;\"> As String<\/span>) _\r\n        <span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(Dir(strPfad)) = 0<span style=\"color:blue;\"> Then<\/span>\r\n         DateiVorhanden = <span style=\"color:blue;\">True<\/span>\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         DateiVorhanden = <span style=\"color:blue;\">False<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<h2>Pr&uuml;fen, ob Dateien nicht ge&ouml;ffnet sind<\/h2>\n<p>Die Pr&uuml;fung, ob die Dateien nicht ge&ouml;ffnet sind, &uuml;bernimmt die Funktion <b>IstDatenbankGeoeffnet<\/b>. Sie erwartet jeweils den Pfad der zu pr&uuml;fenden Datenbankdatei.<\/p>\n<p>Sie erstellt ein neues <b>PrivDBEngine<\/b>-Objekt (den Grund daf&uuml;r haben wir im Beitrag <b>Pr&uuml;fen, ob Datenbank ge&ouml;ffnet ist <\/b>(<b>www.access-im-unternehmen.de\/1296<\/b>) beschrieben) und versucht damit, die <b>OpenDatabase<\/b>-Methode f&uuml;r den angegebenen Datenbankpfad auszuf&uuml;hren. Nur wenn dies gelingt, ist die Datenbankdatei sicher noch nicht ge&ouml;ffnet:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>IstDatenbankGeoeffnet(_\r\n         ByVal strDatenbankpfad<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n      <span style=\"color:blue;\">Dim <\/span>objEngine<span style=\"color:blue;\"> As <\/span>DAO.PrivDBEngine\r\n      <span style=\"color:blue;\">Set<\/span> objEngine = <span style=\"color:blue;\">New<\/span> DAO.PrivDBEngine\r\n      On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n      objEngine.OpenDatabase strDatenbankpfad, True, <span style=\"color:blue;\">True<\/span>\r\n      <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> Err.Number = 0<span style=\"color:blue;\"> Then<\/span>\r\n          IstDatenbankGeoeffnet = <span style=\"color:blue;\">True<\/span>\r\n      <span style=\"color:blue;\">End If<\/span>\r\n      <span style=\"color:blue;\">Set<\/span> objEngine = Nothing\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<h2>Pr&uuml;fen, ob eine neuere Version vorhanden ist<\/h2>\n<p>Anschlie&szlig;end folgt die Funktion <b>NeuereVersionVorhanden<\/b>, der wir die Pfade zu den beiden zu vergleichenden Datenbankdateien &uuml;bergeben (siehe Listing 2). Sie deklariert Variablen namens <b>datVersionAlt<\/b>, <b>datVersionNeu<\/b>, <b>strVersionAlt <\/b>und <b>strVersionNeu<\/b>, um die jeweils gespeicherten Versionsdaten zu speichern.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>NeuereVersionVorhanden(strClientpfad<span style=\"color:blue;\"> As String<\/span>, strServerpfad<span style=\"color:blue;\"> As String<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> strErgebnis<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>datVersionAlt<span style=\"color:blue;\"> As Date<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>datVersionNeu<span style=\"color:blue;\"> As Date<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strVersionAlt<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strVersionNeu<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">If <\/span>VersionsdatumErmitteln(strClientpfad, datVersionAlt, strVersionAlt, strErgebnis) = <span style=\"color:blue;\">False<\/span><span style=\"color:blue;\"> Then<\/span>\r\n         NeuereVersionVorhanden = <span style=\"color:blue;\">False<\/span>\r\n         strErgebnis = \"Versionsdatum von ''\" & strClientpfad & \"'' konnte nicht ermittelt werden.\"\r\n         <span style=\"color:blue;\">Exit Function<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span>VersionsdatumErmitteln(strServerpfad, datVersionNeu, strVersionNeu, strErgebnis) = <span style=\"color:blue;\">False<\/span><span style=\"color:blue;\"> Then<\/span>\r\n         NeuereVersionVorhanden = <span style=\"color:blue;\">False<\/span>\r\n         strErgebnis = \"Versionsdatum von ''\" & strServerpfad & \"'' konnte nicht ermittelt werden.\"\r\n         <span style=\"color:blue;\">Exit Function<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span>datVersionNeu &gt; datVersionAlt<span style=\"color:blue;\"> Then<\/span>\r\n         NeuereVersionVorhanden = <span style=\"color:blue;\">True<\/span>\r\n         strErgebnis = \"Alte Version: \" & strVersionAlt & \" vom \" & datVersionAlt & <span style=\"color:blue;\">vbCrLf<\/span> _\r\n             & \"Neue Version: \" & strVersionNeu & \" vom \" & datVersionNeu\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         strErgebnis = \"Keine neuere Version vorhanden.\"\r\n         NeuereVersionVorhanden = <span style=\"color:blue;\">False<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Pr&uuml;fen, ob eine neuere Version vorhanden ist<\/span><\/b><\/p>\n<p>In einer ersten <b>If&#8230;Then<\/b>-Bedingung holt sie mit der Funktion <b>VersiondatumErmitteln <\/b>das Versionsdatum und die Version der Datei aus <b>strClientpfad<\/b>. Liefert der Aufruf den Wert <b>True<\/b>, enth&auml;lt der Parameter <b>datVersionAlt <\/b>danach das Versionsdatum dieser Datenbankdatei.<\/p>\n<p>Nur in diesem Fall wird die Funktion fortgesetzt, anderenfalls verlassen wir diese mit <b>Exit Function <\/b>und einer entsprechenden Meldung in <b>strErgebnis<\/b>.<\/p>\n<p>Konnten wir das Datum ermitteln, rufen wir <b>VersionsdatumErmitteln <\/b>auch f&uuml;r die auf dem Server liegende Datenbankdatei auf. Auch hier verlassen wir die Funktion, wenn das Datum nicht ermittelt werden konnte.<\/p>\n<p>Nur wenn beide Daten vorliegen, werden diese anschlie&szlig;end verglichen. Ist <b>datVersionNeu <\/b>gr&ouml;&szlig;er als <b>datVersionAlt<\/b>, liefert die Funktion den Wert <b>True <\/b>zur&uuml;ck. Au&szlig;erdem stellt sie im Parameter <b>strErgebnis <\/b>einen Text wie den folgenden zusammen:<\/p>\n<pre>Alte Version: 1 vom 28.05.2025\r\nNeue Version: 2 vom 29.05.2025<\/pre>\n<h2>Versionsdatum ermitteln<\/h2>\n<p>Die Funktion <b>VersionsdatumErmitteln <\/b>nimmt den Pfad der Datenbank sowie einige R&uuml;ckgabeparameter entgegen (siehe Listing 3). Diese sollen Datum und Nummer der Version zur&uuml;ckliefern sowie mit <b>strErgebnis <\/b>eine Meldung, falls etwas nicht funktioniert hat.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>VersionsdatumErmitteln(strDatenbankpfad<span style=\"color:blue;\"> As String<\/span>, ByRef datVersion<span style=\"color:blue;\"> As Date<\/span>, _\r\n         ByRef strVersion<span style=\"color:blue;\"> As String<\/span>, <span style=\"color:blue;\">Optional<\/span> ByRef strErgebnis<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> Fehler\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> db = OpenDatabase(strDatenbankpfad)\r\n     <span style=\"color:blue;\">Set<\/span> rst = db.OpenRecordset(\"SELECT * FROM tblVersion\", dbOpenSnapshot)\r\n     \r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rst.EOF<span style=\"color:blue;\"> Then<\/span>\r\n         datVersion = Nz(rst!Versionsdatum, 0)\r\n         strVersion = Nz(rst!Versionsnummer, 0)\r\n         VersionsdatumErmitteln = <span style=\"color:blue;\">True<\/span>\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         strErgebnis = \"Kein Versionsdatum gefunden.\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\nBeenden:\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rst Is Nothing<span style=\"color:blue;\"> Then<\/span> rst.Close\r\n     <span style=\"color:blue;\">Set<\/span> rst = Nothing\r\n     <span style=\"color:blue;\">Set<\/span> db = Nothing\r\n     <span style=\"color:blue;\">Exit Function<\/span>\r\nFehler:\r\n     strErgebnis = \"Fehler beim Lesen des Versionsdatums: \" & Err.Description\r\n     Resume Beenden\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Ermitteln der Versionsdaten aus der Tabelle tblVersion der jeweiligen Datenbank<\/span><\/b><\/p>\n<p>Sie deaktiviert die Fehlerbehandlung und &ouml;ffnet mit <b>OpenDatabase <\/b>die mit <b>strDatenbankpfad <\/b>&uuml;bergebene Datenbank. In dieser &ouml;ffnet sie ein Recordset auf Basis der Tabelle <b>tblVersion<\/b>. Wenn diese nicht leer ist, liest sie die Werte der Felder <b>Versionsdatum <\/b>und <b>Versionsnummer <\/b>in die R&uuml;ckgabeparameter <b>datVersion <\/b>und <b>strVersion <\/b>ein. Ist die Tabelle leer, wird die Meldung <b>Kein Versionsdatum gefunden <\/b>zur&uuml;ckgegeben.<\/p>\n<p>Falls ein Fehler auftritt, weil die Datenbank oder die Tabelle nicht gefunden werden kann, wird <b>strErgebnis <\/b>ebenfalls mit einer entsprechenden Meldung gef&uuml;llt. Anschlie&szlig;end schlie&szlig;t die Funktion alle ge&ouml;ffneten Elemente wieder und leert die Objektvariablen.<\/p>\n<h2>Datenbank aktualisieren<\/h2>\n<p>Finden wir auf dem Server eine neuere Version der Datenbankanwendung vor als auf dem Client, soll die Clientversion durch die des Servers ersetzt werden. Das erledigen wir mit der Funktion <b>KopiereServerdateiAufClient<\/b> (siehe Listing 4).<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>KopiereServerdateiAufClient(strClientpfad<span style=\"color:blue;\"> As String<\/span>, strServerpfad<span style=\"color:blue;\"> As String<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> strErgebnis<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strKopie<span style=\"color:blue;\"> As String<\/span>\r\n     strKopie = <span style=\"color:blue;\">Replace<\/span>(strClientpfad, \".accdb\", \"_Kopie.accdb\")\r\n     Name strClientpfad<span style=\"color:blue;\"> As <\/span>strKopie\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(Dir(strClientpfad)) = 0<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(Dir(strKopie)) = 0<span style=\"color:blue;\"> Then<\/span>\r\n             FileCopy strServerpfad, strClientpfad\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(Dir(strClientpfad)) = 0<span style=\"color:blue;\"> Then<\/span>\r\n                 KopiereServerdateiAufClient = <span style=\"color:blue;\">True<\/span>\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 strErgebnis = \"Neue Version konnte nicht kopiert werden.\"\r\n                 <span style=\"color:blue;\">Exit Function<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             strErgebnis = \"Zu aktualisierende Datenbank konnte nicht umbenannt werden\"\r\n             <span style=\"color:blue;\">Exit Function<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         strErgebnis = \"Zu aktualisierende Datenbank konnte nicht umbenannt werden.\"\r\n         <span style=\"color:blue;\">Exit Function<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     \r\n     KopiereServerdateiAufClient = <span style=\"color:blue;\">True<\/span>\r\n     \r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Aktualisieren der &auml;lteren Version mit der neuen Version der Datenbankanwendung<\/span><\/b><\/p>\n<p>Hier &uuml;bergeben wir wieder die Pfade zu den beiden Dateien. Im ersten Schritt definieren wir, wie wir die vorhandene, veraltete Version der Datenbankdatei auf dem Client umbenennen wollen, damit wir die neue Version gleichen Namens vom Server kopieren k&ouml;nnen.<\/p>\n<p>Dazu erg&auml;nzen wir einfach hinten die Zeichenkette <b>_Kopie<\/b> und benennen die Datei mit der <b>Name &#8230; As<\/b>-Anweisung um.<\/p>\n<p>Wir pr&uuml;fen, ob das Umbenennen erfolgreich war, indem wir auf das Vorhandensein einer Datei mit dem neuen Namen und das Fehlen der Datei mit dem alten Namen testen &#8211; wieder mithilfe der <b>Len<\/b>&#8211; und der <b>Dir<\/b>-Anweisung.<\/p>\n<p>War dies erfolgreich, kopieren wir die neue Version vom Server mit der <b>FileCopy<\/b>-Anweisung unter der Angabe des vorherigen Pfades auf den Clientrechner.<\/p>\n<p>Ist diese Datei anschlie&szlig;end auf dem Client vorhanden, liefert die Funktion den Wert <b>True<\/b> und mit <b>strErgebnis <\/b>eine passende Meldung zur&uuml;ck.<\/p>\n<p>In allen anderen F&auml;llen erfolgt die R&uuml;ckgabe des Wertes <b>False <\/b>und einer entsprechenden Meldung mit dem Parameter <b>strErgebnis<\/b>.<\/p>\n<h2>Aufruf beim Start der Startdatenbank<\/h2>\n<p>Weiter oben haben wir bereits die leere Funktion <b>StartDb <\/b>angelegt, die vom <b>AutoExec<\/b>-Makro aufgerufen wird.<\/p>\n<p>Diese erweitern wir nun wie in Listing 5. Hier rufen wir zuerst die Funktion <b>DatenbankAktualisieren <\/b>auf und &uuml;bergeben dieser die R&uuml;ckgabeparameter <b>strErgebnis <\/b>und <b>bolFehler<\/b>.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>StartDb()\r\n     <span style=\"color:blue;\">Dim <\/span>strErgebnis<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>bolFehler<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>bolStarten<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strDatenbankpfad<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">If <\/span>DatenbankAktualisieren(strErgebnis, bolFehler) = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> strErgebnis\r\n         bolStarten = <span style=\"color:blue;\">True<\/span>\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">If <\/span>bolFehler = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n             If <span style=\"color:blue;\">MsgBox<\/span>(\"Die Anwendung konnte nicht aktualisiert werden. Setzen Sie sich mit dem Administrator in \" _\r\n                     & \"Verbindung.\" & <span style=\"color:blue;\">vbCrLf<\/span> & strErgebnis, vbYesNo + <span style=\"color:blue;\">vbCr<\/span>itical, _\r\n                     \"Aktualisierung fehlgeschlagen\") = vbYes Then\r\n                 bolStarten = <span style=\"color:blue;\">True<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             bolStarten = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span>bolStarten = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n         strDatenbankpfad = CurrentProject.Path & \"\\\" & DLookup(\"DatenbanknameClient\", \"tblKonfiguration\")\r\n         Shell \"\"\"\" & SysCmd(acSysCmdAccessDir) & \"MSAccess.exe\"\" \"\"\" & strDatenbankpfad & \"\"\"\", vbNormalFocus\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Die Funktion StartDb mit dem Aufruf der Aktualisierungsfunktionen<\/span><\/b><\/p>\n<p>Liefert diese den Wert <b>True<\/b>, geben wir den Inhalt von <b>strErgebnis <\/b>in einem Meldungsfenster aus und stellen die Variable <b>bolStarten <\/b>auf <b>True <\/b>ein.<\/p>\n<p>Wenn nicht, pr&uuml;fen wir anhand der Variablen <b>bolFehler<\/b>, ob es ein Problem beim Aktualisieren gegeben hat oder ob einfach keine neuere Version vorhanden ist und deshalb keine Aktualisierung stattgefunden hat.<\/p>\n<p>Hat <b>bolFehler <\/b>den Wert <b>True<\/b>, geben wir eine Meldung mit der Fehlerbeschreibung aus und fragen, ob dennoch die aktuelle Version gestartet werden soll &#8211; dann stellen wir <b>bolStarten <\/b>auf <b>True <\/b>ein.<\/p>\n<p>Hat <b>bolStarten <\/b>anschlie&szlig;end den Wert <b>True<\/b>, stellen wir den Datenbankpfad auf Basis der Daten aus der Tabelle <b>tblKonfiguration <\/b>ein und &ouml;ffnen die Datenbankdatei mit dem <b>Shell<\/b>-Befehl.<\/p>\n<p>Dabei geben wir als zweiten Parameter <b>vbNormalFocus <\/b>an, damit das ge&ouml;ffnete Fenster direkt den Fokus erh&auml;lt.<\/p>\n<h2>AutoExec-Makro anpassen zum Schlie&szlig;en der Startdatenbank<\/h2>\n<p>Wir ben&ouml;tigen noch eine kleine Anpassung des <b>AutoExec<\/b>-Makros, damit dieses die Startdatenbank nach dem Aktualisieren und Starten der eigentlichen Datenbankdatei wieder schlie&szlig;t.<\/p>\n<p>Dazu f&uuml;gen wir noch den Befehl <b>BeendenAccess<\/b> hinzu und belassen die Option <b>Optionen <\/b>auf <b>Alles speichern <\/b>(siehe Bild 5).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1556_005.png\" alt=\"Neue Version des AutoExec-Makros\" width=\"499,5589\" height=\"180,6915\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Neue Version des AutoExec-Makros<\/span><\/b><\/p>\n<h2>Startdatenbank unsichtbar &ouml;ffnen<\/h2>\n<p>Nun wird die Startdatenbank ge&ouml;ffnet, f&uuml;hrt die gew&uuml;nschten Aktionen durch und wird dann nach dem &Ouml;ffnen der eigentlichen Datenbank wieder geschlossen. Das dabei ge&ouml;ffnete Access-Fenster irritiert dabei etwas &#8211; der Benutzer soll ja nichts von diesem Prozess mitbekommen, au&szlig;er im Erfolgsfall. Also blenden wir das Access-Fenster der Startdatenbank direkt aus, indem wir es mit einer entsprechenden Verkn&uuml;pfung starten beziehungsweise mit einer passenden Batch-Datei. So k&ouml;nnen wir auf einfache Weise das Anwendungsfenster ausblenden.<\/p>\n<p>Wir verwenden hier eine Verkn&uuml;pfung, die wir im Verzeichnis der Beispieldatenbanken mit dem Kontextmen&uuml;befehl <b>Neu|Verkn&uuml;pfung <\/b>anlegen. Danach &ouml;ffnen wir die Eigenschaften der Verkn&uuml;pfung (siehe Bild 6).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1556_006.png\" alt=\"Verkn&uuml;pfung zu einer Access-Datenbank\" width=\"424,5589\" height=\"552,4505\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Verkn&uuml;pfung zu einer Access-Datenbank<\/span><\/b><\/p>\n<p>Hier stellen wir f&uuml;r die Eigenschaft <b>Ziel <\/b>einen Wert wie den folgenden ein:<\/p>\n<pre>\"C:\\Program Files (x86)\\Microsoft Office\\root\\Office16\\MSACCESS.EXE\" \"Startdatenbank.accdb\"<\/pre>\n<p>Wichtig ist, dass wir hier den Namen der Datenbankdatei ohne Pfad angeben. Damit k&ouml;nnen wir die Verkn&uuml;pfung samt der aufgerufenen Datenbank auch in andere Verzeichnisse verschieben, ohne dass wir den Pfad anpassen m&uuml;ssen.<\/p>\n<p>Au&szlig;erdem w&auml;hlen wir unter <b>Ausf&uuml;hren <\/b>den Wert <b>Minimiert <\/b>aus. Damit erreichen wir das eigentliche Ziel, n&auml;mlich dass die Datenbank minimiert ge&ouml;ffnet wird.<\/p>\n<p>Auf diese Weise erscheint lediglich die Meldung, dass eine neue Version angelegt wurde oder gegebenenfalls eine Fehlermeldung, bevor die eigentliche Anwendung ge&ouml;ffnet wird.<\/p>\n<h2>Erweiterungsm&ouml;glichkeiten<\/h2>\n<p>Den Code dieser L&ouml;sung k&ouml;nnen Sie an verschiedenen Stellen erweitern oder anpassen. Wir k&ouml;nnten beispielsweise noch eine weitere Tabelle zur Startdatenbank hinzuf&uuml;gen, die eine Historie der Aktualisierungen auf dem aktuellen Rechner f&uuml;hrt.<\/p>\n<p>Oder wir f&uuml;gen die M&ouml;glichkeit hinzu, dass ein Dateiauswahl-Dialog erscheint, wenn die jeweils neue Version nicht vom Serververzeichnis abgerufen werden kann. So kann der Benutzer einfach den Quellpfad anpassen, der anschlie&szlig;end in der Tabelle <b>tblKonfigurationen <\/b>gespeichert wird.<\/p>\n<h2>Umgekehrter Fall: Startdatenbank aktualisieren<\/h2>\n<p>Es kann auch einmal vorkommen, dass die Startdatenbank aktualisiert werden muss &#8211; beispielsweise, weil sich der Pfad f&uuml;r die neuen Versionen der Produktivdatenbank &auml;ndert. Das erledigen wir genau umgekehrt: Die Startdatenbank &ouml;ffnet die Produktivdatenbank und in dieser bringen wir Code unter, der auf eine neue Version der Startdatenbank pr&uuml;ft. Hier m&uuml;ssen wir lediglich darauf achten, dass wie einen Formulartimer oder ein &auml;hnliches Werkzeug nutzen, um so lange zu warten, bis die Startdatenbank beendet ist. Anderenfalls k&ouml;nnen wir diese nicht ersetzen, wenn es eine neue Version gibt.<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>In diesem Beitrag haben wir gezeigt, wie sich Access-Datenbankanwendungen mit Hilfe einer Startdatenbank automatisch aktualisieren lassen.<\/p>\n<p>Die vorgestellte L&ouml;sung pr&uuml;ft beim Start, ob eine neuere Version der eigentlichen Anwendung auf einem Server bereitliegt, und ersetzt die lokale Version bei Bedarf. Dabei wird die Anwendung minimiert ge&ouml;ffnet und nach erfolgreicher Aktualisierung automatisch gestartet. Dieses Vorgehen eignet sich besonders f&uuml;r Netzwerkinstallationen mit mehreren Benutzern.<\/p>\n<p>In einem kommenden Beitrag zeigen wir, wie sich dieselbe Technik auch f&uuml;r verteilte Systeme nutzen l&auml;sst, bei denen Anwender ihre Updates direkt aus dem Internet beziehen &#8211; ideal f&uuml;r freigegebene L&ouml;sungen au&szlig;erhalb eines Firmennetzwerks.<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>Startdatenbank.zip<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/D8A4A06D-A298-4F07-BB44-BE7FA384F29C\/aiu_1556.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Access-Datenbankanwendungen sind bekanntlich niemals fertig. Das ist an sich kein Nachteil, sondern stellt eher einen Vorteil dar: Im Gegensatz zu fertigen Anwendungen, bei denen Anpassungen entweder gar nicht m&ouml;glich sind oder viel Geld kosten, kann man Access-Datenbanken einfach selbst um neue Funktionen erweitern. Spannend wird das, wenn die Datenbank von mehreren Nutzern eingesetzt wird. Dann stellt sich die Frage: Wie bekomme ich die neue Version einer Datenbank am einfachsten auf die unterschiedlichen Arbeitspl&auml;tze? Das gelingt auf verschiedene Arten, und in diesem Beitrag schauen wir uns eine an, mit der das Update vom Arbeitsplatz des Benutzers aus getriggert werden soll.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662025,66042025,44000027],"tags":[],"class_list":["post-55001556","post","type-post","status-publish","format-standard","hentry","category-662025","category-66042025","category-Loesungen"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Automatisches Update per Startdatenbank - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Automatisches Update per Startdatenbank\" \/>\n<meta property=\"og:description\" content=\"Access-Datenbankanwendungen sind bekanntlich niemals fertig. Das ist an sich kein Nachteil, sondern stellt eher einen Vorteil dar: Im Gegensatz zu fertigen Anwendungen, bei denen Anpassungen entweder gar nicht m&ouml;glich sind oder viel Geld kosten, kann man Access-Datenbanken einfach selbst um neue Funktionen erweitern. Spannend wird das, wenn die Datenbank von mehreren Nutzern eingesetzt wird. Dann stellt sich die Frage: Wie bekomme ich die neue Version einer Datenbank am einfachsten auf die unterschiedlichen Arbeitspl&auml;tze? Das gelingt auf verschiedene Arten, und in diesem Beitrag schauen wir uns eine an, mit der das Update vom Arbeitsplatz des Benutzers aus getriggert werden soll.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2025-08-03T11:25:47+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg01.met.vgwort.de\/na\/f0f901044c4f429cbc7063a661dd7264\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"19\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Automatisches Update per Startdatenbank\",\"datePublished\":\"2025-08-03T11:25:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/\"},\"wordCount\":3178,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/f0f901044c4f429cbc7063a661dd7264\",\"articleSection\":[\"2025\",\"4\\\/2025\",\"L\u00f6sungen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/\",\"name\":\"Automatisches Update per Startdatenbank - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/f0f901044c4f429cbc7063a661dd7264\",\"datePublished\":\"2025-08-03T11:25:47+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/f0f901044c4f429cbc7063a661dd7264\",\"contentUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/f0f901044c4f429cbc7063a661dd7264\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Automatisches_Update_per_Startdatenbank\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Automatisches Update per Startdatenbank\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Automatisches Update per Startdatenbank - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/","og_locale":"de_DE","og_type":"article","og_title":"Automatisches Update per Startdatenbank","og_description":"Access-Datenbankanwendungen sind bekanntlich niemals fertig. Das ist an sich kein Nachteil, sondern stellt eher einen Vorteil dar: Im Gegensatz zu fertigen Anwendungen, bei denen Anpassungen entweder gar nicht m&ouml;glich sind oder viel Geld kosten, kann man Access-Datenbanken einfach selbst um neue Funktionen erweitern. Spannend wird das, wenn die Datenbank von mehreren Nutzern eingesetzt wird. Dann stellt sich die Frage: Wie bekomme ich die neue Version einer Datenbank am einfachsten auf die unterschiedlichen Arbeitspl&auml;tze? Das gelingt auf verschiedene Arten, und in diesem Beitrag schauen wir uns eine an, mit der das Update vom Arbeitsplatz des Benutzers aus getriggert werden soll.","og_url":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/","og_site_name":"Access im Unternehmen","article_published_time":"2025-08-03T11:25:47+00:00","og_image":[{"url":"http:\/\/vg01.met.vgwort.de\/na\/f0f901044c4f429cbc7063a661dd7264","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"19\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Automatisches Update per Startdatenbank","datePublished":"2025-08-03T11:25:47+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/"},"wordCount":3178,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/f0f901044c4f429cbc7063a661dd7264","articleSection":["2025","4\/2025","L\u00f6sungen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/","url":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/","name":"Automatisches Update per Startdatenbank - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/f0f901044c4f429cbc7063a661dd7264","datePublished":"2025-08-03T11:25:47+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/#primaryimage","url":"http:\/\/vg01.met.vgwort.de\/na\/f0f901044c4f429cbc7063a661dd7264","contentUrl":"http:\/\/vg01.met.vgwort.de\/na\/f0f901044c4f429cbc7063a661dd7264"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Automatisches_Update_per_Startdatenbank\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Automatisches Update per Startdatenbank"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001556","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55001556"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001556\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001556"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001556"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001556"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}