Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

238 views
Skip to first unread message

Wolfgang Enzinger

unread,
Mar 28, 2014, 8:43:26 PM3/28/14
to

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

Anton Bayer

unread,
Mar 29, 2014, 6:26:48 AM3/29/14
to
> * 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.

Ulrich Möller

unread,
Mar 29, 2014, 4:32:53 PM3/29/14
to
Hallo Wolfgang,

das sind ja eine ganze Menge von Informationen, die die
unterschiedlichsten Aspekte in Verbindung mit DAO ansprechen und zudem
auch noch in verschiedenen Kombination: einmal Windows7/Office2013/vb6,
vba/access2003 (OS-Angabe fehlt!) und dann von W2k/office97/vb5.
Abgesehen davon fehlen jede Information bezüglich 32/64Bit. Vielleicht
solltest du das erstmal sortieren und nicht alles durcheinander werfen.

Ein paar kleine Anmerkungen:

Fehler: 3027
Ob der Fehler "ungerechtfertigt" ist, weiß ich nicht, aber nähere
Informationen hierzu unter
http://support.microsoft.com/?kbid=904953 oder auch
http://www.donkarl.com/?FAQ7.22.

Das du hier einen Zugriff über einen ISAM-Treiber aus vb6/vba auf Excel
machst, hätte ich fast übersehen. Kein Hinweis deinerseits darauf. =-O

Exklusiv:
Wenn du mit DAO eine Datenbank exklusiv öffnest, ist sie auch exklusiv
eröffnet und jeder weiterer Versuch, diese aus einem anderen Prozess
nochmal zu öffnen, führt unweigerlich zu einem entsprechendem Fehler.
Wenn du etwas anderes meinst, würde ich dich bitten, das etwas nähere
auszuführen.

Fehlermeldungen:
Das Error-Objekt in VBA/VB6 entspricht dem Errorobjekt von der DBEngine
mit der höchsten Nummer, also DBEngine.Errors.Count -1. Nähere
Informationen aus den verschiedenen Ebenen erhält man über das Auslesen
der Error-Auflistung des DBEngine-Objekts.

Des weiteren empfehle ich die Hilfedatei "DAO360.CHM" , in der vieles zu
DAO Objekten und deren Methoden/Eigenschaften nachgelesen werden kann.

Ulrich








Wolfgang Enzinger

unread,
Mar 31, 2014, 5:07:04 PM3/31/14
to
"Anton Bayer" <aba...@sofort-mail.de> wrote:

>Exklusiv, so verstehe ich das bisher, bezieht sich nur aufs Schreibrecht,
>lesen dürfen andere, nur schreiben nicht.

Offensichtlich ist das so, nur geht das aus der Doku nicht hervor, da steht
nur: "Wenn Sie eine Datenbank im exklusiven Modus öffnen, hindern Sie andere
am Öffnen der Datenbank.".

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

Stimmt schon, so richtig leuchtet der Bedarf an "exklusiv lesen" nicht ein,
aber es mag ihn dennoch geben; schliesslich wird das vom Dateisystem, im
Gegensatz zu DAO, genau so implementiert, wie ich das erwartet hätte:

On Error Resume Next

Open "c:\test.txt" For Binary Access Read Lock Read As #1
Open "c:\test.txt" For Binary Access Read Shared As #2
Debug.Assert Err.Number = 70 'Zugriff verweigert
Close #1

Open "c:\test.txt" For Binary Access Read Write Lock Read Write As #1
Open "c:\test.txt" For Binary Access Read Write Shared As #2
Debug.Assert Err.Number = 70 'Zugriff verweigert
Close #1

Open "c:\test.txt" For Binary Access Read Lock Read Write As #1
Open "c:\test.txt" For Binary Access Read Write Shared As #2
Debug.Assert Err.Number = 70 'Zugriff verweigert
Close #1

Open "c:\test.txt" For Binary Access Read Write Lock Read Write As #1
Open "c:\test.txt" For Binary Access Read Shared As #2
Debug.Assert Err.Number = 70 'Zugriff verweigert
Close #1

