Benutzer mit den meisten Antworten
Wie mit VB.NET auf eine laufende Instanz von MS Access zugreifen ?

Frage
-
Hallo,
ich hoffe das ich im richtigen Forum gelandet bin ... ;o)
Ich habe das Problem, das ich mit VB.NET (VB2010 Pro) auf die Access-eigene Funktion DoCmd.TransferSpredsheet zugreifen möchte, damit ich den Import von Excel Daten in die Datenbank mit der recht schnellen Funktion von Access automatisieren kann. Der Umweg über ein Dataset in VB dauert bei der Menge der Daten einfach zu lange.
Erschwerend kommt hinzu, das die Access DB mit einer eigenen System MDW abgesichert ist.
Jetzt probiere ich schon seit Tagen mit dem Access.Applikation Objekt herum, komme aber zu keiner funktionierenden Lösung. Egal was ich mache, jeder Zugriff endet in zwei Access Objekten: Die Shell Anweisung (s.u.) öffnet zwar korrekt die DB, aber die GetObject-Anweisung instanziiert trotzdem immer noch eine neue, zusätzliche Instanz. Dann kommt logischerweise die Fehlermeldung, da in der neuen Instanz natürlich kein Inhalt ist. Durch "acc.visible = true" kann man dann auch sehen, das Access zweimal geöffnet wird.
Es gelingt mir einfach nicht für das Application-Objekt ein Connect zu der von der Shell geöffneten DB. Obwohl es lt. diesem Artikel doch so gehen müsste: http://support.microsoft.com/kb/238610/en-us (ist zwar für Excel geschrieben, sollte aber auch für Access funktionieren).
Hier ist mein Code:
Shell("C:\Program Files\Microsoft Office\Office12\MSACCESS.EXE C:\Users\berger\Documents\WIData.mdb /WRKGRP C:\Users\berger\Documents\WIData.mdw /USER berger /PWD berge01", vbMinimizedFocus) Me.Focus() Dim acc As Access.Application acc = GetObject(, "Access.Application") acc.Visible = True acc.DoCmd.TransferSpreadsheet(Access.AcDataTransferType.acImport, Access.AcSpreadSheetType.acSpreadsheetTypeExcel9, "Sheet1", "C:\DataSource.xls", True) acc.CloseCurrentDatabase()
Ich habe schon sehr viel "gegoogelt", es gibt auch viel für "normale" MDBs, aber eben so gut wie nichts für die Verbindung mit einer MDW.
Vielleicht kann mir hier jemand helfen ? Vielleicht gibt es auch ganz andere Wege ?
Ich wäre für jede Hilfe dankbar ! :o)
Gruß
Uli
Antworten
-
Hallo,
den Umweg über Shell solltest Du Dir sparen und das "Ansonsten" von Josef verwenden
(ausgenommen Du möchtest etwas über COM lernen ;-)Eine gesicherte Datenbank kannst Du über den Jet OleDb Provider öffnen wie beschrieben in:
How to open a secured Access database in ADO through OLE DB (letzter Abschnitt).und kannst dafür den OleDbConnectionStringBuilder verwenden.
TransferSpreadsheet ist nur eine hübsche Verpackung für
INSERT INTO Tabelle (Spalte1, Spalte2) SELECT Spalte1, Spalte2 FROM [Sheet$] IN '' [Excel 8.0;HDR=Yes;DATABASE=C:\DataSource.xls];
Einige weitere Hinweise gibt: How To Use ADO with Excel Data from Visual Basic or VBA
Sollte die Tabelle noch nicht existieren kannst Du sie mit CREATE TABLE anlegen (spart zusätzliches ADOX Gefummel)
siehe Fundamental Microsoft Jet SQL for Access 2000 (bzw. ein Blick in JetSql40.chm bis Office 2003)Gruß Elmar
- Als Antwort vorgeschlagen Peter DoeringMVP, Moderator Mittwoch, 18. Januar 2012 09:15
- Als Antwort markiert Peter DoeringMVP, Moderator Mittwoch, 25. Januar 2012 11:19
Alle Antworten
-
Hallo!
Wenn du die Access-Anwendung per Shell-Funktion startest, müsste die Shell-Funktion die Prozess-ID zurückgeben. Vielleicht kannst du mit der die passende COM-Instanz aus der ROT (Running Object Table) holen.
Möglicherweise ist aber die Anwendung noch nicht vollständig geladen, wenn die Shell-Funktion fertig ist.Ich hole mir z. B. über die ROT die Access-Instanz zu einer VBE-Instanz, die ich in einem VBE-COM-Add-In (AccUnit) erhalte (siehe Klasse "ComTools" (ist allerdings in C#)).
Wenn du die ROT durchläufst und mit der von der Shell-Funktion erhaltenen Task-ID vergleichst, solltest du eigentlich die passende Instanz finden können.
Wie das in VB.Net läuft, weiß ich allerdings auch nicht auswendig. ;-)Übrigens: Sobald die Datei geöffnet ist, sollte auch der Zugriff über acc = GetObject(FullFileName) funktionieren.
Ansonsten:
Wenn du Excel-Tablelen importieren willst, könntest du versuchen, diese nur über die DB-Methoden durchzuführen.Prinzip (Jet-SQL):
insert into Tabelle (Feld1, Feld2, ...)
Select Feld1, Feld2, ... from [excel 8.0;;imex=2;DATABASE=D:\ein\Exceldatei.xls].[Sheet1$].. oder du nutzt überhaupt ADO.net. ;-)
mfg
Josef
Code-Bibliothek für Access-Entwickler
AccUnit - Testen von Access-Anwendungen -
Hallo,
den Umweg über Shell solltest Du Dir sparen und das "Ansonsten" von Josef verwenden
(ausgenommen Du möchtest etwas über COM lernen ;-)Eine gesicherte Datenbank kannst Du über den Jet OleDb Provider öffnen wie beschrieben in:
How to open a secured Access database in ADO through OLE DB (letzter Abschnitt).und kannst dafür den OleDbConnectionStringBuilder verwenden.
TransferSpreadsheet ist nur eine hübsche Verpackung für
INSERT INTO Tabelle (Spalte1, Spalte2) SELECT Spalte1, Spalte2 FROM [Sheet$] IN '' [Excel 8.0;HDR=Yes;DATABASE=C:\DataSource.xls];
Einige weitere Hinweise gibt: How To Use ADO with Excel Data from Visual Basic or VBA
Sollte die Tabelle noch nicht existieren kannst Du sie mit CREATE TABLE anlegen (spart zusätzliches ADOX Gefummel)
siehe Fundamental Microsoft Jet SQL for Access 2000 (bzw. ein Blick in JetSql40.chm bis Office 2003)Gruß Elmar
- Als Antwort vorgeschlagen Peter DoeringMVP, Moderator Mittwoch, 18. Januar 2012 09:15
- Als Antwort markiert Peter DoeringMVP, Moderator Mittwoch, 25. Januar 2012 11:19
-
Hallo Josef, Elmar,
vielen Dank für die Antworten (habe den Thread nach Lösung des Problems leider vergessen, daher erst jetzt die Antwort. Besser spät als nie.).
Hab es mit dem Vorschlag "acc = GetObject(FullFileName) " und dann "insert into Tabelle (Feld1, Feld2, ...)
Select Feld1, Feld2, ... from [excel 8.0;;imex=2;DATABASE=D:\ein\Exceldatei.xls].[Sheet1$]" tatsächlich hinbekommen.Vielen Dank (nachträglich) ;-)
Gruß
uli