PDA

Vollständige Version anzeigen : Aus Excel prüfen ob Word Dokument offen


mathieu_91
27.09.2016, 11:59
Hallo,

ich möchte aus EXCEL heraus prüfen, ob ein ganz bestimmtes Word Dokument bereits geöffnet ist.

Function IsDocumentOpen(ByVal DocName As String) As Boolean
Dim doc As Word.Document

If Right$(DocName, 5) <> ".docm" Then
DocName = DocName & ".docm"
End If
IsDocumentOpen = False
For Each doc In Word.Documents <-- Cannot create activeX element
If (StrComp(doc.Name, DocName, vbTextCompare) = 0) Then
IsDocumentOpen = True
Exit For
End If
Next doc
End Function

Im roten Bereich entsteht jedoch ein Fehler. Mit Documents alleine geht es auch nicht.
Wie kann ich genau durch alle offenen Word Docs gehen? Was passiert falls keine Word App grundsätzlich geöffnet ist?

Grüße

Mathieu

Edit:

Habe jetzt erweitert, jetzt funktioniert es. Wichtig war zudem, dass das offene Worddokument zuvor gespeichert wird... Nur geöffnete Dokumente fallen aus der Schleife raus, scheinbar...

Function IsDocumentOpen(ByVal DocName As String) As Boolean
Dim doc As Word.Document
Dim ObjWord As Object
On Error Resume Next
Set ObjWord = GetObject(, "Word.Application")
If Not ObjWord Is Nothing Then
If Right$(DocName, 5) <> ".docm" Then
DocName = DocName & ".docm"
End If
IsDocumentOpen = False
For Each doc In ObjWord.Documents
If (StrComp(doc.Name, DocName, vbTextCompare) = 0) Then
IsDocumentOpen = True
Exit For
End If
Next doc
Else
IsDocumentOpen = False
End If
End Function

EDIT: Also so richtig will es noch nicht. Zwischenzeitig hat er mein Dokument erkannt, gerade aber tut er es nicht mehr, bzw. in der For Schleife durch die Documents beendet er die Schleife sofort als wäre kein Dokument offen...

mathieu_91
27.09.2016, 13:46
Sorry für den Doppelpost.


