Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.
Es gibt verschiedene Möglichkeiten, auf die Daten einer SQL Server-Datenbank zuzugreifen. Die einfachste Variante, wenn es um die Migration einer reinen Access-Datenbank in eine Kombination aus Access-Frontend und SQL Server-Backend geht, ist der Einsatz ODBC-verknüpfter Tabellen. Dabei werden die Tabellen einfach nur zum SQL Server migriert und man greift dann über ODBC-Verknüpfungen auf die Tabellen zu. Für den Zugriff auf diese Daten von Formularen aus ergeben sich so gut wie keine änderungen – und was sich doch ändern kann, erfahren Sie in diesem Beitrag.
Wenn Sie eine Datenbank von Access zum SQL Server migrieren, übertragen Sie die Tabellen im Optimalfall 1:1 auf die SQL Server-Datenbank. Ist das der Fall, haben Sie recht gute Karten, dass Sie Ihre Anwendung recht schnell auch mit der neuen Datenherkunft läuft.
Wie das geht Indem Sie einfach die Tabellen der SQL Server-Datenbank per ODBC mit der Access-Anwendung verknüpfen. Wenn Sie dabei darauf achten, dass die Verknüpfungen anschließend die gleichen Namen wie die zuvor verwendeten Tabellen haben, sollten die Abfragen, Formulare, Berichte und auch der VBA-Code, der auf die Daten zugreift, anstandslos funktionieren.
Wir schauen uns das einmal an. In unserer Beispieldatenbank finden Sie zwei Formulare, die Ihnen bei der Verknüpfung der Tabellen behilflich sind und Ihnen viel Zeit sparen können. Das erste Formular heißt frmVerbindungszeichenfolgen. Hier legen Sie mit der Schaltfläche Neu eine neue Verbindungszeichenfolge an und geben dann ihre Eigenschaften ein. Ein Beispiel finden Sie in Bild 1 – hier testen wir auch gleich noch die Funktionalität der Verbindungszeichenfolge.
Bild 1: Verbindungszeichenfolge definieren und testen
Das zweite hilfreiche Formular heißt frmTabellenVerknuepfen. Mit diesem wählen Sie als Erstes die soeben definierte Verbindungszeichenfolge aus und selektieren dann bei gedrückter Strg-Taste die zu verknüpfenden Tabellen – in diesem Fall tblArtikel, tblBestelldetails, tblBestellungen, tblKategorien, tblKunden, tblLieferanten, tblPersonal und tblVersandfirmen (siehe -Bild 2).
Bild 2: Hinzufügen der zu verknüpfenden Tabellen
Nach einem Klick auf die Schaltfläche Tabellen verknüpfen landen die Verknüpfungen dann im Navigationsbereich, wo sie mit dem entsprechenden Symbol angezeigt werden (siehe Bild 3).
Bild 3: Die per ODBC verknüpften Tabellen
Zeitstempel
Die Tabellen wurden mit dem SQL Server Migrations-Assistenten für Access in eine SQL Server-Datenbank migriert. Dabei stellt dieser sicher, dass jede Tabelle ein Timestamp-Feld erhält. Dieses sieht in einer frisch migrierten Datenbank erst einmal wie in Bild 4 aus – das Feld ist zunächst scheinbar leer.
Bild 4: Tabelle mit Timestamp-Feld
Wenn Sie sich dieses Feld jedoch im SQL Server Management Studio ansehen, sind die Werte dieses Feldes mit Daten des Typs
Bild 5: Tabelle mit Timestamp-Feld im SQL Server Management Studio
Warum aber wollen wir unsere SQL Server-Tabellen mit einem Zeitstempel versehen – und was ist der Zeitstempel, unter SQL Timestamp, überhaupt Zunächst einmal: Das Timestamp-Feld ist nicht etwa ein Feld, welches die aktuelle Systemzeit etwa beim ändern oder Anlegen eines Datensatzes speichert.
Es hat auch nicht das Format eines Datumsfeldes. Es ist vielmehr ein Feld, das einen binären Wert speichert, der beim Anlegen oder ändern eines Datensatzes eingetragen wird und der einzigartig ist.
Damit sorgen Sie für verschiedene Effekte:
- Sie vereinfachen die Untersuchung, ob ein Datensatz seit dem Beginn der Bearbeitung durch einen anderen Benutzer geändert wurde und ob eine entsprechende Meldung angezeigt werden muss.
- Sie verhindern Fehler, die durch unterschiedliche Fließkomma-Datentypen auftreten können.
Datensatzänderungen prüfen
Bevor Sie einen Datensatz im SQL Server nach der Bearbeitung etwa in einem Formular speichern können, muss der SQL Server prüfen, ob eventuell ein anderer Benutzer in der Zwischenzeit ebenfalls änderungen an diesem Datensatz durchgeführt hat. Ist das der Fall, erhalten Sie eine Meldung wie in Bild 6.
Bild 6: Fehlermeldung bei Schreibkonflikt
Wie lösen Sie diesen Fehler aus Dazu haben wir die Tabelle tblKategorien, die in der Beispieldatenbank bereits ein Timestamp-Feld enthält, nochmals in eine neue Tabelle namens tblKategorien1 kopiert, die kein Timestamp-Feld enthält. Außerdem haben wir für diese Tabelle eine ODBC-Verknüpfung namens tblKategorien1 in der Access-Datenbank erstellt. Dann haben wir zwei Formulare namens frmKategorien1 und frmKategorien2 erstellt, die beide die ODBC-Verknüpfung tblKategorien1 referenzieren.
Beide Formulare öffnen Sie und platzieren diese so, dass beide Formulare sichtbar sind. Dann ändern Sie den Datensatz im ersten Formular, speichern die änderung aber noch nicht. Hier setzen wir den Wert des Feldes Kategoriename auf Kategorie 2. Achten Sie darauf, dass der Datensatzmarkierer das Bearbeiten-Symbol anzeigt (siehe Bild 7).
Bild 7: ändern des Datensatzes im ersten Formular
Nun ändern Sie den Wert des gleichen Feldes im zweiten Formular auf Kategorie 3 und speichern die änderung dort durch einen Klick auf den Datensatzmarkierer (siehe Bild 8). Schließlich versuchen Sie im Anschluss, auch die änderungen im ersten Formular per Klick auf den Datensatzmarkierer zu speichern. In diesem Moment erscheint die oben vorgestellte Meldung.
Bild 8: ändern und Speichern des Datensatzes im zweiten Formular
Die Meldung hält zwei Optionen bereit:
- In Zwischenablage kopieren: Aktualisiert den Datensatz im Formular, wodurch die im zweiten Formular geänderte Version angezeigt wird. Die Version des Datensatzes, die im ersten Formular gespeichert wurde, landet dann in der Zwischenablage. Von dort können Sie diesen dann über den aktuellen Datensatz schreiben und doch noch speichern.
- Eigene änderungen verwerfen: Diese Option verwirft einfach die änderungen im ersten Formular und aktualisiert dieses mit dem im zweiten Formular geänderten Datensatz.
Noch eine Fehlermeldung
Interessanterweise gibt es noch eine zweite Konstellation, unter der eine Fehlermeldung beim ändern eines Datensatzes angezeigt wird – und zwar schon beim Versuch, auch nur den Inhalt eines Feldes zu bearbeiten. Um dies nachzustellen, verwenden Sie wieder die gleichen beiden Formular frmKategorien1 und frmKategorien2. Geben Sie nun in frmKategorien1 für das Feld Kategoriename beispielsweise den Wert Kategorie 0 ein. Speichern Sie den Datensatz diesmal direkt.
Anschließend wechseln Sie zum Formular frmKategorien2 und versuchen, den Inhalt des Feldes Kategoriename anzupassen. Schon beim Eintippen des ersten Zeichens erscheint die Fehlermeldung aus Bild 9. Dies gilt übrigens für alle Steuer-elemente des Formulars.
Bild 9: Fehlermeldung beim Versuch, einen bereits geänderten Datensatz von einem anderen Formular aus nochmals zu ändern
Wichtig: Um dies reproduzieren zu können, muss der im anderen Formular editierte und gespeicherte Datensatz bereits im ersten Formular angezeigt werden. Wenn Sie den Datensatz erst nach der Bearbeitung im anderen Formular laden oder diesen erst aktualisieren, können Sie ihn ohne Probleme bearbeiten.
Fehlernummer ermitteln
Aber woher kommt dieser Fehler Wir wollen erst einmal die Fehlernummer ermitteln, um dann weitere Nachforschungen anstellen zu können. Fehler, die in Formularen auftreten, aber nicht per VBA ausgelöst werden, kommt man nicht auf herkömmliche Weise auf die Spur – also indem man einfach die Fehlernummer per Err.Number abfragt. Stattdessen müssen wir in diesem Fall wir die Ereignisprozedur Form_Error bemühen, die wir für die Ereigniseigenschaft Bei Fehler des Formulars anlegen (in diesem Fall nur für das Formular frmKategorien2).
Die Ereignisprozedur statten wir zunächst nur mit einer einzigen Anweisung aus:
Private Sub Form_Error(DataErr As Integer, Response As Integer) MsgBox DataErr End Sub
Danach führen wir die oben angegebenen Schritte erneut aus. Dies liefert die Meldung aus Bild 10 mit der Nummer 7878.
Bild 10: Ausgabe der Fehlernummer bei Reproduzierung des zweiten Fehlers
Wenn wir schon einmal dabei sind, können wir auch gleich die Fehlernummer des weiter oben ausgelösten Fehlers ermitteln. Dieser lautet, wie Bild 11 zeigt, nur etwas anders, nämlich 7787.
Bild 11: Ausgabe der Fehlernummer bei Reproduzierung des ersten Fehlers
Um die Fehlertexte der beiden Fehler zu ermitteln, können wir die Funktion AccessError im Direktbereich des VBA-Fensters absetzen. Für den Fehler 7878 ergibt sich Folgendes:
AccessError(7878) Die Daten wurden geändert.@Ein anderer Benutzer hat diesen Datensatz bearbeitet und die von ihm vorgenommenen änderungen gespeichert, bevor Sie versucht haben, Ihre änderungen zu speichern.@Bearbeiten Sie den Datensatz erneut.@1@@@1
Für den Fehler 7787 liefert diese Funktion interessanterweise keine Fehlermeldung.
Fehlermeldungen durch benutzerdefinierte Fehlermeldung ersetzen
Wenn Sie denken, dass die Benutzer Ihrer Datenbankanwendung nicht mit der vom System erzeugten Meldung arbeiten können, lässt sich diese natürlich auch durch eine benutzerdefinierte Meldung ersetzen.
Für den Fehler 7787, der beim zwischenzeitlichen ändern des gleichen Datensatzes an anderer Stelle ausgelöst wird, erledigen wir dies wie in Listing 1.
Private Sub Form_Error(DataErr As Integer, Response As Integer) Select Case DataErr Case 7878 MsgBox "7878" Case 7787 MsgBox "Der Datensatz wurde in der Zwischenzeit an anderer Stelle geändert." & vbCrLf & vbCrLf _ & "Ihre änderungen werden verworfen, aber in der Zwischenablage gespeichert." & vbCrLf & vbCrLf _ & "Um Ihre Version zu übernehmen, markieren Sie den Datensatz und drücken Sie Strg + V." Response = acDataErrContinue Case Else End Select End Sub
Listing 1: Neue Fehlermeldung für den Fehler mit der Nummer 7787
Dabei prüfen wir in einer Select Case-Bedingung den Wert des Parameters DataErr. Lautet dieser auf 7787, zeigen wir eine Meldung an, die den Benutzer über das Problem und die Möglichkeiten aufklärt (siehe Bild 12). Aber wo sind hier im Vergleich zur Systemmeldung die beiden Auswahlmöglichkeiten Ganz einfach: Die haben wir herausgekürzt. In diesem Fall haben wir nämlich nicht die Möglichkeit, individuell auf die Benutzereingabe zu reagieren. Wie aber können wir dem Benutzer die Möglichkeit offen halten, dass er trotz der übernommenen änderungen durch einen anderen Benutzer dennoch seine eigenen änderungen durchsetzen kann Und geht das überhaupt, wenn wir die Ursprungsmeldung mit den beiden Optionen gar nicht mehr anzeigen
Bild 12: Neue, benutzerdefinierte Meldung beim Versuch, einen Datensatz zu ändern, der zwischenzeitlich an anderer Stelle geändert wurde.
Ja, das geht. Den Hinweis auf die Vorgehensweise geben wir in der Meldung. Nach dem Benutzer diese bestätigt hat, weisen wir dem Parameter Response der Prozedur noch den Wert acDataErrContinue zu. Das sorgt dafür, dass die Systemmeldung unterdrückt wird.
Immerhin sichert Access in diesem Fall aber den Inhalt des Datensatzes, den der aktuelle Benutzer bearbeitet hat, in der Zwischenablage – so kann dieser seine Version des Datensatzes über den durch den anderen Benutzer geänderten Datensatz kopieren.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
Testzugang
eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel
diesen und alle anderen Artikel mit dem Jahresabo