Registriert seit: 26.09.2022
Version(en): 2019
Moinsen, für mich ergibt sich aus deinen vielen Beiträgen noch kein guter Zusammenhang. Und ein einheitliches Fehlerbild kann ich auch nicht erkennen. Einen Objektverweis auf Nothing zu setzen ist dem Objekt im Zweifel egal. Im konkreten Beispiel hilft vielleicht die Onlinehilfe weiter. Die .OpenRecordset-Methode von DAO hat hat mehrere Parameter, darunter den Type, der den Zugriff auf die einzelnen Records des Recordsets festlegt und den LockEdit-Parameter, der bestimmt, wie mit parallelen Zugriffen umgegangen werden soll. insbsesondere den LockType, der festlegt, wie mit parallelen Zugriffen umgegangen werden soll. Dabei geht es aber eher um (auch) schreibende Zugriffe. Wenn ich das richtig sehe, willst du aber ein ReadOnly Recordset verwenden. Hierzu gibt es den Parameter Options, der du unter anderem den dbReadOnly Wert zuweisen kannst. Doku bei MicrosoftDeinen anderen Beiträgen entnehme ich, dass du gelegentlich noch einen Access-Prozess beenden musst. Mit welchem Treiber greifst du auf die Datenbank zu? Viele Grüße derHöpp
Registriert seit: 22.09.2024
Version(en): 2010
@derHöpp:
Das ist alles schon gesagt, beantwortet und erklärt worden. Wo fehlt dir da der Zusammenhang? Das es sich um DAO handelt, ist bereits in in der Fragestellung erwähnt worden.
Bei einer MDB-Datenbankdatei ist es eigentlich egal, ob die DAO 3.6 Engine oder die neuere Access Database Engine verwendet wird, allerdings wird das neuere Datenbankformat ACCDB nur von letzterem unterstützt.
Gruß Ulrich
Registriert seit: 10.04.2014
Version(en): 97-2019 (32) + 365 (64)
... vielleicht kann man noch darauf hinweisen - auch wenn das schon geschrieben wurde - dass es da um Parameter für das Recordset geht. Es geht nicht um SQL-Befehle. Ich vermute, dass es für den TE bei den "abgekürzten" SQL-Befehlen um weggelassene Recordset - Parameter gehen könnte. Das für bestimmte Aktionen bestimmte Parameter Voraussetzung sein können, sei mal dahingestellt.
Wenn es um Geschwindigkeit geht, ist oftmals auch Excel die Bremse - z.B., weil die Daten einzeln abgegriffen und irgendwo in Zellen gepackt werden. Man kann ein Recordset aber auch komplett in ein Array holen, z.B. mit arrDyna() = objDynaset.GetRows() Es ist auch relevant, ob Du auf mehrere Tabellen zugreifen musst oer ob Du eine Art "View" hast, der dir die Daten schon aufbereitet bereitstellt.
. \\\|/// Hoffe, geholfen zu haben. ( ô ô ) Grüße, André aus G in T ooO-(_)-Ooo (Excel 97-2019+365)
Folgende(r) 1 Nutzer sagt Danke an schauan für diesen Beitrag:1 Nutzer sagt Danke an schauan für diesen Beitrag 28
• Stefan1
Registriert seit: 26.09.2015
Version(en): 2013
06.11.2024, 21:38
(Dieser Beitrag wurde zuletzt bearbeitet: 06.11.2024, 21:38 von Stefan1.)
Ich habe zusätzlich zu dbOpenForwardOnly im Zusammenspiel mit MoveNext oder nur einmaligen Treffersuche nun auch das dbOpenSnapshot im Zusammenspiel mit MoveFirst oder mehreren nicht indexierten Treffer beim OpenRecordSet (DAO) erfolgreich eingebaut bei Anwendungen Word/Excel mit VBA-Zugriff auf Access-Datenbanken. Besonders da wo dbOpenForwardOnly jetzt zum Einsatz kommt, sind die Abfragen spürbar schneller und ich würde sagen das zusätzliche Attribute dient auch der Stabilität allgemein. Wahrscheinlich könnte man noch besser optimieren und ich kann mir MoveNext bei mehreren Treffern oder auch MoveFirst den Vorteil bzw. Anwending nicht ganz vorstellen, weil bislang in einem Loop durchaus erfolgreich eines dieser beiden möglichen Attribute fehlen und doch Treffer erfolgen. Ich muss dazu sagen, dass ich die VBA-Programmierung nicht ursprünglich angelegt habe. Es ist quasi ein "Erbstück2. Dann frage ich mich, was denn der Vorteil von MoveFrist oder MoveNext den sein könnte (wieso nicht weglassen), höchstens bei einer vorgängigen Sortierung nach einem Kriterium noch verständlich. Zur Sicherheit und fehlerfreien Abarbeitung belasse ich es bei entsprechenden Kriterien beim dbOpenSnapshot, wenn das auch geringfügig langsamer ist als dbOpenForwardOnly und doch immer noch wesentlich schneller als der Defaultwert dbOpenDynaset, auch beim Fehlen dieser Eigenschaft.
Nochmals Danke an Euch für die Unterstützung. Den Vorschlag mit arrDyna() = objDynaset.GetRows() werde ich noch studieren, der ist interessant. Ob ein ReadOnly im DAO-Verfahren noch sinnvoll angewendet werden kann, bin nicht sicher ob das MultiUser-Anwendung oder eben die Datenaktualisierung (Neu, Mutation) von einer Drittanwendung einen Vorteil bringen könnte?
Registriert seit: 22.09.2024
Version(en): 2010
Hallo Stefan,
je weniger Ressourcen ein Objekt verbraucht, desto effizienter kann es sein. Wenn also ein Recordset nur ForwardOnly unterstützen muss, ist das natürlich ressourcenschonender als wenn das Recordset Locks, mögliche Updates und konkurrierende Zugriffe verwalten muss.
Grundsätzlich geht es ja um Zugriffe per SQL auf die Daten, auch wenn man nur Tabellen angeben kann. SQL hat viel mit Mengen zu tun und die Ergebnismenge einer solchen Abfrage wird in einem Recordset zugänglich gemacht bzw. verwaltet. Mit seinen Methoden Move... wird dann der Cursor entsprechend der Move-Methode innerhalb des Recordsets datensatzweise weiter bewegt. Will man also alle Datensätze der Ergebnismenge nacheinander ansprechen, geht das mit diesen Move-Methoden innerhalb einer Schleife.
Zusätzlich gibt es beim DAO Recordset auch die Möglichkeit, mit GetRows() mehrere DS als Array abzurufen (näheres in der Doku).
In Excel gibt es außerdem auch noch eine Methode Range.CopyFromRecordset, womit ein Recordset einer Range zugewiesen werden kann. Hinweis dazu: das funktioniert nur bedingt fehlerfrei bei großen Ergebnismengen.
Gruß Knobbi38
Folgende(r) 1 Nutzer sagt Danke an knobbi38 für diesen Beitrag:1 Nutzer sagt Danke an knobbi38 für diesen Beitrag 28
• Stefan1
Registriert seit: 26.09.2015
Version(en): 2013
Guten Tag miteinanderarr
Kann mit dbOpenForwardOnly oder dbOpenSnapshot auch arrDyna() = objDynaset.GetRows() abgerufen werden oder ist das nur mit dbOpenDynaset möglich?
Das arrDyna() soll als Variant deklariert (Dim arrDyna() as Variant) sein und bei mehreren Treffer soll es Transponiert im Array sein. Was ist bei einem einzelnen Treffer? Wahrscheinlich nicht transponiert? Wie kann man das mit VBA sauber abfangen und mit einer Schlaufe auslesen. Da findet sich fast kein wirklich saubes Beispiel, das auch rasch und sicher ist.
Gruss Stefan1
Registriert seit: 16.08.2020
Version(en): 2019 64bit
Hallo Stefan, anbei mal ein Beispiel, wie eine Tabelle aus eines Access Datenbank Via DAO in ein Array (arr) geladen wird und in einer Listbox (Control in Userform) ausgegeben wird. Der Arrayinhalt ist prinzipbedingt in den Koordinaten vertauscht und wird deshalb via .Column in die Listbox geladen. Wenn dies für den restlichen nachfolgenden Code falls vorhanden stört, kann man bei kleineren Datenmengen Application.Transpose nutzen. Bei großen Datenaufkommen ist es besser den nachfolgenden Code entsprechend anpassen. (Early Binding und gerade durch ist das bessere Timing). Code: Option Explicit Private db As DAO.Database Private rs As DAO.Recordset
Private Sub AusAccessLesen() Dim i&, j&, k&, arr() ' Verweis auf Microsoft Office 16.0 Access Database Engine Object Library erforderlich da Early Binding Set db = OpenDatabase("C:\MeineDatenbank.accdb", False, False, ";PWD=MeinGeheimesPasswort") Set rs = db.OpenRecordset("MeinTabellenName", dbOpenDynaset) With rs Do Until .EOF k = k + 1 ReDim Preserve arr(1 To .Fields.Count, 1 To k) For j = 0 To rs.Fields.Count - 1 If Not rs(j) = "Null" Then arr(j + 1, k) = rs(j) Next j .MoveNext Loop If (.EOF And .BOF) = False Then With ListBox1 .ColumnCount = rs.Fields.Count .Column = arr End With .MoveFirst End If End With rs.Close db.Close Set rs = Nothing Set db = Nothing End Sub
Private Sub UserForm_Initialize() AusAccessLesen End Sub
Es ist etwas Datenbank Missbrauch was ich dir zeige. Normalerweise holt man sich nur das was gebraucht wird, verarbeitet es und schreibt die Änderungen wieder zurück. Gruß Uwe
Folgende(r) 1 Nutzer sagt Danke an Egon12 für diesen Beitrag:1 Nutzer sagt Danke an Egon12 für diesen Beitrag 28
• Stefan1
Registriert seit: 26.09.2022
Version(en): 2019
Moin Ulrich, (06.11.2024, 12:54)knobbi38 schrieb: @derHöpp:
Wo fehlt dir da der Zusammenhang? In einem der vorherigen Threads ging es darum, dass nach der Nutzung von DAO ein übrig-gebliebener Access-Prozess gekillt werden müsste. Aber egal, was ich anstelle, ich schaffe es nicht, dass bei der Verwendung von DAO aus Excel oder Word heraus überhaupt ein Access-Prozess gestartet würde. In diesem Thread sollte es eigentlich darum gehen, dass mehrere User auf die Datenbank zugreifen können sollen. Das bedeutet für mich (wie in deiner ersten Antwort beschrieben), dass der Options-Parameter von .OpenDatabase() auf False gesetzt wird (was standard ist) um einen exklusiven Zugriff zu verhindern. Gegebenenfalls kann man mit dem ReadOnly-Parameter das Schreiben von Anfang an verhindern (über Options) oder parallelle Zugriffe regeln (oder den Locktype). Alternativ lässt sich die Beschränkung auf das Lesen noch im Recordset festlegen, in dem entweder die Options. Mittlerweile geht es um den Type des Recordsets, der bestimmt meiner Kenntnis nach aber nur das Verhalten des Cursors und hat nichts mit ReadOnly oder einem übriggebliebenen Prozess zu tun. Aber wahrscheinlich geht es momentan nur mir so, dass ich das gedanklich nicht übereinbekomme. Viele Grüße derHöpp
Folgende(r) 1 Nutzer sagt Danke an derHoepp für diesen Beitrag:1 Nutzer sagt Danke an derHoepp für diesen Beitrag 28
• Stefan1
Registriert seit: 10.04.2014
Version(en): 97-2019 (32) + 365 (64)
Hallöchen, da ist sicher auch Deine Experimentierfreude gefragt... Wenn man das Recordset nicht transponiert übergeben kann dann könnte man auch im zweiten Schritt das array in ein weiteres transponieren. Wenn eine Abfrage nur einen einzelnen Datensatz ergibt, dann braucht es kein Array, man kann es trotzdem verwenden. Wenn sicher ist, dass z.B. nur ein einzelner Feldinhalt zurückgegeben wird, nimmt man es natürlich auch nicht. PHP-Code: Dim arrDyna() Set objDynaset = New ADODB.Recordset objDynaset.Open sql_string, Dbase, adOpenForwardOnly, adLockReadOnly If Not objDynaset.EOF Then arrDyna() = objDynaset.GetRows() End If
Wenn Du das Array in einen Zellinhalt übergeben willst, und irgendwo hast Du einen Feldinhalt "Null" - damit meine ich nicht 0 - geht das nicht und Du musst die Daten in einer Schleife übertragen. PHP-Code: objDynaset.MoveFirst 'Daten ab Zeile 2 While Not objDynaset.EOF For xCnt = 0 To objDynaset.Fields.Count - 1 .Cells(yCnt + 2, xCnt + 1 + iOffset) = objDynaset.Fields(xCnt).Value Next objDynaset.MoveNext yCnt = yCnt + 1 Wend
Brauchst Du die Spaltenüberschriften aus der Datenbank, musst Du diese ggf. gesondert abrufen, im Prinzip PHP-Code: objDynaset.MoveFirst 'Spaltenbeschriftung in Zeile 1 For xCnt = 0 To objDynaset.Fields.Count - 1 .Cells(1, xCnt + 1 + iOffset) = objDynaset.Fields(xCnt).Name .Cells(1, xCnt + 1 + iOffset).Font.Bold = True Next
...
. \\\|/// Hoffe, geholfen zu haben. ( ô ô ) Grüße, André aus G in T ooO-(_)-Ooo (Excel 97-2019+365)
Folgende(r) 1 Nutzer sagt Danke an schauan für diesen Beitrag:1 Nutzer sagt Danke an schauan für diesen Beitrag 28
• Stefan1
Registriert seit: 16.08.2020
Version(en): 2019 64bit
Hallo Andrè, das ist natürlich auch eine Möglichkeit. Das kann man auch mit If Not IsNull(... prüfen. Da wird es vermutlich noch mehrere Lösungsmöglichkeiten geben. Gruß Uwe
Folgende(r) 1 Nutzer sagt Danke an Egon12 für diesen Beitrag:1 Nutzer sagt Danke an Egon12 für diesen Beitrag 28
• Stefan1
|