Symptome
SPEED Ferret stürzt beim Durchsuchen einer bestimmten Datenbank ab, arbeitet mit anderen Datenbanken aber normal.
Problem
Die Datenbank enthält eines oder mehrere Objekte mit ungültigen Metadaten.
Hintergrund
Metadaten beschreiben das Design Ihrer Datenbank. Access verwaltet diese Daten in Systemtabellen und anderen internen Datenstrukturen. Zusätzlich zu den primären Metadaten, die Sie bearbeiten, wenn Sie zum Beispiel die Eigenschaften eines Objektes ändern, verwaltet Access sekundäre Metadaten, die aus den primären Daten abgeleitet und zwischengespeichert werden um die Ausführungsgeschwindigkeit zu erhöhen. Beispielsweise speichert Access zwei Versionen jedes VBA Moduls, dass Sie anlegen. Die primäre Version enthält den Code und die sekundäre Version enthält eine compilierte Version des Codes. Ähnliches gilt für Abfragen, wo Access einen Ausführungsplan anlegt und optimiert der vom eigentlichen SQL Ausdruck des Abgfrageentwurfs abgeleitet wird.
Beim laufenden Bearbeiten eines Projekts aktualisiert Access die sekundären Metadaten kontinuierlich und inkrementell um sie mit den Primärdaten zu synchronisieren. In seltenen Fällen kann diese Synchronisierung fehlschlagen was dann zu Problemen führt.
SPEED Ferret verwendet die Microsoft DAO Objektbibliothek um die Eigenschaften von Objekten aus der Access Datenbank auszulesen. Wenn die Sekundärdaten nicht synchronisiert sind, kann dies zu einem Schutzverletzungsfehler führen. Da DAO als DLL innerhalb des SPEED Ferret Prozesses ausgeführt wird, bringt dies den kompletten SPEED Ferret Prozess unweigerlich zum Absturz.
Erster Test
Führen Sie eine Suche aus, die nur die Abfragen in Ihrer Datenbank enthält. Für eine Projekt Namens Projekt1 können Sie hierfür folgenden Objektfilter verwenden: {Projekt1.Queries.*}
Wenn SPEED Ferret bei dieser Suche abstürzt, sind die Jet Metadaten beschädigt. Ansonsten liegt das Problem wahrscheinlich bei den VBA Metadaten.
VBA Metadaten reparieren
Diese Anleitung verwendet den von Microsoft nicht dokumentierten und nicht supporteten Kommandozeilenparameter /decompile. Wir empfehlen dringend, die hier beschriebene Vorgehensweise nur an einer Kopie und nicht mit Ihrer Originaldatenbank durchzuführen. Nach Lokalisierung des Objekts, welches den Fehler auslöst, können Sie eventuelle Änderungen an der Originaldatenbank durch Überschreiben des Fehlerobjekts mit einer korrigierten Variante vornehmen.
- Starten Die msaccess.exe mit dem nicht dokumentierten Kommandozeilenparameter /decompile
- Öffnen Sie Ihre Datenbank mit dem Datei/Öffnen Befehl. Jeglicher sekundärer VBA Metacode wird nun verworfen.
- Kompilieren Sie die Datendank erneut (Anmerkung: Das Kommando Kompilieren bewirkt normalerweise nur eine inkermentelle Kompilierung um die bestehenden Metadaten zu aktualisieren. Da in diesem Fall jedoch, durch alle Metadaten verworfen wurden, wird der kompletten Code neu kompiliert und so alle Synchronisierungsfehler behoben.)
- Schließen Sie die Datenbank.
Jet Metadaten reparieren
Fügen sie den folgenden Quellcode in ein neues Modul ein und geben Sie im Direktfenster (Drücken Sie STRG+G um das Direktfenster zu Öffnen) folgende Kommandozeile ein: QueryCheck
Drücken Sie dann die ENTER-Taste.
Der Code erzeugt eine Datei namens c:\journal.txt. Jedesmal, wenn der Code eine Abfrage durchsucht, wird der Name der Abfrage am Ende der Datei journal.txt angehägt. Wenn Ihre Datenbank eine beschädigte Abfrage enthält, wird Access abstürzen. Öffnen Sie dann die Datei c:\journal.txt. Die letzte Zeile der Datei enthält den Namen der beschädigten Abfrage. Um die Abfrage zu reparieren, Öffnen Sie sie einfach in Entwurfsansicht und speichern sie. Dann starten Sie Access erneut und lassen Sie den Code nochmals ausführen um zu prüfen, ob weitere Abfragen beschädigt sind.
Anmerkung: Wenn eine Abfrage mit Namen wie "TMPCLPnnnnn" auftaucht, ist dies ein temporäres, verstecktes Objekt. Schließen Sie Ihre Access Sitzung und Öffnen Sie die Datenbank erneut, dann wird das temporäre Objekt nicht mehr enthalten sein.
Sub QueryCheck()
Dim DB As DAO.Database
Dim QueryDef As DAO.QueryDef
Dim FileNo As Long
Dim SccStatus As Long
Set DB = Application.CurrentDb
For Each QueryDef In DB.QueryDefs
FileNo = FreeFile
Open "c:\journal.txt" For Append As #FileNo
Print #FileNo, "Query '" + QueryDef.Name + "'? ";
Close #FileNo
On Error Resume Next
SccStatus = QueryDef.Properties("SccStatus")
On Error GoTo 0
FileNo = FreeFile
Open "c:\journal.txt" For Append As #FileNo
Print #FileNo, "OK"
Close #FileNo
Next
End Sub