Benutzer mit den meisten Antworten
zugriff auf geöffnete word-dokumente

Frage
-
hallo visual-basic-gemeinde,
mit den beiden deklarationen
Dim meinWord As Word.Application = GetObject(, "Word.Application")
Dim meinDokument As Word.Document = meinWord.ActiveDocument
kann ich bequem auf bereits geöffnete word-dokumente zugreifen.
sind jedoch mehrere word-instanzen eingesetzt, so greift der aufruf von GetObject leider immer nur bei der zuerst eingesetzten instanz.
gibt es nun ein verfahren, um alle word-instanzen zu erreichen?
grüsse von peter
- Bearbeitet SePe Samstag, 12. Mai 2012 09:02
Antworten
-
Hallo Peter,
Du musst den Klassennamen weglassen, wenn Du auf die Art auf die Objekte zugreifen möchtest. Zudem bekommst Du eine Referenz auf das Dokument, nicht Word.Application:
Dim doc As Word.Document = DirectCast(GetObject("D:\beispielDok.docx"), Word.Document) dim app As Word.Application = doc.Application
Thorsten Dörfler
Microsoft MVP Visual Basic
vb-faq.de- Als Antwort markiert SePe Montag, 14. Mai 2012 07:12
Alle Antworten
-
Hallo Peter,
wenn Du den Dateinamen des geöffneten Dokuments kennst, kannst Du bei GetObject auch diesen Dokumentnamen angeben und Dir dessen Instanz zurückgeben lassen. Ist der Name nicht bekannt, musst Du Dich selber durch die Running Object Table (ROT) arbeiten und die passende Instanz heraussuchen. Ein Codesnippet zum Durchlaufen der ROT findest Du u.a. hier:
Laufende COM-Objekte abfragen
http://dotnet-snippets.de/dns/laufende-com-objekte-abfragen-SID526.aspxThorsten Dörfler
Microsoft MVP Visual Basic
vb-faq.de -
hallo thorsten;
mit der angabe des dateinamens habe ich mich eben auch schon versucht, aber da verstehe ich offenbar etwas falsch,
denn sowohl bei
meinWord =
CType(GetObject("Dokument1", "Word.Application"), Word.Application)
als auch beispielsweise bei
meinWord =
CType(GetObject("D:\beispielDok.docx", "Word.Application"), Word.Application)
erhalte ich die ex.message:
"der Datei- oder Klassenname wurde während des Automatisierungsvorgangs nicht gefunden"
grüsse, peter
-
Hallo Peter,
Du musst den Klassennamen weglassen, wenn Du auf die Art auf die Objekte zugreifen möchtest. Zudem bekommst Du eine Referenz auf das Dokument, nicht Word.Application:
Dim doc As Word.Document = DirectCast(GetObject("D:\beispielDok.docx"), Word.Document) dim app As Word.Application = doc.Application
Thorsten Dörfler
Microsoft MVP Visual Basic
vb-faq.de- Als Antwort markiert SePe Montag, 14. Mai 2012 07:12
-
hallo thorsten,
dein link zu Laufende COM-Objekte abfragen macht mir noch bauchschmerzen, weil ich einerseits mit der funktion GetRunningCOMObjectNames() alle namen der COMobjekte erhalte, mir aber dabei kein filter zur verfügung steht, um die wordObjekte herauszufiltern, und anderseits mit der funktion GetRunningCOMObjectByName(objectDisplayName As String) unter objectDisplayName der dokumentpfad bekannt sein müsste.
jedenfalls mit meinem beschränkten wissen stosse ich da an meine grenzen.
inzwischen habe ich folgenden code zusammengebaut, doch mit eher ungutem gefühl, weil ich da um sieben ecken herumprogrammiere:
Option Explicit On Option Strict On Imports System.Runtime.InteropServices Imports System.Runtime.InteropServices.ComTypes ' Imports Microsoft.Office.Interop Module alleWordFenster <DllImport("ole32.dll")> _ Private Function GetRunningObjectTable(reserved As UInteger, ByRef pprot As IRunningObjectTable) As Integer End Function <DllImport("ole32.dll")> _ Private Function CreateBindCtx(reserved As UInteger, ByRef pctx As IBindCtx) As Integer End Function Public Sub wordFensterListe() Dim msgText As String = "" Dim fenstertitelListe As List(Of String) = listeAllerFenstertitel() Dim hptPfadListe As List(Of String) = New List(Of String) ' For Each objektName As String In holeNamenAllerLaufendenCOMobjekte() For Each fenstertitel As String In fenstertitelListe If objektName.EndsWith(fenstertitel) Then If Not hptPfadListe.Contains(objektName) Then hptPfadListe.Add(objektName) End If End If Next fenstertitel Next fenstertitelListe.Clear() ' Dim meinDokument As New Word.Document Dim listeAllerWordInstanzen As List(Of Word.Application) = New List(Of Word.Application) ' For Each pfad As String In hptPfadListe meinDokument = DirectCast(GetObject(pfad), Word.Document) listeAllerWordInstanzen.Add(meinDokument.Application) Next pfad hptPfadListe.Clear() ' Dim z As Integer = 0 For Each instanz As Word.Application In listeAllerWordInstanzen For Each dok As Word.Document In instanz.Documents msgText &= dok.FullName & vbCr z += 1 Next dok Next instanz ' MsgBox(msgText, _ CType(MsgBoxStyle.Information + MsgBoxStyle.OkOnly, MsgBoxStyle), _ z.ToString & " wordDokumente") End Sub Private Function listeAllerFenstertitel() As List(Of String) Dim liste As List(Of String) = New List(Of String)() Dim prozessListe As Process() = Process.GetProcesses ' For Each prozess As Process In prozessListe If LCase(prozess.ProcessName) = "winword" Then If (prozess.MainWindowTitle IsNot Nothing) AndAlso (Not prozess.MainWindowTitle = "") Then liste.Add(Replace(prozess.MainWindowTitle, " - Microsoft Word", "")) End If End If Next ' Return liste End Function Private Function holeNamenAllerLaufendenCOMobjekte() As List(Of String) Dim liste As List(Of String) = New List(Of String)() ' Dim laufendeObjekteTafel As IRunningObjectTable = Nothing If (Not GetRunningObjectTable(0, laufendeObjekteTafel) = 0) OrElse (laufendeObjekteTafel Is Nothing) Then MsgBox("kein zugriff auf die tafel der laufenden COMobjekte", _ CType(MsgBoxStyle.Information + MsgBoxStyle.OkOnly, MsgBoxStyle), _ "fehlermeldung") Return liste End If ' Dim monikerListe As IEnumMoniker = Nothing laufendeObjekteTafel.EnumRunning(monikerListe) monikerListe.Reset() ' Dim monikerArray As IMoniker() = New IMoniker(0) {} ' While monikerListe.[Next](1, monikerArray, IntPtr.Zero) = 0 Dim bindInfo As IBindCtx = Nothing Dim anzeigenamen As String = "" ' CreateBindCtx(0, bindInfo) monikerArray(0).GetDisplayName(bindInfo, Nothing, anzeigenamen) Marshal.ReleaseComObject(bindInfo) ' liste.Add(anzeigenamen) End While ' If laufendeObjekteTafel IsNot Nothing Then Marshal.ReleaseComObject(laufendeObjekteTafel) End If If monikerListe IsNot Nothing Then Marshal.ReleaseComObject(monikerListe) End If ' Return liste End Function End Module
in Function listeAllerFenstertitel() erhalte ich mithilfe Process.GetProcesses die MainWindowTitle aller wordinstanzen und in Function holeNamenAllerLaufendenCOMobjekte() hole ich die namen aller COMobjekte ab. darunter sind die pfade der geöffneten word-dokumente aufgeführt. in Sub wordFensterListe vergleiche ich beide listen und übernehme nur die entsprechenden pfade der MainWindowTitle. durch diese bekomme ich zugang zu allen word-instanzen, über die ich dann genauso wie auf die documents-auflistung zugreifen könnte.
das alles wird dir bestimmt sehr unprofessionell vorkommen und ist es ja auch, aber mir kommt die programmierei bei der verwaltung meiner schreibarbeiten doch sehr entgegen.
gruss, peter