Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1696to1700
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Excel und ADODB.Connection

Excel und ADODB.Connection
25.06.2019 09:47:06
Sven
Hallo zusammen,
ich bin gerade dabei, mich in die Excel-Access-Programmierung einzuarbeiten.
Mit diesem Code-Beispiel kann ich den Inhalt eines Tabellenblattes auslesen und in eine Access-Datenbank schreiben. Das klappt.
Sub ExportToAccess()
Dim i As Integer
Dim ADODBConnection As New ADODB.Connection
Dim ADODBRecordset As New ADODB.Recordset
'Verbindung herstellen:
ADODBConnection.Open "Provider = Microsoft.ACE.OLEDB.12.0;" & _
"Data Source= " & ThisWorkbook.Path & "\Database1.accdb;"
'Tabelle öffnen:
ADODBRecordset.Open "Ort", ADODBConnection, adOpenKeyset, adLockOptimistic
'Daten übertragen:
For i = 1 To ActiveSheet.UsedRange.Rows.Count
With ADODBRecordset
.AddNew
.Fields("PLZ") = Cells(i, 4)
.Fields("Ort") = Cells(i, 5)
.Update
End With
Next i
'Tabelle schließen:
ADODBRecordset.Close
'Verbindung trennen:
ADODBConnection.Close
MsgBox "Erfolg!"
End Sub
Ich hätte drei Fragen:
  • Muss ich eine Schleife durchlaufen, oder kann ich den gesamten Tabelleninhalt auf ein Tabellenblatt bringen?

  • Wie sähe es aus, wenn ich einen bestimmten Datensatz (bspw. die ID 15) updaten möchte?

  • Kann man den Code irgendwie so abändern, dass ich einen beliebigen SQL-Befehl an die Datenbank schicke?

  • Ist denn ADODB noch state of the art (bei Excel 10 und Access 10)?
    Habt Ihr eine Literaturempfehlung für mich?
    Danke und Grüße
    Sven

    20
    Beiträge zum Forumthread
    Beiträge zu diesem Forumthread

    Betreff
    Datum
    Anwender
    Anzeige
    AW: Excel und ADODB.Connection
    25.06.2019 10:16:24
    Sven
    Also so geht das Update schon mal nicht:
    Sub AccessSQL()
    Dim ADODBConnection As New ADODB.Connection
    Dim ADODBRecordset As New ADODB.Recordset
    On Error GoTo errDB
    'Verbindung herstellen:
    ADODBConnection.Open "Provider = Microsoft.ACE.OLEDB.12.0;" & _
    "Data Source= " & ThisWorkbook.Path & "\Database1.accdb;"
    'Query ausführen:
    ADODBRecordset.Open "update Ort set [Ort] = 'Hamburg' where [PLZ]='30000'",  _
    ADODBConnection, adOpenKeyset, adLockOptimistic
    'Tabelle schließen:
    ADODBRecordset.Close
    'Verbindung trennen:
    ADODBConnection.Close
    MsgBox "Erfolg!"
    On Error GoTo 0
    Exit Sub
    errDB:
    MsgBox "Fehler" & vbCrLf & err.Description
    End Sub
    
    "Der Vorgang ist für ein geschlossenes Objekt nicht zugelassen."
    Anzeige
    AW: Excel und ADODB.Connection
    25.06.2019 11:18:08
    Zwenn
    Hallo Sven,
    wie ich schon in Deinem anderen Thread schrieb, habe ich leider keine Zeit mich mit Deinem Projekt zu beschäftigen. Aber für Access-Fragen würde ich mich in Access-lastigeren Foren umsehen.
    Ich denke einen guten Anfang für die Recherche kannst Du hier machen:
    http://www.ms-office-forum.net/forum/forumdisplay.php?f=3
    Viele Grüße,
    Zwenn
    Updatae mit ADODB.Connection
    25.06.2019 12:18:42
    EtoPHG
    Hallo,
    Ein .Update kannst du zwar auf einen Recordset ausführen, wenn du die entsprechenden Felder (.Fields(x)) des aktiven Records gesetzt hast. Dein SQL kannst du direkt auf die Connection ausführen, nämlich so:
    ADODBConnection.Execute "update Ort set..."
    
    Gruess Hansueli
    Anzeige
    AW: Excel und ADODB.Connection
    25.06.2019 13:07:43
    Sven
    Danke, ich schaue mich da mal um.
    AW: Excel und ADODB.Connection
    25.06.2019 12:13:51
    Luschi
    Hallo Sven,
    ich benutze sehr oft AdoDB zum Datenaustausch zwischen Access/Excel bzw. umgekehrt. Seit Office 2007 hat M$ das inzwischen schon für Tod gegelaubte DAO in Access wieder reaktiviert und zum Standard erklärt - allerdings bleibe ich bei AdoDB.
    Hilfestellungen gebe ich allerdings nur noch, wenn Du Demodateien (Access und Excel) bereitstellst, denn hier kommt es auf Genauigkeit an und User haben schon 'ne Menge erzählt, was dann in den Demodateien total anders war (Datumsfeld als String definiert u.ä.).
    Gruß von Luschi
    aus klein-Paris
    PS: Allerdings benutze ich 'Late Binding' (GetObject/CreateObject) statt wie bei Dir 'Early Binding' (As New ADODB.Connection).
    Anzeige
    AW: Excel und ADODB.Connection
    25.06.2019 13:44:31
    Sven
    Hallo Luschi, wo ist Klein-Paris? :o)
    Wenn Du mir helfen würdest, wäre ich Dir sehr dankbar. Das mit dem Update habe ich hinbekommen, aber konkret geht es mir um folgendes:
    Ich habe eine Exceldatei, bei der die Bearbeitung der Daten ausschließlich über ein Userform erfolgt. Funktioniert super, soll jetzt aber Multiuser-fähig werden. Das hatte ich hier (https://www.herber.de/forum/messages/1699260.html) neulich thematisiert. Also werde ich wohl für jeden Anwender eine Frontend-Version der Excel-Mappe verteilen und die Datenhaltung in Access machen.
    Wie kann ich die "Synchronisation" beim Öffnen und Schließen sicherstellen?
    Was hälst Du von der Idee, beim Start alle Daten (4 Tabellen) aus der DB auszulesen und auf Tabellenblätter zu verteilen und beim Schließen den umgekehrten Weg zu gehen - könnte das klappen? Der Vorteil wäre, dass meine bisherige Programmierung erhalten bleiben könnte.
    Irgendwie kann ich keine Access-Dateien hochladen. Aber die muss auch keine weitere Logik (Beziehungen etc.) haben, sondern einfach die 4 Tabellen aufnehmen. Hättest Du da ein Beipsiel (oder einen ganz anderen Ansatz) für mich?
    Danke!
    Sven
    Anzeige
    AW: Excel und ADODB.Connection
    25.06.2019 14:36:19
    Rob
    Hallo Sven,
    diesen Ansatz hätte ich auch verfolgt: Access-DB in die Arbeitsblätter hochladen, über das UserForm Aktualisierungen vornehmen und dann wieder in Access hochladen.
    Du solltest aber sicherstellen , dass ein Datensatz nicht gleichzeitig von mehr als einem User bearbeitet werden. Das sollte mit dem Locktype vom Recordset funktionieren, den Du wie folgt festlegen kannst (habe ich aber ehrlich gesagt auch noch nicht ausprobiert):
    adLockPessimistic Daten werden beim Öffnen des Recordsets für andere User gesperrt.
    Pessimistischer LockType bedeutet, daß die Daten vom ersten User der sie aufruft für weitere Änderungen gesperrt werden. Die Daten können jedoch auch von anderen Usern angezeigt, jedoch nicht mehr geändert werden. Er ist ratsam wenn die Datenbankstruktur das Ändern von einzelnen Fällen vorsieht. Für Auflistungen ist er jedoch nicht empfehlenswert, da alle angezeigten Daten für nachfolgende User nicht mehr Änderbar sind.

    Siehe auch: http://www.access-basics.de/index.php/ADODB_als_Alternative_zu_DAO.html
    Anzeige
    AW: Excel und ADODB.Connection
    25.06.2019 14:50:33
    Rob
    Sorry, bei Pessimistic wird der Datensatz komplett geperrt, d.h. er kann anschl. nicht mehr bearbeitet werden. Optimistic wäre eher zutreffend, obwohl ich mir hier auch nicht sicher bin, ob nach dem Update der Datensatz anschl. wieder bearbeitet werden kann. Da müsste man wohl doch einen anderen Ansatz verfolgen, als über den Locktype. Hier noch ein aufschlussreicher Artikel:
    https://activevb.de/tutorials/tut_adokurs/adokurs4.html
    AW: Excel und ADODB.Connection
    26.06.2019 16:16:34
    Sven
    Hallo Rob,
    kann ich Dich hier nochmal belästigen?
    Könntest Du mir hier einen Beispielcode schicken? Die Exceldatei hatte ich dem ersten Beitrag anbgehängt.
    Nachdem ich den Recordset mit einer Access-Tabelle gefüllt habe, muss ich dann in zwei Schleifen die Zellen des Excel-Tabellenblattes Spalten- und Zeilenweise füllen oder geht das auf einen Schlag?
    Ich habe (trotz des Links) auch nicht verstanden, wie ich beim zurückschreiben in die Access-DB sicherstelle, dass Änderungen von anderen Nutzern berücksichtigt werden. :o(
    Grüße
    Sven
    Anzeige
    AW: Excel und ADODB.Connection
    26.06.2019 21:08:31
    Rob
    Hi Sven,
    Du musst lediglich eine Schleife für den Tabellen-Header machen und anschl. kannst Du mit der Methode CopyFromRecordset den kompletten Recordset in die Tabelle ausgeben. So ungefähr:
    
    With Sheets(1)
    For i = 0 To rs.Fields.Count - 1
    .Range("A1").Offset(0, i).Value = rs.Fields(i).Name
    Next i
    .Range("A2").CopyFromRecordset rs
    End With
    
    Bezgl. dem Sicherstellen, dass ein Datensatz nicht parallel bearbeitet wird, habe ich auch keine wirkliche Lösung gefunden. Da muss ich mich mal selber reinfuchsen. Du könntest die Excel-Datei mit der Userform aber zentral ablegen und da Excel nur einfache Bearbeitungsrechte zuweist, können andere Nutzer keine Änderungen vornehmen, so lange jemand die Datei geöffnet hat. Ist natürlich nicht besonders elegant aber sicher.
    Anzeige
    AW: Excel und ADODB.Connection
    27.06.2019 07:55:06
    Rob
    Aber mal ne andere Frage; warum gehst Du überhaupt den Umweg über Excel? Du kannst auch in Access mit VBA ein Userform erstellen und die Daten dort direkt manipulieren.
    AW: Excel und ADODB.Connection
    27.06.2019 09:34:01
    Sven
    Moin Rob, vielen Dank für das Codebeispiel. Damit bekomme ich das Auslesen der accdb schon mal gut hin. Was das Zurückspeichern angeht, muss ich mich noch etwas reinfuchsen. Mein aktueller Ansatz ist, dass ich durch das Userform ausgelöste Änderungen an den Daten gleichzeitig in der dann ja in der Arbeitsmappe liegenden Kopie sowie direkt in der Datenbank vornehme. Damit hat ein Kollege, der die Excel-Datei im Anschluss öffnet immer den aktuellsten Stand.
    Grundsätzlich hast Du Recht und man hätte alles in Access machen können. Aber: Weder mein Vorgänger noch ich haben Ahnung von Access und VBA. :o)
    Anzeige
    AW: Excel und ADODB.Connection
    27.06.2019 10:44:51
    Rob
    Moin Sven,
    schau mal hier:
    https://www.experts-exchange.com/questions/21144473/adOpenKeyset-adLockOptimistic-What-does-it-do.html
    Neben dem LockType ist der CursorType von Bedeutung. Wenn Du vermeiden möchtest, dass zwei User denselben Datensatz gleichzeitig bearbeiten, benötigst Du die Kombination aus adOpenDynamic/adLockPessimistic. So z.B.:
    rs.Open sSQL, Cn, adOpenDynamic,adLockPessimistic
    rs.Fields("SomeField")="some value" 'Record locked
    rs.Update 'Record Unlocked
    D.h. sobald neue Daten eingespielt werden, ist der Datensatz gesperrt. Nachdem die Funktion Update ausgeführt wurde, ist der Datensatz wieder frei zur Bearbeitung. Soviel in der Theorie.
    Anzeige
    AW: Excel und ADODB.Connection
    27.06.2019 11:29:38
    Sven
    Hallo Rob,
    ah, ein super Link. Ich werde
    
    adOpenDynamic, adLockPessimistic
    
    nutzen - obwohl ich die Erläuteruzngen der unterschiedlichen Varianten nicht wirklich geblickt habe. Während die obigen drei Zeilen Code ausgeführt werden, vergehen ja nur Millisekunden und die Wahrscheinlichkeit eines Updates auf den gleichen Datensatz durch einen anderen Anwender sehe ich gering. Allerdings frage ich mich, wie ich die dennoch potentiell auftretenden Fehler abfange...
    Ein größeres Problem in meinem Anwendungsfall sehe ich beim Hinzufügen eines Datensatzes:
    With adoRecSet
    .AddNew
    .Fields("Timestamp") = now()
    .Fields("Anwender") = "Lisa"
    .Update
    End With
    

    Ich nutze hier eine Tabelle quasi als Änderungshistorie und notiere wann wer welche Änderung _ durchgeführt hat. Sollte ich hier adoRecSet auch mit
    
    adOpenDynamic, adLockPessimistic
    
    öffnen?
    AW: Excel und ADODB.Connection
    27.06.2019 13:55:13
    Rob
    Ehrlich gesagt bin ich da überfragt - da geht es mir stellenweise wie Dir; verstehe auch nicht den ganzen Sinn und Zweck dieser Properties. Datenbanken habe ich in Verbindung mit VBA bisher auch nur zum Auslesen (ReadOnly) von Daten benötigt. Ist aber ein interessantes Thema, in das ich mich mal einarbeiten werde.
    Ich würde mir an Deiner Stelle aber trotzdem nochmal überlegen, für diesen Zweck komplett auf Access umzustellen. Es gibt hierzu gute Tutorials von Steve Bishop auf Youtube, z.B.: Introduction (Programming in Microsoft Access 2013).
    Allg. DB LockType
    28.06.2019 20:21:43
    ChrisL
    Hi Sven
    Ich bin kein Experte, aber ich glaube in der Situation (reines Log-File) darfst du optimistisch sein. Die Chance eines Konfliktes sehe ich als sehr klein an, wenn du nur neue Datensätze hinzufügst und bestehende nicht änderst.
    Ein Konflikt entsteht nur dann, wenn genau im Moment zwischen der Codeausführung .AddNew und .Update jemand versucht z.B. das Datum zu ändern, das du eben eingetragen hast. Die Chance im Lotto zu gewinnen ist grösser ;)
    Selbst wenn mal ein Konflikt entstehen würde, ist dies i.d.R. kein Weltuntergang. Ausnahmen sind, wie unteren erwähnt z.B. ein Reservationssystem (z.B. zwei Personen buchen gleichzeitig das gleiche Zimmer).
    Andererseits ist es auch nicht schlimm mal was zu "locken", wenn du unsicher bist. Ich vermute im Normalgebrauch ist Performance kein Thema.
    Die Wahl hängt natürlich auch stark von der Art der Bearbeitung ab. Bearbeitet man manuell Access Tabellen, dann "öffnet" man den Datensatz und bearbeitet die jeweilige Zeile. Bis zum Update (verlassen der Zeile) kann es also länger dauern und die Konfliktchance steigt. Mit CursorType macht man das Feintuning für die manuelle Bearbeitung.
    Wird die Datenbank hingegen ausschliesslich per Code bearbeitet, dann vergehen oft nur Millisekunden bis zum Update.
    cu
    Chris
    https://docs.microsoft.com/en-us/sql/ado/guide/data/types-of-locks?view=sql-server-2017
    adLockOptimistic
    Indicates that the provider uses optimistic locking - locking records only when you call the Update method. This means that there is a chance that another user may change the data between the time you edit the record and when you call Update, which creates conflicts. Use this lock type in situations where the chances of a collision are low or where collisions can be readily resolved.
    adLockPessimistic
    Indicates pessimistic locking, record by record. The provider does what is necessary to ensure successful editing of the records, usually by locking records at the data source immediately before editing. Of course, this means that the records are unavailable to other users once you begin to edit, until you release the lock by calling Update. Use this type of lock in a system where you cannot afford to have concurrent changes to data, such as in a reservation system.
    AW: Allg. DB LockType
    28.06.2019 20:37:36
    ChrisL
    Mit CursorType macht man das Feintuning für die manuelle Bearbeitung.
    Diese Aussage nehme ich zurück.
    Je nach CursorType kann man die Chance für einen Konflikt noch ein wenig verringern oder erhöhen, was dann wieder die Entscheidung betr. LockType beinflusst.
    Ich denke aber kaum, dass du einen Performanceunterschied merkst.
    cu
    Chris
    AW: Allg. DB LockType
    01.07.2019 09:44:52
    Sven
    Hallo Chris,
    danke für die Anmerkung.
    Bei mir gibt es zwei Szenarien: Einmal wird ein bestimmter Datensatz geupdatet - hier würde ich zu adLockPessimistic tendieren. Das andere Thema ist eine Protokolltabelle, bei der via Insert ein neuer Datensatz angehängt wird. Hier bin ich noch unschlüssig. Was schlägst Du vor?
    Hast Du eine Ahnung, wie im Zweifelsfall bei adLockPessimistic reagiert wird? Gibts da eine Fehlermeldung oder "gewinnt" der letzte?
    Grüße
    Sven
    AW: Allg. DB LockType
    01.07.2019 17:57:38
    ChrisL
    Hi Sven
    Ich glaube bei Optimistic gewinnt der letzte. Bei Pessimistic ist der Datensatz während der Bearbeitung gesperrt und es kommt eine Meldung, wenn man trotzdem versucht die Zeile zu ändern.
    Protokoll = egal, Optimistic reicht, da die Chance einer Kollision gleich Null ist
    Update = kommt drauf an. Wenn es ganz schlimm ist, wenn eine Kollision entstehen würde, dann nimm Pessimistic
    cu
    Chris

    Links zu Excel-Dialogen

    Beliebteste Forumthreads (12 Monate)

    Anzeige

    Beliebteste Forumthreads (12 Monate)

    Anzeige
    Anzeige
    Anzeige
    Archiv - Verwandte Themen