Per VBScript und SQL auf Access-DB zugreifen
Ein fröhliches guten Morgen an die Scripting-Profis unter uns. Kann mir mal jemand mit ein oder zwei Codeschnippseln auf die Sprünge helfen?
Ich wurde gerne aus einem VBScript heraus eine vorhandene Access-Datenbank (bspw. datenbank.mdb) handlen und per SQL-Statement die üblichen Aktionen (bspw. select, insert, update, delete,...) ausführen. Google hat mir zwar ein paar Treffer geliefert, aber irgendwie steige ich als nicht VBS-Profi da nicht so ganz durch den SQL-Teil hingegen bekomme ich hin
Manuel
Ich wurde gerne aus einem VBScript heraus eine vorhandene Access-Datenbank (bspw. datenbank.mdb) handlen und per SQL-Statement die üblichen Aktionen (bspw. select, insert, update, delete,...) ausführen. Google hat mir zwar ein paar Treffer geliefert, aber irgendwie steige ich als nicht VBS-Profi da nicht so ganz durch den SQL-Teil hingegen bekomme ich hin
Manuel
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 116429
Url: https://administrator.de/contentid/116429
Ausgedruckt am: 23.11.2024 um 05:11 Uhr
12 Kommentare
Neuester Kommentar
Moin Moin
So sollte das in etwa funktionieren für Access 97- 2003. Bei Acc 2007 müste wohl der Connctstring etwas anders aussehen.
Noch ein hilfreicher Link: http://www.connectionstrings.com/
Gruß L.
So sollte das in etwa funktionieren für Access 97- 2003. Bei Acc 2007 müste wohl der Connctstring etwas anders aussehen.
Const connectString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;User Id=admin;Password=;"
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adUseClient = 3
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")
objConnection.Open connectString
objRecordset.CursorLocation = adUseClient
objRecordset.Open "SELECT * FROM MyTable" , objConnection, adOpenStatic, adLockOptimistic
Wert = objRecordSet("Feld1")
objRecordset.Close
Noch ein hilfreicher Link: http://www.connectionstrings.com/
Gruß L.
Hallo manuel-r,
anhand der folgenden Beispiele solltest Du es verstehen.
Der Code funktioniert jedoch nur mit Datenbanken ohne Passwort. Bei Datenbanken mit Passwort müssen noch ein paar Anweisungen eingefügt und in ACCESS eine Sicherheitsdatei *.mdw mit Benutzername und Benutzerpasswort erstellt werden.
Ideal währe es, wenn Du den Code in einem Excel-Modul einfügst und bei den Kommentaren Main Beg/End eine Sub Test/End einfügst, dann könntest Du den Code Debuggen und im ADO-Object einiges anhand der Einträge besser nachvollziehen.
Bei komplexen Abfragen, kann in ACCESS eine Abfrage im Entwurfsmodus erstellt und der SQL-Code in eine Datei kopiert werden, die dann im Code in einen Sql-String komplett eingelesen an die Routine OpenRecordset übergeben werden kann. Hierbei ist allerdings zu beachten, dass nur SQL-Kompatible Funktionen verwendet werden.
Hier noch zwei hilfreiche Links:
http://www.activevb.de/tutorials/tut_adokurs/adokurs.html
http://msdn.microsoft.com/en-us/library/ms677516(VS.85).aspx
Beispiel Test.Mdb - Tabelle1:
Gruß Dieter
anhand der folgenden Beispiele solltest Du es verstehen.
Der Code funktioniert jedoch nur mit Datenbanken ohne Passwort. Bei Datenbanken mit Passwort müssen noch ein paar Anweisungen eingefügt und in ACCESS eine Sicherheitsdatei *.mdw mit Benutzername und Benutzerpasswort erstellt werden.
Ideal währe es, wenn Du den Code in einem Excel-Modul einfügst und bei den Kommentaren Main Beg/End eine Sub Test/End einfügst, dann könntest Du den Code Debuggen und im ADO-Object einiges anhand der Einträge besser nachvollziehen.
Bei komplexen Abfragen, kann in ACCESS eine Abfrage im Entwurfsmodus erstellt und der SQL-Code in eine Datei kopiert werden, die dann im Code in einen Sql-String komplett eingelesen an die Routine OpenRecordset übergeben werden kann. Hierbei ist allerdings zu beachten, dass nur SQL-Kompatible Funktionen verwendet werden.
Hier noch zwei hilfreiche Links:
http://www.activevb.de/tutorials/tut_adokurs/adokurs.html
http://msdn.microsoft.com/en-us/library/ms677516(VS.85).aspx
Beispiel Test.Mdb - Tabelle1:
Feld1 | Feld2 | Feld3 | Feld4 | Feld5 | Feld6 |
1 | 2a | 3a | 4a | 5a | 6a |
2 | 2c | 3c | 4c | 5c | 6c |
3 | 2d | 3d | 4d | 5d | 6d |
(Auto) |
Option Explicit
Const dbPath = "F:\Test\Test.mdb"
Const adModeReadWrite = 3
Const adUseClient = 3
Const adOpenKeyset = 1
Const adLockOptimistic = 3
Dim dbCon, dbRec, Data, i
'Main Begin
'Datenbank öffnen
Call OpenRecordset("SELECT * FROM [Tabelle1]")
'Datensatz
Data = Array("Dummy AutoWert", "feld 2b", "feld 3b", "feld 4b", "feld 5b", "feld 6b")
With dbRec 'Datensatz Data in Feld2 bis Feld6 hinzufügen (Feld1 = AutoWert)
.AddNew
For i = 1 To .Fields.Count - 1: .Fields(i) = Data(i): Next
.Update
End With
With dbRec 'Alle Datensätze nacheinander auslesen
.Sort = "Feld2"
.MoveFirst
Do Until .EOF
For i = 0 To .Fields.Count - 1: Data(i) = .Fields(i): Next
MsgBox Join(Data, ";")
.MoveNext
Loop
End With
With dbRec 'Den Eintrag 'feld 3c' in Feld3 suchen
.MoveFirst
.Find = "feld3 = 'feld 3c'"
If .EOF Then
MsgBox "Nicht gefunden."
Else
MsgBox "Gefunden Zeile: " & .AbsolutePosition
End If
End With
'Alternativ direkte SQL-Anweisungen ausführen
dbCon.Execute "INSERT INTO Tabelle1 (Feld2) VALUES ('Hallo')"
dbCon.Execute "DELETE FROM Tabelle1 WHERE Feld2 = 'Hallo'"
dbCon.Execute "SELECT Tabelle1.* FROM Tabelle1 ORDER BY Tabelle1.feld2;"
'Datenbank und Recordset schließen
dbRec.Close: dbCon.Close
'WScript.Quit
'Main End
Private Sub OpenRecordset(ByRef dbSql)
Set dbCon = CreateObject("ADODB.Connection")
Set dbRec = CreateObject("ADODB.Recordset")
With dbCon 'Verbindung zur Datenbank herstellen
.Mode = adModeReadWrite
.CursorLocation = adUseClient
.Provider = "Microsoft.Jet.OLEDB.4.0" '*.mdb
'.Provider = "Microsoft.ACE.OLEDB.12.0" '*.accdb ACCESS 2007
.Properties("Data Source") = dbPath
.Properties("Persist Security Info") = False
.Open
End With
With dbRec 'Einen Recordset für die Datensätze erstellen
.Source = dbSql
.ActiveConnection = dbCon
.CursorLocation = adUseClient
.CursorType = adOpenKeyset
.LockType = adLockOptimistic
.Open
End With
End Sub
Gruß Dieter
Hallo manuel-r,
Meine SQL-Kenntnisse sind sehr bescheiden und hier auch nur in geringem Umfang erforderlich, da der ganze Ablauf über Recordset-Funktionen ausgeführt werden kann (siehe Links).
Beim Lesen und Schreiben über Recordset, können Felder auch über den Feldnamen angesprochen werden z.B:
Mit den folgenden Anwesungen können die aktuelle Zeilen-Position und die Anzahl der Datensätze abgefragt werden:
Mit der Funktion <dbRec.Find .....> kann geprüft werden, ob ein Datensatz schon vorhanden ist.
Gruß Dieter
Meine SQL-Kenntnisse sind sehr bescheiden und hier auch nur in geringem Umfang erforderlich, da der ganze Ablauf über Recordset-Funktionen ausgeführt werden kann (siehe Links).
Beim Lesen und Schreiben über Recordset, können Felder auch über den Feldnamen angesprochen werden z.B:
With dbRec 'Datensatz hinzufügen
.AddNew
.Fields("Feld1") = "ab"
.Fields("Feld2") = "xy"
..........
.Update
End With
Mit den folgenden Anwesungen können die aktuelle Zeilen-Position und die Anzahl der Datensätze abgefragt werden:
Pos = dbRec.AbsolutePosition 'Zeilen-Position lesen/setzen
Cnt = dbRec.RecordCount 'Anzahl Datensätze
Mit der Funktion <dbRec.Find .....> kann geprüft werden, ob ein Datensatz schon vorhanden ist.
Gruß Dieter
Hallo manuel_r,
Yep
Gruß Dieter
Zitat von @manuel-r:
Danke, ich hab's ja schon (s. oben). dbRec.Recordcount
liefert mir die Anzahl der mit der vorangegangenen Abfrage gelieferten Datensätze.
Danke, ich hab's ja schon (s. oben). dbRec.Recordcount
liefert mir die Anzahl der mit der vorangegangenen Abfrage gelieferten Datensätze.
Yep
Gruß Dieter
Hallo nochmal,
also, ich habe das nochmal getestet und festgestellt, dass das so nicht funktioniert, weil die SQL-Anweisungen über <dbCon.Execute> nicht vom Recordset erfasst werden. D.h. die Recordset-Funktionen AbsolutePosition und RecordCount werden nur aktualisiert, wenn die Datenbank über den Recordset gelesen oder beschrieben wird.
Das bedeutet, wenn Du Execute SQL verwendest, musst Du alles über SQL selbst steuern. Inwieweit das funktioniert, habe ich leider keine Ahnung.
Gruß Dieter
also, ich habe das nochmal getestet und festgestellt, dass das so nicht funktioniert, weil die SQL-Anweisungen über <dbCon.Execute> nicht vom Recordset erfasst werden. D.h. die Recordset-Funktionen AbsolutePosition und RecordCount werden nur aktualisiert, wenn die Datenbank über den Recordset gelesen oder beschrieben wird.
Das bedeutet, wenn Du Execute SQL verwendest, musst Du alles über SQL selbst steuern. Inwieweit das funktioniert, habe ich leider keine Ahnung.
Gruß Dieter
Hallo manuel-r,
also, beim ändern von Daten - wie von Logan geschrieben - einfach das AddNew weglassen.
wenn Du nur einen bestimmten Datensatz ansprechen möchtest, dann übergebe den SQL-String "Select + Where" in der Anweisung:
Ansonsten hast Du, wie bei meinem SQL-OpenRecordset alle Datensätze, die Du über MoveFirst bzw MoveNext
nacheinander ausliest und z.B. einen IF-Test machen kannst:
oder Du verwendest besser das Find-Beispiel:
Wenn gefunden, dann befindet sich die AbsolutePosition auf dieser Datensatz-Zeile (EOF = False)
Wenn nicht gefunden, dann ist EOF = True
Kommst Du damit klar?
Gruß Dieter
also, beim ändern von Daten - wie von Logan geschrieben - einfach das AddNew weglassen.
wenn Du nur einen bestimmten Datensatz ansprechen möchtest, dann übergebe den SQL-String "Select + Where" in der Anweisung:
OpenRecordset("Select ...Where").
Ansonsten hast Du, wie bei meinem SQL-OpenRecordset alle Datensätze, die Du über MoveFirst bzw MoveNext
nacheinander ausliest und z.B. einen IF-Test machen kannst:
...
If LCase(.Fields("Feld1")) = LCase("abc2") Then .Fields("Feld2") = "was anderes"
.MoveNext
...
.Find = "feld1 = 'abc2'"
Wenn gefunden, dann befindet sich die AbsolutePosition auf dieser Datensatz-Zeile (EOF = False)
Wenn nicht gefunden, dann ist EOF = True
Kommst Du damit klar?
Gruß Dieter