Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Per VBScript und SQL auf Access-DB zugreifen

Frage Entwicklung VB for Applications

Mitglied: manuel-r

manuel-r (Level 2) - Jetzt verbinden

20.05.2009, aktualisiert 08:12 Uhr, 17389 Aufrufe, 12 Kommentare, 1 Danke

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
Mitglied: Logan000
20.05.2009 um 08:26 Uhr
Moin Moin

So sollte das in etwa funktionieren für Access 97- 2003. Bei Acc 2007 müste wohl der Connctstring etwas anders aussehen.

01.
Const connectString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;User Id=admin;Password=;" 
02.
Const adOpenStatic = 3 
03.
Const adLockOptimistic = 3 
04.
Const adUseClient = 3 
05.
Set objConnection = CreateObject("ADODB.Connection") 
06.
Set objRecordset = CreateObject("ADODB.Recordset") 
07.
objConnection.Open connectString			  
08.
objRecordset.CursorLocation = adUseClient 
09.
objRecordset.Open "SELECT * FROM MyTable" , objConnection, adOpenStatic, adLockOptimistic 
10.
Wert = objRecordSet("Feld1")  
11.
objRecordset.Close
Noch ein hilfreicher Link: http://www.connectionstrings.com/

Gruß L.
Bitte warten ..
Mitglied: manuel-r
20.05.2009 um 08:35 Uhr
Hallo Logan,
kannst du das vielleicht noch etwas kommentieren, damit ich es auch verstehe?
Bitte warten ..
Mitglied: 76109
21.05.2009 um 15:50 Uhr
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:

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)

01.
Option Explicit 
02.
 
03.
Const dbPath = "F:\Test\Test.mdb" 
04.
 
05.
Const adModeReadWrite = 3 
06.
 
07.
Const adUseClient = 3 
08.
Const adOpenKeyset = 1 
09.
Const adLockOptimistic = 3 
10.
 
11.
Dim dbCon, dbRec, Data, i 
12.
 
13.
'Main Begin 
14.
 
15.
   'Datenbank öffnen 
16.
    Call OpenRecordset("SELECT * FROM [Tabelle1]") 
17.
     
18.
   'Datensatz 
19.
    Data = Array("Dummy AutoWert", "feld 2b", "feld 3b", "feld 4b", "feld 5b", "feld 6b") 
20.
 
21.
    With dbRec 'Datensatz Data in Feld2 bis Feld6 hinzufügen (Feld1 = AutoWert) 
22.
       .AddNew 
23.
        For i = 1 To .Fields.Count - 1:  .Fields(i) = Data(i):  Next 
24.
       .Update 
25.
    End With 
26.
 
27.
    With dbRec 'Alle Datensätze nacheinander auslesen 
28.
      .Sort = "Feld2" 
29.
      .MoveFirst 
30.
        Do Until .EOF 
31.
            For i = 0 To .Fields.Count - 1:  Data(i) = .Fields(i):  Next 
32.
            MsgBox Join(Data, ";") 
33.
           .MoveNext 
34.
        Loop 
35.
    End With 
36.
 
37.
    With dbRec 'Den Eintrag 'feld 3c' in Feld3 suchen 
38.
        .MoveFirst 
39.
        .Find = "feld3 = 'feld 3c'" 
40.
         If .EOF Then 
41.
            MsgBox "Nicht gefunden." 
42.
         Else 
43.
            MsgBox "Gefunden Zeile: " & .AbsolutePosition 
44.
         End If 
45.
    End With 
46.
          
47.
   'Alternativ direkte SQL-Anweisungen ausführen 
48.
    dbCon.Execute "INSERT INTO Tabelle1 (Feld2) VALUES ('Hallo')" 
49.
    dbCon.Execute "DELETE FROM Tabelle1 WHERE Feld2 = 'Hallo'" 
50.
    dbCon.Execute "SELECT Tabelle1.* FROM Tabelle1 ORDER BY Tabelle1.feld2;" 
51.
 
52.
   'Datenbank und Recordset schließen 
53.
    dbRec.Close:   dbCon.Close 
54.
 
55.
   'WScript.Quit 
56.
     
57.
'Main End 
58.
 
59.
 
60.
Private Sub OpenRecordset(ByRef dbSql) 
61.
     
62.
    Set dbCon = CreateObject("ADODB.Connection") 
63.
    Set dbRec = CreateObject("ADODB.Recordset") 
64.
     
65.
    With dbCon 'Verbindung zur Datenbank herstellen 
66.
        .Mode = adModeReadWrite 
67.
        .CursorLocation = adUseClient 
68.
        .Provider = "Microsoft.Jet.OLEDB.4.0"  '*.mdb 
69.
       '.Provider = "Microsoft.ACE.OLEDB.12.0" '*.accdb ACCESS 2007 
70.
        .Properties("Data Source") = dbPath 
71.
        .Properties("Persist Security Info") = False 
72.
        .Open 
73.
    End With 
74.
     
75.
    With dbRec 'Einen Recordset für die Datensätze erstellen 
76.
        .Source = dbSql 
77.
        .ActiveConnection = dbCon 
78.
        .CursorLocation = adUseClient 
79.
        .CursorType = adOpenKeyset 
80.
        .LockType = adLockOptimistic 
81.
        .Open 
82.
    End With 