Wolfgang Enzinger

unread,
Mar 31, 2014, 5:16:54 PM3/31/14
to
Am Sat, 29 Mar 2014 21:32:53 +0100 schrieb Ulrich Möller:

[Fullquote entsorgt]

> das sind ja eine ganze Menge von Informationen, die die
> unterschiedlichsten Aspekte in Verbindung mit DAO ansprechen und zudem
> auch noch in verschiedenen Kombination: einmal Windows7/Office2013/vb6,
> vba/access2003 (OS-Angabe fehlt!) und dann von W2k/office97/vb5.
> Abgesehen davon fehlen jede Information bezüglich 32/64Bit. Vielleicht
> solltest du das erstmal sortieren und nicht alles durcheinander werfen.

Bitteschön:

* Windows7 (64bit) / Office2003 (32bit) / vb6 (32bit)
* Windows 2000 (32bit) / Office97 (32bit) / vb5 (32bit)

Office 2013 war ein Typo.

Ich glaube dennoch nicht, dass das eingangs geschilderte Phänomen etwas mit
32 / 64 bit zu tun hat, aber wer weiss, vielleicht spielt ja auch der
Prozessortyp eine Rolle ...

> Ein paar kleine Anmerkungen:
>
> Fehler: 3027
> Ob der Fehler "ungerechtfertigt" ist, weiß ich nicht, aber nähere

Ist er. Datenbank und Recordset werden glasklar zum Schreiben geöffnet, und
es spricht nichts dagegen, diesem Ansinnen zu entsprechen (also kein
Schreibschutz oder ähnliches). VB5/6 schaffen das ja auch.
Da geht's um verknüpfte Tabellen, das hat mit meinem Thema nichts oder nur
sehr entfernt was zu tun.

> Das du hier einen Zugriff über einen ISAM-Treiber aus vb6/vba auf Excel
> machst, hätte ich fast übersehen. Kein Hinweis deinerseits darauf. =-O

Sorry, ich dachte es genügt, wenn das im Sourcecode steht ...

> Exklusiv:
> Wenn du mit DAO eine Datenbank exklusiv öffnest, ist sie auch exklusiv
> eröffnet und jeder weiterer Versuch, diese aus einem anderen Prozess
> nochmal zu öffnen, führt unweigerlich zu einem entsprechendem Fehler.

Eben nicht.

> Wenn du etwas anderes meinst, würde ich dich bitten, das etwas nähere
> auszuführen.

Ja mei, was soll ich da noch näher ausführen ... es ist eben so, dass du
ein und dieselbe Access-DB mit zwei verschiedenen DAO.Database-Objekten
exklusiv readonly öffnen kannst. Gleichzeitig. Ob das im gleichen Prozess
stattfindet oder in unterschiedlichen Prozessen auf dem selben Rechner oder
in unterschiedlichen Prozessen auf unterschiedlichen Rechnern, das spielt
keine Rolle. Probier's mal aus.

> Fehlermeldungen:
> Das Error-Objekt in VBA/VB6 entspricht dem Errorobjekt von der DBEngine
> mit der höchsten Nummer, also DBEngine.Errors.Count -1. Nähere
> Informationen aus den verschiedenen Ebenen erhält man über das Auslesen
> der Error-Auflistung des DBEngine-Objekts.

Bekannt, führt im Kontext aber auch nicht weiter. Bei allen von mir
angeführten Varianten eines gescheiterten Öffnens einer Access-DB ist

DBEngine.Errors.Count = 0
DBEngine.Errors(0).Number = Err.Number
DBEngine.Errors(0).Description = Err.Description

und somit bin ich nach wie vor der Ansicht, dass die Fehlerbeschreibung in
diesen Fällen verbesserungsbedürftig ist.

> Des weiteren empfehle ich die Hilfedatei "DAO360.CHM" , in der vieles zu
> DAO Objekten und deren Methoden/Eigenschaften nachgelesen werden kann.

Ahja? Danke auch für den Tipp ...

