Access 2010 Laufzeitfehler 3048 - "Mehr Datenbanken können nicht geöffnet werden."
-
Freitag, 16. November 2012 13:07
- 3-4 Frontend DB greifen permanent auf 11 Backend DB zu (auch mit VBA): Bekomme immer wieder folgende Fehlermeldungen: Laufzeitfehler 3048 - "Mehr Datenbanken können nicht geöffnet werden." und zu wenig Systemresourcen. Gefundene Lösung ConstMaxRsCount AsLong=10000 Dim rs() As Recordset ReDim rs(MaxRsCount) Gilt dies nur für den einen rs ? – Muß ich bei jeder Deklaration eines neuen rs wiederholen ?
- Beim Schließen eines Formulars mit vielen Unterformularen werden die rs´s geschlossen?
Alle Antworten
-
Freitag, 16. November 2012 15:12
1. ein Hallo oder ähnlichtes zu Beginn der Frage wäre schön, das hier ist keine kostenpflichtige Hotline.
2. Name wäre schön, dann könnte man Dich anreden.Hallo,
Wenn Du deinen Quelltext schickst, das Stück mit dem Teil um den es geht, wäre es leichter etwas sinnvolles zu schreiben.
Meine Kristallkugel ist bereits im Wochenende.
Wozu möchtest Du ein Recordset mit 1000 Elementen Dimensionieren, wenn es doch 11 Backends gibt?Warum möchtest Du die Recordsets offen halten und warum möchtest Du nicht mit einem einzigen Recordset arbeiten?
Was ist am anderen Ende, worauf greifst Du zu? Um Resourcen zu schonen, und um Folgefehler zu vermeiden sollten Recordsets geschlossen werden.
Um Recourcen zu schonen und Folgefehler zu vermeiden sollten Recordsets mit Bedacht und in geringer Anzahl geöffnet werden.Grüße Alexander
-
Freitag, 16. November 2012 16:57
Hallo Alexander,
wollte nicht unhöflich sein, sorry.
Beschreibung:
Meine DB ist eine sehr große KursverwaltungsDB in welcher alle Daten der Teilnehmer, Kurse, Anwesenheiten, usw. gehalten werden.
Ein Hauptformular mit einigen UF und mit VBA gesteuerten Einträgen, Verwaltungsformulare mit vielen UF, die ich per VBA aufrufe und ebenso per Doppelklick Formulare in Word und Excel ausfülle.
Nun mehren sich in letzter Zeit die beschriebenen Fehlermeldungen und leider nicht an der gleichen Stelle. Dann Access schließen wieder aufmachen und es geht wieder.
VBA:
Innerhalb der Funktionen (sehr sehr viele) öffne ich ein neues Recordset, am Ende setze ich es nothing.
Derzeit habe ich es umgeschrieben(noch nicht fertig), arbeite ein rs in einer Collection ab und fülle diese dann mit den weiteren Informationen auf, um mehrfaches Öffnen eines rs in div. Funktionen zu vermeiden.
Deine Frage nach den Quelltext ist schwer zu erfüllen, da ich alleine 45 Module habe und fast jedes Formular VBA-Anweisungen enthält.
Hier ein Code-Schnipsel wie ich auf die div. DB´s zugreife:
Private Sub ColFelderBOErstellen(dat As Date)Dim sql As StringDim rs As Recordset
Dim Anz As IntegerDim ID As Integer
Dim n As String
Dim ColZeileBO As Collection
Dim i As Integer
Set colFelder = New Collection
sql = mxSQL.BOMitNameKomplett
Set rs = mDatenbank.db.OpenRecordset(sql, dbOpenDynaset)
Do While Not rs.EOF
Set ColZeileBO = New Collection
ID = rs.Fields("BO.ID")
n = rs.Fields("BONameKomplett")
With ColZeileBO
.Add ID, "ID"
.Add n, "BOName"
End With
colFelder.Add ColZeileBO
rs.MoveNext
Loop
Set rs = Nothing
For i = 1 To colFelder.Count
colFelder.Item(i).Add AnzahlTNProBO(dat, CInt(colFelder.Item(i)(eBO.IDBO))), "Anzahl"
colfelderTNErstellen i, dat
Next i
Set rs = Nothing
End Sub
In mDatenbank initialisiere ich die DB, in mxSQL befinden sich alle SQL-Strings, bzw. Stringteile.
Vielleicht kannst Du mir einen guten Tipp geben, wie ich die beschriebenen Fehler verhindern kann.
Herzlichen Dank für Deine Bemühung und nochmals sorry!
Elisabeth
- Bearbeitet GRIDL Elisabeth Freitag, 16. November 2012 16:58
-
Freitag, 16. November 2012 17:39
Hallo Elisabeth,
nein den Teil mit den MaxConnections kann ich nicht sehen.
Dieser Teil sieht sauber aus, ein Set Rs=nothing zuviel, doch das soll nicht entscheidend sein.
Nur wozu brauchst Du die große Anzahl von Recordsets?
Kannst Du einen Auschnitt zeigen mit :Recordset ReDim rs(MaxRsCount)?Grüße Alexander
-
Freitag, 16. November 2012 20:30
Lieber Alexander!
Herzlichen Dank für Deine prompte Antwort. Das Recordset mit ReDim habe ich noch nicht gemacht, da ich dem gegenüber etwas skeptisch war, daher auch meine Eingangsfragen.
Wenn ich den rs neu dimensioniere betrifft das nur den erstellten rs, oder hält Access die Möglichkeit der höhere Anzahl der rs in der gesamten DB?
Die Menge der rs entsteht, da ich die Daten aus verschiedensten Tabellen, und DB zusammenfassen muss. Bis jetzt hatte ich in einer Funktion einen rs erstellt, dann die ID in die nächste Funktion geschickt und erst am Ende alle rs wieder geschlossen. Nach massiven Auftreten dieses Problemes fülle ich Collection´s um nur einen offen zu haben, d.h. ich stopple die Daten erst in einer Collection zusammen und gebe sie erst dann aus. Das Problem hat sich aber leider nicht wesentlich geändert.
Ich las im Forum, dass nur 232 rs offen sein dürfen, und dies betreffe auch die auf Abfragen basierenden Formulare und Unterformulare. Könnte dort ein Problem auftreten? Ich lade beim Start einen 4 TreeView`s auf Registersteuerelement mit Namen um beim Klick-Ereignis sämtliche Daten des Kursteilnehmers darzustellen, auf diesem Form ist auch ein Button z.B. für die Verwaltung, die viele Tabelle direkt beschreibt, ebenso ein Zugang zu Anwesenheiten, wo diese unter verschiedenen Aspekten dargestellt wird. Sowohl die Anwesenheiten, als auch die Verwaltung sind natürlich zusätzlich geöffnet, werden allerdings nach dem Eintrag wieder geschlossen.
D.h. es könnten viele Zugriffe gleichzeitig stattfinden. Daher schien mir das ReDim eine Option.
Hardwaretechnisch ist alles geklärt, 8 GB Ram, Virtueller Arbeitsspeicher auf max 3072 gesetzt.
Bin derzeit am Ende meiner Weisheit.
Liebe Grüße
Elisabeth
-
Freitag, 16. November 2012 21:24Moderator
Hallo,
GRIDL-EDV wrote:
1. 3-4 Frontend DB greifen permanent auf 11 Backend DB zu (auch mit VBA):
Bekomme immer wieder folgende Fehlermeldungen: Laufzeitfehler 3048 -
"Mehr Datenbanken können nicht geöffnet werden." und zu wenig
Systemresourcen. Gefundene Lösung
ConstMaxRsCount As Long=10000
Dim rs() As Recordset
ReDim rs(MaxRsCount)
Gilt dies nur für den einen rs ? – Muß ich bei jeder Deklaration eines neuen rs wiederholen ?Die Vorgehensweise ist unueblich. Man oeffnet Recordsets, wenn man sie braucht, und schliesst sie danach wieder. Die "saubere" vorgehensweise ist:
Dim Db As DAO.Database Dim Rst As DAO.Recordset Set Db = CurrentDb Set Rst = Db.OpenRecordset("SELECT whatever FROM wherever", dbOpenDynaset) Do While Not Rst.EOF 'dein Code Rst.MoveNext Loop Rst.Close Set Rst = Nothing Set Db = NothingDabei ist durchaus erlaubt, innerhalb der Schleife weitere Recordsets zu
oeffnen. Meist ist das aber nicht noetig, weil man per Aktionsabfrage
schneller ans Ziel kommt.2. Beim Schließen eines Formulars mit vielen Unterformularen werden die
rs´s geschlossen?Und was passiert im Fehlerfall? Ich wuerde an deiner Stelle die
Vorgehensweise umstellen.Gruss - Peter
Mitglied im http://www.dbdev.org
FAQ: http://www.donkarl.com -
Samstag, 17. November 2012 07:30
Hallo Peter
Danke für deine Antwort, ich habe db nicht in der function nothing gesetzt, sondern in mDatenbank, werde ich machen, vielleicht hilft das. Im übrigen habe ich so wie du beschrieben hast das gesamte Ding programmiert, erst nach auftreten dieser Fehlermeldungen drehte ich alles um und öffnete einen rs, füllte eine Collection, schloss den rs wieder, übergab die collection und befüllte sie mit weiteren Daten. Half aber nicht wirklich, nur schneller wurde es.
Bei meiner 2. Frage meinte ich nicht VBA Funktionen, sondern an Abfragen gebundene Formulare und Unterformulare.
Nochmals danke für deine Bemühungen hoffe, dass der Fehler dann weg ist.
LG Elisabeth
-
Montag, 19. November 2012 17:47
Hallo Elisabeth,
sieh Dir 'mal diesen Thread an, vielleicht hilft der Dir weiter:
http://social.msdn.microsoft.com/Forums/de-DE/accessde/thread/2a6b77d0-cfbb-4b0c-a738-926860ad0870
Gruß
Giorgio
-
Montag, 19. November 2012 18:36
Hallo Giorgio,
lieben Dank für Deine Bemühung, ich fürchte, dass ich es so ähnlich machen muss, da trotz Wochenendarbeit, inklusive Nacht nur eine geringe Besserung eingetreten ist. Werde Formulare komplett über vba steuer und redimen. Hoffentlich funktioniert es dann, da hier über den Test in Access 2003 gesprochen wird und meine DB läuft auf 2010.
LG Elisabeth
-
Dienstag, 20. November 2012 05:19
Hallo Elisabeth
"GRIDL Elisabeth" schrieb
Innerhalb der Funktionen (sehr sehr viele) öffne ich ein neues
Recordset, am Ende setze ich es nothing...
In mDatenbank initialisiere ich die DB, in mxSQL befinden sich alle
SQL-Strings, bzw. Stringteile.Mit den RS hat das wenig zu tun. Lies' nochmals die Fehlermeldung: "Mehr Datenbanken ...".
Das Limit ist IIRC bei 255 Datenbanken. Da Du diese in einer eigenen Funktion zu verwalten scheinst, solltest Du diese mal herzeigen. Sonst wissen wir ja gar nicht, was Du da bastelst.Grundsätzlich ist es so, dass Du die Database Instanzen jeweils wieder vernichten solltest, wenn Du diese nicht mehr brauchst. Das geht aber nur, wenn Du alle Objekte, die Du darin geöffnet hast, ebenfalls schliesst und vernichtest.
Dieser klassischer Code ohne Collection und anderes neumodisches Zeugs funktioniert problemlos:
Dim db as Database
Set db = CurrentDB()
set rs1 = db.openrecordset (.....)
set rsN = db.openrecordset (.....)
.....
rs1.Close
rsN.Close
set rs = Nothing
set db = NothingWenn Du diesen Code verwendest, dann kannst Du sooft Du willst und aus so vielen Datenbanken wie Du willst, Recordsets öffnen. Wenn Du (z.B. aus Performance Gründen) die Datenbank Instanz lieber re-usen möchtest, dann gibt es noch den CurrentDBC Ansatz. Hier ein Beispiel, wie das gemacht werden kann:
http://www.access-entwicklerbuch.de/2007/index.php?page=buch&bookpage=Kap_09/05.htmlGruss
Henry -
Dienstag, 20. November 2012 17:50Moderator
Hallo,
Henry Habermacher schrieb folgendes:
ersetzte set rs = Nothing
aus Henrys Code noch durch:
set rs1 = Nothing
set rsN = NothingGruß
Gunter
Access FAQ: http://www.donkarl.com
http://www.avenius.de - http://www.AccessRibbon.de
http://www.ribboncreator.de - http://www.ribboncreator2010.de -
Dienstag, 20. November 2012 18:09
Hallo Henry,
setze alle deklarierten rs`s am Ende der function oder sub wieder nothing und jetzt auch vorher das close. Konnte dadurch das Problem zumindest eingrenzen, aber nicht beheben. Beim Öffnen eines Zusatzformulares mit einigen Unterformularen kommt es jetzt vermehrt zu dieser Meldung. Offensichtlich muss ich die Bindung der Formulare kappen und erst beim Klickereignis ihnen den mit reDim definierten RS zuweisen.
LG Elisabeth
-
Dienstag, 20. November 2012 19:18
Hallo Ihr
Hier mein Code in mDatenbank:
Option Compare Database
Dim mDB As Database
Public Property Get db() As Database
If mDB Is Nothing Then
DatenbankInitialisieren
Set db = mDB
Else
Set db = mDB
End If
End Property
Public Property Let db(Value As Database)
Set mDB = Value
End Property
Public Sub DatenbankInitialisieren()
db = CurrentDb
End Sub
Public Sub RSSchließen(rs As Recordset)
If Not rs Is Nothing Then
rs.Close
Set rs = Nothing
End If
If Not mDB Is Nothing Then
Set mDB = Nothing
End If
End SubSo sind alle Function´s und Sub´s deklariert:
Private Sub Ausstieg()
Dim rs As Recordset
Dim sql As String
sql = "select * from Massnahme_Teilnehmer"
Set rs = mDatenbank.db.OpenRecordset(sql, dbOpenDynaset)
Do While Not rs.EOF
If IsNull(rs.Fields("IDAustrittsStatus")) Then
rs.Edit
rs.Fields("IDAustrittsStatus") = 1
rs.Update
End If
rs.MoveNext
Loop
mDatenbank.RSSchließen rs
End SubWo ist mein Fehler ?????
- Bearbeitet GRIDL Elisabeth Dienstag, 20. November 2012 19:33
- Bearbeitet GRIDL Elisabeth Dienstag, 20. November 2012 19:34
-
Mittwoch, 21. November 2012 02:11
Hallo Elisabeth
Wenn ich diesen Code anschaue wird mir schwindelig. Was bastelst Du da blos? Benutze doch einfach die Standard Vorgehensweisen, um Daten zu bearbeiten. Vezichte auf Collections und und komplizierte Ansätze um die Objekte zu initialisieren, etc. Siehe auch den Link, den ich Dir bereits geschickt hatte.
Dann noch ein kleiner Hinweis bezüglich der letzten Funktion, die Du da aufgeführt hast:
Private Sub Ausstieg()
Dim rs As Recordset
Dim sql As String
sql = "select * from Massnahme_Teilnehmer"
Set rs = mDatenbank.db.OpenRecordset(sql, dbOpenDynaset)
Do While Not rs.EOF
If IsNull(rs.Fields("IDAustrittsStatus")) Then
rs.Edit
rs.Fields("IDAustrittsStatus") = 1
rs.Update
End If
rs.MoveNext
Loop
mDatenbank.RSSchließen rs
End SubSowas lässt sich einfacher und massiv effizienter über einen Bulk Update lösen, ohne ein Recoirdset sequentiell abzuarbeiten.
Private Sub Ausstieg() Dim sql As String sql = "UPDATE Massnahme_Teilnehmer SET IDAustrittsStatus = 1 WHERE IDAustrittsStatus IS NULL" mDatenbank.db.Execute strSQL, dbFailOnError + dbSeeChanges End Sub
Das ist wesentlich schneller und läuft in einem Wish druch. Du brauchst kein Recordset, um diesen Update auszuführen und schon gar nicht ein sequentielles Abarbeiten der Tabelle. Selbst wenn Du unbedingt sequentielle abarbeiten willst, solltest Du die WHERE Bedingung so setzen, dass Du bereits beim Instanziieren des Recordsets auf NULL prüfst.
Und schliesslich: Ich würde auch hier nicht über das komplizierte mDatenbank Konstrukt gehen. Mach's besser konventionell und vernichte am Schluss das Database Objekt wieder.
Gruss
Henry
-
Mittwoch, 21. November 2012 05:03
Hallo Henry,
Da hast du recht, aber das ist noch immer nicht der Grund für den Fehler: Mehr Datenbanken können nicht geöffnet werden, da ich in der Funktion rs öffne und wieder schließe. Ich suche den Grund für die Fehlermeldung. Tritt derzeit beim 2. mal Öffnen eines Formulares am häufigsten auf, dieses hat 5 Unterformulare, welche ab Abfragen gebunden sind.
????????
-
Mittwoch, 21. November 2012 06:16
Du bist nicht zu überzeugen, dass es hier nicht um die Recordsets, sondern um die Database Objekte handelt, gell?
Wenn es beim zweiten Öffnen eines Formulares auftritt, das 5 UFOs hat, dann sollte es doch eigentlich möglich sein, dieses mal vom unkonventionellen Ansatz zu befreien oder dann halt im Debug Modus durch den Code durchzugehen, bis der Fehler auftritt. Wenn Du mit dem erwähnten CurrentDBC Model arbeitest, dann kann der Fehler nicht auftreten, da in diesem Fall nur genau 1 Database Instanz vorhanden ist, die immer wieder verwendet wird. Ich vermute eher, dass bei Deinem Ansatz etwas schief läuft. Beispielsweise weil Du hier:
If mDB Is Nothing Then DatenbankInitialisieren Set db = mDB Else Set db = mDB End If
keinen Error Handler verwendest. Falls die Prüfung mDB Is Nothing schiefläuft, wirst Du DatenbankInitialisieren aufrufen. Was dann passiert, kann ich nicht sagen. Du setzt dann DB() auf eine neue CurrentDB Instanz, ob die alte dabei vernichtet wird, weiss ich nicht. Evt. bleibt diese noch bestehen, weil Du darin noch Recordset Instanziiert hast.
Also zuerst mal überall einen vernünftigen Error Handler reinmachen:
Public/Private Function/Sub ... (...) AS ... On Error GoTo ProcErr ... Dein Code ProcExit: Exit Sub/Function ProcErr: MsgBox "Fehler " & Err.Number & ": " & Err.Description Resume ProcExit End Function/Sub
Wenn dann ein Fehler auftritt, findest Du heraus, wo der Auslöser ist.
Und nochmals: Komm' weg von Deinem unkonventionellen Ansatz. Vergiss' all das Zeugs in mDatenbank mit Properties und solchen Dingen. Verwende den konventionellen oder den CurrentDBC Ansatz und es wird keine Probleme mit dem genannten Fehler mehr geben. Ich habe wesentlich komplexere Formulare mit wesentlich mehr UFOs und komplexen verschachtelten Datenbank Zugriffen in VBA und habe diesen Fehler erst wenige male gesehen, als ich in einem Loop vergessen hatte, eine Database Instanz wieder zu vernichten oder wenn ich ein Formulare mit zu vielen Domain Aggregat Funktionen (DLookup(), DSum(), DCount(), etc.) zugepflastert hatte.
Gruss
Henry
-
Donnerstag, 22. November 2012 04:47
Danke Henry, werde am Wochenende die DB umbauen und die Fehlerüberprüfung einbauen.. Hoffentlich komme ich dann der Ursache auf den Grund.
LG Elisabeth
-
Donnerstag, 22. November 2012 10:37Moderator
Hallo,
GRIDL Elisabeth wrote:
werde am Wochenende die DB umbauen und die Fehlerüberprüfung einbauen..
Hoffentlich komme ich dann der Ursache auf den Grund.Wenn du die DB wie von Henry und mir vorgeschlagen umbaust, wird die
Ursache nicht mehr existieren. ;-)Gruss - Peter
Mitglied im http://www.dbdev.org
FAQ: http://www.donkarl.com -
Donnerstag, 20. Dezember 2012 10:51
Herzlichen Dank an alle, die sich um mein Problem gekümmert haben.
Lösung gefunden: seit dem letzten Update war tatsächlich die Anzahl der Forms und Steuerelemente zu viele, umgebaut und jetzt funktioniert es.
Gruß an alle
Elisabeth