FileName = Mid(ThisWorkbook.Worksheets("LOP-Config").Cells(98, 4).Value, _
InStrRev(ThisWorkbook.Worksheets("LOP-Config").Cells(98, 4).Value, "\") + 1)

result = FileStatus("C:\Users\" & Login & "\Desktop\temp_" & Login & "\" & FileName)
If result = XL_OPEN Then
Application.DisplayAlerts = False
Set AppWord = GetObject(, "Word.Application")
AppWord.Documents(FileName).Close SaveChanges:=False
Application.DisplayAlerts = True
Else
Set AppWord = CreateObject("Word.Application")
End If

Habe jetzt eine andere Funktion gefunden.
Leider erkennt

AppWord.Documents(FileName).Close SaveChanges:=False

den Dateinamen nicht, obwohl diese vorhanden und gerade geöffnet ist.

Das ist die Prüfung, ob die Datei geöffnet ist:

In ein neues Modul
Option Explicit

Public Enum XL_FILESTATUS
XL_UNDEFINED = -1
XL_CLOSED
XL_OPEN
XL_DONTEXIST
End Enum

Public Function FileStatus(xlFile As String) As XL_FILESTATUS
On Error Resume Next
Dim File%: File = FreeFile
Err.Clear
Open xlFile For Input Access Read Lock Read As #File
Close #File
Select Case Err.Number
Case 0: FileStatus = XL_CLOSED
Case 70: FileStatus = XL_OPEN
Case 76: FileStatus = XL_DONTEXIST
Case Else: FileStatus = XL_UNDEFINED
End Select
End Function

EDIT:

Habe noch eine weitere Funktion gefunden..


If IsFileOpen("C:\Users\" & Login & "\Desktop\temp_" & Login & "\" & filename) = True Then
Application.DisplayAlerts = False
Set AppWord = GetObject(, "Word.Application")
With AppWord
.visible = True
.Activate
.Documents("C:\Users\" & Login & "\Desktop\temp_" & Login & "\" & filename).Close SaveChanges:=False
End With
Application.DisplayAlerts = True
Else
Set AppWord = CreateObject("Word.Application")
With AppWord
.visible = True
.Activate
End With
End If

Function IsFileOpen(filename As String)
Dim filenum As Integer, errnum As Integer

On Error Resume Next ' Turn error checking off.
filenum = FreeFile() ' Get a free file number.
' Attempt to open the file and lock it.
Open filename For Input Lock Read As #filenum
Close filenum ' Close the file.
errnum = Err ' Save the error number that occurred.
On Error GoTo 0 ' Turn error checking back on.

' Check to see which error occurred.
Select Case errnum

' No error occurred.
' File is NOT already open by another user.
Case 0
IsFileOpen = False

' Error number for "Permission Denied."
' File is already opened by another user.
Case 70
IsFileOpen = True

' Another error occurred.
Case Else
Error errnum
End Select

End Function

Erkennt zwar, dass die Datei offen bzw. geschlossen ist, leider kann ich die Datei anschließend nicht schließen, was ich aber möchte...
Hat jemand eine Idee, wie ich die Word Datei schließen kann?

Leider Funktion, aus welchen Gründen auch immer, AppWord.Documents("Mein Doc.doc").Close hier nicht...

EDIT:

Jetzt läufts...

If IsFileOpen("C:\Users\" & Login & "\Desktop\temp_" & Login & "\" & filename) = True Then
Application.DisplayAlerts = False
Set DocToClose = GetObject("C:\Users\" & Login & "\Desktop\temp_" & Login & "\" & filename)
With DocToClose
.Close SaveChanges:=False
Set DocToClose = Nothing
End With
Set AppWord = GetObject(, "Word.application")
With AppWord
.visible = True
.Activate
End With
Application.DisplayAlerts = True
Else
Set AppWord = CreateObject("Word.Application")
With AppWord
.visible = True
.Activate
End With
End If

Danke für die.. Hilfe?

Storax
27.09.2016, 19:46
Also folgender Code funktioniert bei mir
Sub TesterA()

Dim wd As Word.Application

Dim wDoc As Word.Document

Set wd = GetObject(, "Word.Application")
If wd Is Nothing Then
Debug.Print "Word ist nicht gestartet"
exit sub
End If
For Each wDoc In Word.Documents
Debug.Print wDoc.Name
wDoc.Close False
Next

End Sub

Und So könntest Du prüfen, ob ein Dokument in Word geöffnet ist:Sub TesterB()

Dim myDocName As String
myDocName = "MyDok1.docx"
Debug.Print FileInWdOpen(myDocName)

End Sub
Function FileInWdOpen(DokName As String) As Boolean
Dim wd As Word.Application
Dim wDoc As Word.Document

Set wd = GetObject(, "Word.Application")

If wd Is Nothing Then
FileInWdOpen = False
End If

For Each wDoc In Word.Documents
If wDoc.Name = DokName Then
FileInWdOpen = True
Exit Function
End If
Next

FileInWdOpen = False

End Function
Über Verweise muss die Word Library eingebunden sein. Aber ich habe die Vermutung, Du weißt nicht genau, was die Code-Schnipsel, die Du gepostet hast, überhaupt tun :( Dann wird Dir das auch nicht helfen.

ebs17
27.09.2016, 20:31
prüfen, ob ein ganz bestimmtes Word Dokument bereits geöffnet ist
Man darf davon ausgehen, dass Du Pfad und Name des Dokumentes kennst?

Prüfen, ob Datei bereits geöffnet ist (https://is.gd/p1DfIm)

Auf dem Rechner können mehrere Wordinstanzen geöffnet sein. Wenn man also eine vorhandene beliebige Instanz anfasst, muss das Dokument nun nicht gerade in dieser offen sein.
Auf das (geprüft) offene Dokument erlangst Du so Zugriff:
Dim wDoc As Object
Dim wApp As Object

Set wDoc = GetObject(PfadUndNameDokument)
' Zugriff auf zugehörige Wordinstanz
Set wApp = wDoc.Application

haklesoft
28.09.2016, 09:17
Wenn ich mich recht erinnere wollte der TE das Dokument vor dem Schließen ggf. noch speichern, was auch der bessere Programmierstil ist.
Die MOF-Götter haben dieses - nur im Doppelpost - stehende Ansinnen aber gerade nach dem gleichen Motto gekillt. :upps:

Mit .Close SaveChanges:=Falsewerden jedenfalls alle Änderungen verworfen und nichts gespeichert :(

Da prüft man besser vorab und speichert ggf. direkt. wdDoc.Close SaveChanges:=Abs(Not wdDoc.Saved) * -2

mathieu_91
28.09.2016, 09:55
Hallo,

danke für die Infos.

Prinzipiell muss das Dokument nicht gespeichert werden.

Der Prozess ist folgender:

Es wird ein temp_UserName Ordner auf dem Desktop erzeugt. Sollte dort bereits einer sein, wird dieser gelöscht

--> Dafür muss aber die Word Datei geschlossen sein, sonst gibt es einen Zugriffsfehler <--

Anschließend wird das Template (Word Dokument), aus dem Netzwerk auf den Desktop in diesen Ordner kopiert und geöffnet.
Es werden Daten reingeschrieben.

Der Code endet.

Das Dokument soll dann vom Nutzer nur noch ergänzt, gedruckt und einfach wieder geschlossen werden.

Sollte der Nutzer jetzt auf die glorreiche Idee kommen diese Funktion erneut zu nutzen während das Dokument noch geöffnet sind, kommt es zu einem Fehler, daher die Prüfung ob erstens das Dokument geöffnet ist, falls ja, schließen ohne speichern und prüfen ob Wordinstanzen ohne Dokumente geöffnet sind und diese schließen.

Anschließend eine neue Instanz öffnen und das spiel beginnt von vorne.

Grüße

Mathieu

mathieu_91
28.09.2016, 10:00
Über Verweise muss die Word Library eingebunden sein. Aber ich habe die Vermutung, Du weißt nicht genau, was die Code-Schnipsel, die Du gepostet hast, überhaupt tun :( Dann wird Dir das auch nicht helfen.

Das ist jetzt erst einmal eine Behauptung.

Die API verstehe ich tatsächlich nicht.
Die Function IsFileOpen ist verständlich durch MS erklärt.

Storax
28.09.2016, 10:08
Das ist jetzt erst einmal eine Behauptung.

Die API verstehe ich tatsächlich nicht.
Die Function IsFileOpen ist verständlich durch MS erklärt.

Würde ich nicht so sehen, denn wenn Du z.B. IsFileOpen verstanden hättest, würdest Du auch verstehen, dass Du so keinen Zugriff auf die Datei erhältst, um sie in Word zu schließen.

mathieu_91
28.09.2016, 10:10
Vermutlich hast du recht, ja.
Naja, mit GetObject hat das ja dann alles geklappt...

Storax
28.09.2016, 10:13
Genau, GetObject reicht aus, um zu prüfen, ob die Datei in Word offen ist. Die Anmerkung von ebs17 ist natürlich richtig. Mein Code könnte krachen gehen, falls mehrere Instanzen von Word gestartet sind, was eher selten ist.