JETERR40.chm ist übrigens auch recht lesenswert.

Wolfgang Enzinger

unread,
Mar 31, 2014, 5:32:08 PM3/31/14
to
Wolfgang Enzinger <we_u...@nurfuerspam.de> wrote:

kleine Korrektur ...

>Bekannt, führt im Kontext aber auch nicht weiter. Bei allen von mir
>angeführten Varianten eines gescheiterten Öffnens einer Access-DB ist
>
-- DBEngine.Errors.Count = 0

++ DBEngine.Errors.Count = 1

Ulrich Möller

unread,
Apr 2, 2014, 6:42:11 AM4/2/14
to
Hallo Wolfgang,

ich habe das mit dem "exklusiv" öffnen nochmal unter Access 2010
ausprobiert.

Tatsächlich können zwei Prozesse gleichzeitig ein und dieselbe db
exklusiv/ro öffnen, was dem umgangssprachlichem Begriff von "exklusiv"
meines Erachtens nicht ganz gerecht wird.
Allerdings verhindert diese Art von Zugriff recht zuverlässig, das ein
anderer Prozess sich Schreibrechte beschafft. Ich kann also darauf
vertrauen, daß kein anderer Prozess die Daten verändern kann. Öffne ich
dagegen eine db explizit mit exklusiv/rw kann kein anderer Prozess die
db mehr öffnen, auch nicht ro. Hier stimmt es dann wieder.

"exklusiv/ro" habe ich zwar selber noch nie eingesetzt, ich könnte mir
das aber bei in vba geschriebenen externen CodeBibliotheken gut
vorstellen. Da möchte ich auf keinen Fall, das diese während der
Benutzung irgendwie verändert werden können.

Grüße

Ulrich







Wolfgang Enzinger

unread,
Apr 2, 2014, 6:07:47 PM4/2/14
to
Wolfgang Enzinger <we_u...@nurfuerspam.de> wrote:

>* Windows7 (64bit) / Office2003 (32bit) / vb6 (32bit)
>* Windows 2000 (32bit) / Office97 (32bit) / vb5 (32bit)
>
>Office 2013 war ein Typo.

Weitere Tests zum Thema "Exceltabelle mit DAO 3.6 bearbeiten" (was wie gesagt
unter VB5/6 problemlos geht):

* Windows XP (32bit), Office 2007 (32bit; Microsoft Visual Basic 6.5)
* Windows 7 (64bit), Office 2010 (32bit; Microsoft Visual Basic for
Applications 7.0)

Mit diesen beiden Setups geht's auch nicht, allerdings hat das Phänomen jetzt
eine eigene Fehlernummer bekommen:

Fehler 3823
"Sie können das Feld nicht bearbeiten, da es sich in einer verknüpften
Excel-Kalkulationstabelle befindet.
In dieser Access-Version wurde das Bearbeiten von Daten in einer verknüpften
Excel-Kalkulationstabelle deaktiviert."

Was natürlich gleich doppelt falsch ist, denn weder handelt es sich um eine
verknüpfte Tabelle, noch wurde hier irgendwas "in dieser Version deaktiviert",
vielmehr ging es zehn Jahre vorher (Office 97) auch schon nicht.

Allmählich frage ich mich, ob wir nicht eher froh sein sollten, dass VB6
eingefroren wurde - immerhin bleiben uns auf diese Weise derartige
"Verbesserungen" erspart.

Zum anderen bleibt die Frage, wie ein und dieselbe COM-Komponente (DAO) unter
VB resp. VBA ein derart unterschiedliches Verhalten an den Tag legen kann.
Legt VBA - im Gegensatz zu VB - da noch eine zusätzliche "Kontrollschicht"
zwischen sich und das COM-Objekt?

Wolfgang Enzinger

unread,
Apr 2, 2014, 6:07:52 PM4/2/14
to
Ulrich Möller <knob...@usenet.arcornews.de> wrote:

>ich habe das mit dem "exklusiv" öffnen nochmal unter Access 2010
>ausprobiert.

