Hallo,
in einem vorhergehenden Post hatte ich das Thema schon einmal angesprochen:
Ich möchte über eine Wordautomation die Inhalte von Textfeldern in eine Wordvorlage übertragen. Die Wordvorlage enthält Textmarken in die die Daten der Textfelder aus Access übertragen werden. Soweit klappt dies bis jetzt einwandfrei auf meinem eigenen PC. Ich habe das Programm nun auf einen Server gelegt und dort gestartet. Nachdem es nun eine gewisse Zeit fehlerfrei gelaufen ist, taucht nun ab und zu eine Fehlermeldung auf:
"Automatisierungsfehler Ein Aufruf im Messagefilter ist unzulässig."
Hier mal kurz der Programmcode (Vorgänge die ablaufen sind auskommentiert):
Private Sub A3D3_Click()
On Error GoTo Err_A3D3_Click
Const Pfad As String = "C:\Eigene Dateien\"
' Pfadbeginn wo die neu erstellte Word Datei gespeichert wird
' ***********************************************************
Const wdDialogFileSaveAs = 84
' = Dialogfenster "Speichern" in Word
' ************************************
Dim appWord As Object, docWord As Object
' = docWord = Wordvorlage, appWord = neu erstellte Worddatei
' ******************************************************
Set appWord = CreateObject("word.application")
appWord.Visible = True
' = Erstellen von appWord als Word-Dokument
' = soll anschließend sichtbar sein
' ******************************************
Set docWord = appWord.Documents.Add("C:\Users\user\Documents\Formulare\Doc\A3D3.doc")
' = docWord = appWord = haben die gleichen Daten (und Pfadangabe zum Wordvorlagedokument)
' damit die Originalvorlage docWord unverändert bleibt
'**********************************************************************************
'Falls der Datensatz noch nicht gespeichert wurde= Eigenschaft Me.Dirty = True
'Durch Me.Dirty = False wird der Datensatz quasi gespeichert
If Me.Dirty Then
MsgBox "Sie müssen den Datensatz erst speichern", vbInformation
Me.Dirty = False
appWord.Visible = False 'Worddokument schließen
Exit Sub
End If
'Eingaben erlauben
'******************************************
Me.AllowEdits = True
Me.AllowAdditions = True
Me.AllowDeletions = True
'Abfrage ob Eingaben vergessen wurden
' ******************************************
If Len(Trim(Me!Anrede & vbNullString)) = 0 Then
MsgBox ("Fehler: Anrede vergessen!!!")
Me!Anrede.SetFocus
appWord.Visible = False 'Worddokument schließen
Exit Sub
End If
If Len(Trim(Me!Vorname & vbNullString)) = 0 Then
MsgBox ("Fehler: Vorname vergessen!!!")
Me!Vorname.SetFocus
appWord.Visible = False 'Worddokument schließen
Exit Sub
End If
If Len(Trim(Me!Nachname & vbNullString)) = 0 Then
MsgBox ("Fehler: Vorname vergessen!!!")
Me!Nachname.SetFocus
appWord.Visible = False 'Worddokument schließen
Exit Sub
End If
If Len(Trim(Me!Strasse & vbNullString)) = 0 Then
MsgBox ("Fehler: Strasse vergessen!!!")
Me!Nachname.SetFocus
appWord.Visible = False 'Worddokument schließen
Exit Sub
End If
If Len(Trim(Me!PLZ & vbNullString)) = 0 Then
MsgBox ("Fehler: PLZ vergessen!!!")
Me!PLZ.SetFocus
appWord.Visible = False 'Worddokument schließen
Exit Sub
End If
If Len(Trim(Me!Ort & vbNullString)) = 0 Then
MsgBox ("Fehler: Ort vergessen!!!")
Me!Ort.SetFocus
appWord.Visible = False 'Worddokument schließen
Exit Sub
End If
If Len(Trim(Me!EinzelgesprächeA & vbNullString)) = 0 Then
MsgBox ("Fehler:" & vbCrLf & "Datum Einzelgespräche Anfang vergessen!!!")
Me!EinzelgesprächeA.SetFocus
appWord.Visible = False 'Worddokument schließen
Exit Sub
End If
If Len(Trim(Me!EinzelgesprächeE & vbNullString)) = 0 Then
MsgBox ("Fehler:" & vbCrLf & "Datum Einzelgespräche Ende vergessen!!!")
Me!EinzelgesprächeE.SetFocus
appWord.Visible = False 'Worddokument schließen
Exit Sub
End If
If Len(Trim(Me!AnzahlE & vbNullString)) = 0 Then
MsgBox ("Fehler:" & vbCrLf & "Anzahl Einzelgespräche vergessen!!!")
Me!AnzahlE.SetFocus
appWord.Visible = False 'Worddokument schließen
Exit Sub
End If
'********************************************************************************
' Herr Frau = seines oder ihres
If Me!Anrede = "Herr" Then
Me!seines = "seines"
Else
Me!seines = "ihres"
End If
' ********************************************************************************
' = Routine zum Übertragen der Accesstextfelder in die Word Textmarken von docWord
' = in die Originalvorlage wird das Textfeld von Access geschrieben.
' = da ja docWord und appWord gleich sind wird auch in appWord dies geschrieben
With docWord
.Bookmarks("Anrede").range = Me!Anrede
.Bookmarks("Vorname").range = Me!Vorname
.Bookmarks("Nachname").range = Me!Nachname
.Bookmarks("Strasse").range = Me!Strasse
.Bookmarks("PLZ").range = Me!PLZ
.Bookmarks("Ort").range = Me!Ort
.Bookmarks("seines").range = Me!seines
.Bookmarks("EinzelgesprächeA").range = Me!EinzelgesprächeA
.Bookmarks("EinzelgesprächeE").range = Me!EinzelgesprächeE
.Bookmarks("AnzahlE").range = Me!AnzahlE
End With
' ********************************************************************************
' = Routine zum Abspeichern und öffnen des neuen Dokuments
appWord.ChangeFileOpenDirectory ("C:\Users\user\Documents\Formulare\Bescheinigungen")
With appWord.Dialogs(wdDialogFileSaveAs)
.Name = Format(Date, "yyyy-mm-dd")
.Show
Set docWord = Nothing
End With
' ********************************************************
Application.Forms!frmDebitoren.Controls!Rechnung = False
Exit_A3D3_Click:
Exit Sub
Err_A3D3_Click:
MsgBox Err.Description
Resume Exit_A3D3_Click
End Sub
Was ich nicht verstehe warum das Ganze fehlerfrei auf meinem PC läuft (Windows 10) und immer wieder mal eine Fehlermeldung verursacht wird auf dem Server (Windows 2012 R2)
Grüße
Herri
Hallo, was ich vergessen habe zu erwähnen: auf meinem PC ist Office 2013 (Access Version 15.0..) und auf dem Server Access 2003.
Gruß
Herri
Hallo,
auf den ersten Blick ist ersichtlich, dass die Word-Instanz nicht geschlossen wird und damit weiterhin existiert. Das führt zu mehreren Instanzen im Speicher, was die Fehlermeldung erklären könnte.
ZitatappWord.Visible = False 'Worddokument schließen
schließt nicht das Dokument, bzw. Word, es wird lediglich am Bildschirm unsichtbar...
Die ganzen IF-B(l)öcke sollten besser organisiert und auf "Exit Sub" verzichtet werden. Ein(!) Ausgang aus der Sub sollte reichen, wobei dann an dieser Stelle "aufgeräumt" werden kann, soll heißen, das Dokument zu speichen/schliessen und die Word-Instanz schliessen (appWord.Quit). Weiterhin sollten die Objekt-Referenzen mit Set docWord = Nothing und Set appWord = Nothing, zerstört werden.
Zitat von: DF6GL am November 10, 2020, 10:47:12Hallo,
auf den ersten Blick ist ersichtlich, dass die Word-Instanz nicht geschlossen wird und damit weiterhin existiert. Das führt zu mehreren Instanzen im Speicher, was die Fehlermeldung erklären könnte.
ZitatappWord.Visible = False 'Worddokument schließen
schließt nicht das Dokument, bzw. Word, es wird lediglich am Bildschirm unsichtbar...
Die ganzen IF-B(l)öcke sollten besser organisiert und auf "Exit Sub" verzichtet werden. Ein(!) Ausgang aus der Sub sollte reichen, wobei dann an dieser Stelle "aufgeräumt" werden kann, soll heißen, das Dokument zu speichen/schliessen und die Word-Instanz schliessen (appWord.Quit). Weiterhin sollten die Objekt-Referenzen mit Set docWord = Nothing und Set appWord = Nothing, zerstört werden.
Hallo Franz, vielen Dank! Werde ich machen.
Grüße
Herri
So, ich habe jetzt mal eine Sprungmarke an das Ende (vor dem Fehlerhandler) gesetzt und diese Sprungmarke für die "Exit Sub" eingesetzt. Die Sprungmarke ist dann für das aufräumen zuständig:
If Len(Trim(Me!EinzelgesprächeA & vbNullString)) = 0 Then
MsgBox ("Fehler:" & vbCrLf & "Datum Einzelgespräche Anfang vergessen!!!")
Me!EinzelgesprächeA.SetFocus
appWord.Visible = False 'Worddokument unsichtbar
GoTo Bereinigung
End If
.
.
.
.
With appWord.Dialogs(wdDialogFileSaveAs)
.Name = Format(Date, "yyyy-mm-dd")
.Show
End With
' = Routine zum Abspeichern und öffnen des neuen Dokuments
' ********************************************************
'**************Bereinigung******************************
Bereinigung:
Set docWord = Nothing
Set appWord = Nothing
Exit_A3D3_Click:
Exit Sub
Err_A3D3_Click:
MsgBox Err.Description
Resume Exit_A3D3_Click
End Sub
Was mir noch nicht so richtig klar ist, was du mit "besser organisieren der If-Blöcke" meinst? Ich wüsste jetzt nicht wie man dies vereinfachen kann.
Noch eine Frage:
With appWord.Dialogs(wdDialogFileSaveAs)
.Name = Format(Date, "yyyy-mm-dd")
hier wird ja mit dem aktuellen Datum abgespeichert. Ich könnte aber genauso gut z.B. mit dem Nachnamen abspeichern - also so:
With appWord.Dialogs(wdDialogFileSaveAs)
.Name = Me!Nachname
Grüße
Herri
Hallo,
unabhängig davon, dass "GoTo Sprungmarke" recht verpönt ist, fehlt immer noch das Beenden der Word-Instanz(en)....
Hallo Franz,
mit appWord.Quit bekomme ich eine Fehlermeldung:
"Objekt unterstützt diese Eigenschaft der Methode nicht"
Ist es möglich, dass dies durch das Late Binding kommt?
Gruß
Herri
Hallo,
das hat mit Late Binding nichts zu tun..
Zeig mal den kompletten Code der Prozedur..
Vermutlich steht die Codezeile an einer falschen Stelle.
Hallo Franz,
hier der untere (letzte) Teil der Prozedur:
.
.
.
If Len(Trim(Me!AnzahlE & vbNullString)) = 0 Then
MsgBox ("Fehler:" & vbCrLf & "Anzahl Einzelgespräche vergessen!!!")
Me!AnzahlE.SetFocus
appWord.Visible = False 'Worddokument unsichtbar
GoTo Bereinigung
End If
'********************************************************************************
' Herr Frau = seines oder ihres
If Me!Anrede = "Herr" Then
Me!seines = "seines"
Else
Me!seines = "ihres"
End If
' ********************************************************************************
' = Routine zum Übertragen der Accesstextfelder in die Word Textmarken von docWord
' = in die Originalvorlage wird das Textfeld von Access geschrieben.
' = da ja docWord und appWord gleich sind wird auch in appWord dies geschrieben
With docWord
.Bookmarks("Anrede").range = Me!Anrede
.Bookmarks("Vorname").range = Me!Vorname
.Bookmarks("Nachname").range = Me!Nachname
.Bookmarks("Strasse").range = Me!Strasse
.Bookmarks("PLZ").range = Me!PLZ
.Bookmarks("Ort").range = Me!Ort
.Bookmarks("seines").range = Me!seines
.Bookmarks("EinzelgesprächeA").range = Me!EinzelgesprächeA
.Bookmarks("EinzelgesprächeE").range = Me!EinzelgesprächeE
.Bookmarks("AnzahlE").range = Me!AnzahlE
End With
' ********************************************************************************
appWord.ChangeFileOpenDirectory ("C:\Users\user\Documents\Formulare\Bescheinigungen")
With appWord.Dialogs(wdDialogFileSaveAs)
.Name = Me!Nachname
.Show
End With
' = Routine zum Abspeichern und öffnen des neuen Dokuments
' ********************************************************
Bereinigung:
appWord.Quit
Set docWord = Nothing
Set appWord = Nothing
Exit_A3D3_Click:
Exit Sub
Err_A3D3_Click:
MsgBox Err.Description
Resume Exit_A3D3_Click
End Sub
Ich hatte auch schon gedacht, appWord.Quit an anderen Stellen zu platzieren hat aber nix gebracht.
Grüße
Herri
Hallo,
vermutlich fehlt das Schließen des Docs:
Bereinigung:
docword.Close
appWord.Quit
Hallo Franz, vielen Dank! Ich habe dies auch noch mit aufgenommen. Es funktioniert jetzt einwandfrei. Ich habe auch noch mal eine Reparatur von meinem Office vorgenommen. Das Einzige was jetzt noch unschön ist: Beim Abspeichern öffnet sich auf meinem eigenen PC Worddialog zum Abspeichern und legt sich vor das Accessprogramm. Auf dem Server bleibt das im Hintergrund. Hängt wahrscheinlich damit zusammen, dass es sich um ein älteres Office (2003) handelt. Gibt es da noch eine Möglichkeit, dass zu ändern dh. zu erzwingen, dass sich der Worddialog in den Vordergrund stellt?
Grüße
Herri
Hallo,
dann sag Word, dass es nicht speichern soll. Die Close-Methode hat einen "SaveChanges"-Parameter:
docword.Close False
Hallo Franz,
astrein - hat sofort geklappt! Vielen Dank für deine Hilfe!
Schon interessant: Du hattest mir vor Jahren im Spotlight-Forum schon viel geholfen
und jetzt auch hier.
Vielen lieben Dank auch an all die Anderen die hier immer wieder helfen wenn Not am Mann ist!
Grüße
Herri
Hi,
mhmm,ja, Spotlight.... Da schwelgt man ein bisschen in Nostalgie :'( ,
auch wenn ich mich jetzt nicht mehr so ganz genau (an Dich) erinnere...vielleicht hast Du jetzt aber auch einen anderen Nickname.