83.
End Sub
Gruß Dieter
Bitte warten ..
Mitglied: manuel-r
25.05.2009 um 08:35 Uhr
Danke für das Beispielscript Dieter.
Ich hab's jetzt mal getestet, einige Dinge auf meine Bedürfnisse angepasst usw - und ich hab's wohl auch verstanden.
Eine Frage stellt sich mir aber noch:
Wenn ich ein SELECT (in SQL) ausführe müssen die Ergebnisse doch in irgendeinem Array stehen. In welchem? Gibt es auch einen Befehl der etwa das gleiche macht wie unter PHP mysql_affected_rows?
Ich muss beim Schreiben von Datensätzen die UNIQUE-Felder haben ja vorher prüfen ob es den Datensatz schon gibt. Je nachdem muss ich ja entweder ein INSERT oder UPDATE machen.

Manuel

EDIT:
Hab's schon selbt raus gefunden
01.
If dbRec.Recordcount > 0 Then 
02.
  strSQL = "UPDATE " & dbTab1 & " SET Nutzer = 'geändert' WHERE Nummer = '" & strNummer & "'" 
03.
  dbCon.Execute strSQL 
04.
Else 
05.
  strSQL = "INSERT INTO " & dbTab1 & " (Nummer, Nutzer) VALUES ('1111111111', 'ein Test')" 
06.
  dbCon.Execute strSQL 
07.
End If
Bitte warten ..
Mitglied: 76109
25.05.2009 um 10:22 Uhr
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:
01.
With dbRec 'Datensatz hinzufügen  
02.
     .AddNew 
03.
     .Fields("Feld1") = "ab" 
04.
     .Fields("Feld2") = "xy" 
05.
     .......... 
06.
    .Update 
07.
End With
Mit den folgenden Anwesungen können die aktuelle Zeilen-Position und die Anzahl der Datensätze abgefragt werden:
01.
Pos = dbRec.AbsolutePosition 'Zeilen-Position lesen/setzen 
02.
Cnt = dbRec.RecordCount 'Anzahl Datensätze
Mit der Funktion <dbRec.Find .....> kann geprüft werden, ob ein Datensatz schon vorhanden ist.

Gruß Dieter
Bitte warten ..
Mitglied: manuel-r
25.05.2009 um 10:27 Uhr
Danke, ich hab's ja schon (s. oben). dbRec.Recordcount liefert mir die Anzahl der mit der vorangegangenen Abfrage gelieferten Datensätze. Somit weiß ich also nach einem SELECT ob es den Datensatz schon gibt (recordcount = 1) und kann dann per IF entweder ein UPDATE oder INSERT ausführen.

Manuel
Bitte warten ..
Mitglied: 76109
25.05.2009 um 10:31 Uhr
Hallo manuel_r,

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.

Yep

Gruß Dieter
Bitte warten ..
Mitglied: 76109
25.05.2009 um 10:58 Uhr
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
Bitte warten ..
Mitglied: manuel-r
25.05.2009 um 14:59 Uhr
Miffft. Klappt doch nicht so einfach
Hast du vielleicht mal eben noch den passenden Code für das UPDATE eines Datensatzes analog zu
01.
With dbRec 'Datensatz hinzufügen  
02.
     .AddNew 
03.
     .Fields("Feld1") = "ab" 
04.
     .Fields("Feld2") = "xy" 
05.
     .......... 
06.
    .Update 
07.
End With
Manuel
Bitte warten ..
Mitglied: Logan000
25.05.2009 um 15:13 Uhr
Moin Moin

Wenn dein SQL Statement nur einen Datensatz holt, reicht es einfach das
01.
    .AddNew
wegzulassen.

Gruß L.
Bitte warten ..
Mitglied: manuel-r
25.05.2009 um 15:18 Uhr
*kopfkratz*
Irgendwie muss ich aber doch ein WHERE mitgeben - oder eine Zeilennummer irgendwas halt.
Wenn ich bspw. eine Tabelle mit
    • feld1, feld2, feld3
    hab und darin dann die Werte
    • abc1, cde, fgh1
    • abc2, cde, fgh2
    • abc3, cde, fgh3
    Wenn ich jetzt in der Zeile mit dem abc2 den Wert cde ändern will, dann muss ich doch ein WHERE feld1 = 'abc2' (oder ähnlich) übergeben.

    Manuel
Bitte warten ..
Mitglied: 76109
25.05.2009 um 16:37 Uhr
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:
01.
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:
01.
... 
02.
 If LCase(.Fields("Feld1")) = LCase("abc2") Then .Fields("Feld2") = "was anderes" 
03.
.MoveNext 
04.
...
oder Du verwendest besser das Find-Beispiel:
01.
.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
Bitte warten ..
Neuester Wissensbeitrag
Microsoft

Lizenzwiederverkauf und seine Tücken

Erfahrungsbericht von DerWoWusste zum Thema Microsoft ...

Ähnliche Inhalte
Datenbanken
SQL 2000 DB ist Fehlerverdächtig (3)

Frage von franksig zum Thema Datenbanken ...

Datenbanken
gelöst SQL-Abfrage - DISTINCT - letztes Datum (3)

Frage von emeriks zum Thema Datenbanken ...

LAN, WAN, Wireless
Access Point: Ubiquiti UAP AC PRO Einschätzung Reichweite (4)

Frage von TimMayer zum Thema LAN, WAN, Wireless ...

Heiß diskutierte Inhalte
Windows Server
Outlook Verbindungsversuch mit Exchange (15)

Frage von xbast1x zum Thema Windows Server ...

Microsoft Office
Keine Updates für Office 2016 (13)

Frage von Motte990 zum Thema Microsoft Office ...

Grafikkarten & Monitore
Tonprobleme bei Fernseher mit angeschlossenem Laptop über HDMI (11)

Frage von Y3shix zum Thema Grafikkarten & Monitore ...