Jo, Doku lesen ist gut, aber zusätzlich selber ausprobieren ist oftmals
allemal erhellender ... ;-)

>Tatsächlich können zwei Prozesse gleichzeitig ein und dieselbe db
>exklusiv/ro öffnen, was dem umgangssprachlichem Begriff von "exklusiv"
>meines Erachtens nicht ganz gerecht wird.

Sehe ich genauso, siehe auch meine Antwort an Anton Bayer.

>Allerdings verhindert diese Art von Zugriff recht zuverlässig, das ein
>anderer Prozess sich Schreibrechte beschafft. Ich kann also darauf
>vertrauen, daß kein anderer Prozess die Daten verändern kann. Öffne ich
>dagegen eine db explizit mit exklusiv/rw kann kein anderer Prozess die
>db mehr öffnen, auch nicht ro. Hier stimmt es dann wieder.
>
>"exklusiv/ro" habe ich zwar selber noch nie eingesetzt, ich könnte mir
>das aber bei in vba geschriebenen externen CodeBibliotheken gut
>vorstellen. Da möchte ich auf keinen Fall, das diese während der
>Benutzung irgendwie verändert werden können.

Einen weiteren Vorteil dieses unerwarteten Verhaltens sehe ich darin, dass man
auf diese Weise - auch mehrfach - Datenbanken zum Lesen öffnen kann, die in
einem Verzeichnis liegen, für das man nur Leserechte hat. Die meisten Admins
misstrauen - sicherlich nicht ganz zu Unrecht - ihren Anwendern und geben
ihnen deshalb nur die minimal erforderlichen Rechte, was das Dateisystem
und/oder die Verzeichnisfreigabe betrifft. Da ich bisher davon ausging, dass
exklusiv eben exklusiv ist und daher Schreibrechte für die LDB-Datei
erforderlich sind, sobald mehrere User gleichzeitig eine Access-DB lesen
sollen, gab das mit so manchem Admin längere Diskussionen. Die subtile
Erkenntnis, dass man, wenn man scheinbar *mehr* Rechte (exklusiv!) anfordert,
mit *weniger* Rechten (Lesen genügt) auskommt, ändert die Sachlage nicht
unwesentlich ... ;-)

Moch Ingo

unread,
Apr 4, 2014, 4:31:16 AM4/4/14
to
War da nicht vor 10 oder mehr Jahren
eine Patentverletzung seitens
Microsoft, woraufhin die Editierbarkeit von Text- und
Exceldateien via DAO eingeschränkt wurde?

Schuss ins Blaue: mit VB6 wurde das nicht ausreichend getestet.
Access macht ja mehr mit DAO, als es von einer anden Sprache aus
offensteht.
--




----Android NewsGroup Reader----
http://www.piaohong.tk/newsgroup

Wolfgang Enzinger

unread,
Apr 9, 2014, 6:56:48 PM4/9/14
to
Wolfgang Enzinger <we_u...@nurfuerspam.de> wrote:

>Wo wir gerade bei DAO sind,

Das wird jetzt mein persönlicher Ingrid-Tread hier ... ;-)

Egal, noch was zur OpenDatabase-Methode, was mir bisher auch nicht klar war
und sich nicht direkt intuitiv erschliesst (in Ermangelung eines Hinweises in
der Dokumentation):

Öffnet man eine kennwortgeschützte Access-DB ohne Angabe des Passworts oder
unter Angabe eines falschen Passworts, gibt's einen Fehler, soweit klar.
Öffnet man hingegen eine DB unter Angabe eines Passworts, obwohl die DB gar
nicht kennwortgeschützt ist, klappt das Öffnen ohne Fehler.

Das klingt jetzt auf den ersten Blick vielleicht wenig spektakulär, aber mir
hat das eine schön gedachte Absicherungsstrategie ausgehebelt, zum Glück
bislang ohne ernsthafte Konsequenzen.

Nur für den Fall, dass jemand einen ähnlichen Ansatz verfolgt hat ...
0 new messages