DAO-Fehler in Microsoft Visual Basic 6.5, nicht in 6.0

29/03/2014 - 01:43 von Wolfgang Enzinger | Report spam
Sorry für den EyeCatcher im Subject ... ;-)

Mit "Microsoft Visual Basic 6.5" ist natürlich VBA in MS Office 2003 (Access)
gemeint, aber MS nennt das nun mal so ...

Jedenfalls habe ich da vorhin eine verblüffende Erfahrung gemacht. Folgende
einfache Routine (Referenz auf DAO 3.6 ist gesetzt):


Sub Main()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim t As DAO.TableDef
Set db = DBEngine.Workspaces(0).OpenDatabase("c:\test.xls", _
False, False, "Excel 5.0;")
Set t = db.CreateTableDef("Tabelle1")
t.Fields.Append t.CreateField("Feld1", dbText)
db.TableDefs.Append t
Set rs = db.OpenRecordset("SELECT * FROM Tabelle1", _
dbOpenDynaset, dbAppendOnly)
rs.AddNew '<<<<-
'Fehler 3027: Aktualisieren nicht möglich; Datenbank
'oder Objekt ist schreibgeschützt.
rs.Fields(0).Value = "hallo!"
rs.Update
rs.Close
db.Close
End Sub

In VBA tritt bei .AddNew der - ungerechtfertigte - Fehler 3027 auf; in VB6
làuft alles anstandslos durch, anschliessend steht das "hallo!" in der
Tabelle.

Was mir vor allem nicht in den Kopf will: beide Tests laufen auf dem gleichen
Rechner, also wird wohl das gleiche Binary angesprochen (gerade
vorsichtshalber nochmal nachgeschaut: dao360.dll gibt's zwar zweimal, aber in
der exakt gleichen Version). Woher "weiss" DAO, ob es unter VB oder VBA làuft?
Und warum der Unsinn unter VBA?

Bei mir nachvollziehbar in der Kombination
* Windows 7 - Office 2013 - VB6

Eben noch getestet in der Kombination
* Windows 2000 - Office 97 - VB5

Da geht beides. Seltsam.

Irgendeine Idee?

...

Wo wir gerade bei DAO sind, noch zwei Erkenntnisse, die ich diese Woche
herausdestilliert habe:

* Prozess A öffnet eine Access-DB *exklusiv* zum Lesen (readonly). Prozess B
tut genau das Selbe. Ohne Probleme. Hallo? Unter "exklusiv" hàtte ich jetzt
was anderes verstanden.

* Der Klartext zu Fehlermeldungen (Err.Description) speziell bei .OpenDatabase
ist teilweise eher geeignet Verwirrung zu stiften als Klarheit zu schaffen.
Daher hier eine kleine Übersetzungshilfe für die hàufigsten Fehlernummern:

l = Err.Number
s = Err.Description

Select Case l 'in der nachstehenden Reihenfolge prüft auch DAO
'(ausser Schreibschutz-Attribut, das offenbar als
'letztes geprüft wird)
Case 3051
'Standardmeldung:
' Das Microsoft Jet-Datenbankmodul kann die Datei 'xxx.mdb' nicht öffnen.
' Sie ist bereits von einem anderen Benutzer exklusiv geöffnet, oder Sie
' benötigen eine Berechtigung, um die Daten lesen zu können.
'Korrekturbedarf:
' "bereits von einem anderen Benutzer exklusiv geöffnet" ist Unsinn; in
' diesem Fall würde Fehler 3045 geworfen
If (Not ReadOnly) And IsReadOnlyAttributeSet(DBName) Then
s = "Das Schreibschutz-Attribut der Datei " & DBName & " ist gesetzt"
Else
s = "Sie haben nicht die notwendigen Dateisystemberechtigungen für " _
& "Datei '" & DBName & "'"
Select Case True
Case Left$(DBName, 2) = "\\", GetDriveType(Left$(DBName, 2)) _
= DRIVE_REMOTE
s = s & ", oder Sie haben keine ausreichenden Berechtigungen " _
"für die zugrundeliegende Freigabe"
End Select
End If
Case 3045
'Standardmeldung:
' 'xxx.mdb' konnte nicht verwendet werden; Datei wird bereits verwendet.
'Korrekturbedarf:
' "bereits verwendet" wàre ja per se nicht weiter schlimm; es fehlt der
' entscheidende Hinweis, dass sie bereits *exklusiv* geöffnet ist
s = "Die Datei '" & DBName & "' ist durch einen anderen Prozess " _
& "exklusiv" geöffnet"
Case 3050
'Standardmeldung:
' Datei konnte nicht gesperrt werden
'Korrekturbedarf:
' *Warum* konnte die Datei nicht gesperrt werden? Es fehlt der Hinweis,
' dass das Anlegen bzw. Schreiben der .ldb-Datei fehlgeschlagen ist
Debug.Assert Not (ReadOnly And Exclusive) '<- in diesem Fall wird keine
'LDB angelegt
s = "Fehlende Schreibberechtigung im Verzeichnis"
Case 3356
'Standardmeldung:
' "Sie haben versucht, eine Datenbank zu öffnen, die
' bereits exklusiv von Benutzer 'yyy' auf Computer 'zzz' geöffnet ist.
' Versuchen Sie es nochmals, wenn die Datenbank verfügbar ist.
'Korrekturbedarf:
' Dies ist nicht unbedingt richtig. Der Fehler tritt auch auf, wenn man
' *selbst* exklusiven Zugriff anfordert und dies daran scheitert, dass
' die DB bereits durch einen anderen Prozess geöffnet ist (exklusiv oder
' nicht).

Debug.Assert Not ReadOnly 'bei nur lesendem Zugriff kann eine DB mehrfach
'(!) exklusiv (!) geöffnet werden

i = InStr(1, s, "t ist. Vers")
If i Then
'erstmal das bescheuerte "Versuchen Sie es nochmals ..." wegschneiden
s = Left$(s, i + 5)
End If

If Exclusive Then
'ggfs. Bezug des Wortes "exklusiv" korrigieren
If Mid$(s, 58, 10) = " exklusiv " Then
s = Left$(s, 57) & Mid$(s, 67)
End If

If Mid$(s, 31, 8) = "bank zu " Then
s = Left$(s, 35) & "exklusiv" & Mid$(s, 35)
End If
End If
End Select
On Error GoTo 0
Err.Raise l, "DAO", "Fehler beim Öffnen der Datenbank '" & DBName & "': " & s
End Function

In der Hoffnung, dass es jemandem nützt, der so wie ich hàufiger Ferndiagnosen
stellen muss ... ;-)

Viele Grüsse,
Wolfgang
http://www.enzinger.net
 

Lesen sie die antworten

#1 Anton Bayer
29/03/2014 - 11:26 | Warnen spam
* Prozess A öffnet eine Access-DB *exklusiv* zum Lesen (readonly). Prozess
B
tut genau das Selbe. Ohne Probleme. Hallo? Unter "exklusiv" hàtte ich
jetzt
was anderes verstanden.



Exklusiv, so verstehe ich das bisher, bezieht sich nur aufs Schreibrecht,
lesen dürfen andere, nur schreiben nicht. Ob der Exklusiv-Prozeß nun
schreiben will oder nicht ist für die anderen Prozesse ohne Bedeutung.

Nur wenn der Exklusiv-Prozeß im r/w-Mode öffnet, so würde ich erwarten,
sollten andere auch nicht lesen dürfen, da dann ja die gelesenen Daten
inkonsistent sein könnten, bei r/o eben genau nicht.

Ähnliche fragen