![]() |
Word-Datei einbinden, bearbeiten, speichern
Hallo zusammen,
ich habe schon ein bisschen was im Forum gefunden, würde aber gerne mal meine Aufgabe erklären und suche ein paar Antworten dazu. Ich möchte aus meinem Programm heraus eine vorhandene Word-Datei öffnen, diese mit Word bearbeiten und anschließend unter einem vorgegebenen Namen wieder abspeichern. Die Original Word-Datei soll selber gar nicht geändert werden. Diese dient wie eine Vorlage, das bearbeitete Dokument soll einen Dateinamen bekommen, den ich aus meinem Programm vorgebe. Geht das so überhaupt? Ich habe schon bzgl. der OLE Schnittstelle gelesen. Gibt es eine Übersicht, aller möglichen Befehle, damit ich das oben beschriebene realisieren/testen kann? |
AW: Word-Datei einbinden, bearbeiten, speichern
Hallo,
auf die Frage "Geht das so überhaupt?" ist die Antwort ja. Ein paar Tipps: word2010.pas ist eine gute Hilfe. Mach dich vertraut mit dem Word Format dotx (Type Word Vorlage) Wenn du "Hallo Word" hast dann melde dich bitte. |
AW: Word-Datei einbinden, bearbeiten, speichern
Danke, die Pas-Datei kannte ich noch gar nicht :shock:
Delphi-Quellcode:
Damit kann ich eine Datei öffnen und wieder abspeichern.
procedure TForm1.Button1Click(Sender: TObject);
begin try WordApp.Documents.Open('D:\Test1.docx'); finally end; end; procedure TForm1.Button2Click(Sender: TObject); begin WordApp.ActiveDocument.SaveAs('D:\Test2.docx'); end; procedure TForm1.FormCreate(Sender: TObject); begin WordApp := CreateOLEObject('Word.Application'); end; procedure TForm1.FormDestroy(Sender: TObject); begin WordApp := Unassigned; end; Komischerweise bleibt am Ende aber immer die Tilde-Datei der Test2.docx vorhanden und die Test2.docx scheint von irgendeinem Prozess in Verwendung zu sein, weil ich sie auch nicht löschen kann im Explorer. |
AW: Word-Datei einbinden, bearbeiten, speichern
Wenn Du im Taskmanager nachschaust, wirst Du feststellen, dass Word noch läuft (und das geöffnete Dokument nicht geschlossen wurde und (vermutlich) jeder ButtonClick eine weitere Wordinstanz erstellt).
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var vParam : OleVariant; begin // Aktuelles Dokument unter neuem Namen speichern. WordApp.ActiveDocument.SaveAs('D:\Test2.docx'); // Aktuelles Dokument (ohne Änderungen zu speichern) schließen. vParam := wdDoNotSaveChanges; WordApp.ActiveDocument.Close(vParam); end; procedure TForm1.FormDestroy(Sender: TObject); begin WordApp.Quit; // Word beenden. WordApp := Unassigned; end; |
AW: Word-Datei einbinden, bearbeiten, speichern
Ok, danke.
Wenn der User aber Word manuell schließt, dann kommt im Destroy eine Fehlermeldung, weil Word nicht mehr offen ist. Kann man denn verhindern, dass der User diese Instanz manuell beendet? Das öffnen und schließen sollte nur aus meiner Anwendung gehen Oder gibt es ein Event, welches man verknüpfen könnte, um auf das geschlossene Word zu reagieren? Eine Sache noch, wenn ich zwischen dem Button1 (öffnen) und dem Button2 (speichern mit SaveAs) an dem Word Dokument änderungen vornehme, werden diese in meinem zweiten Word Dokument immer gespeichert, egal ob ich "wdDoNotSaveChanges" oder "wdSaveChanges" mit anschließenden Close aufrufe. Was bringt mir also das mit den beiden Parametern? |
AW: Word-Datei einbinden, bearbeiten, speichern
Delphi-Quellcode:
SaveAs speichert das Dokument so, wie es gerade ist. Wenn man was ändert, speichert man die Änderungen natürlich mit. Das Originaldokument sollte aber ohne Änderungen geschlossen werden.
procedure TForm1.FormDestroy(Sender: TObject);
begin Try WordApp.Quit; // Word beenden. Except // Fehlermeldung ausgeben oder sonstwas machen oder Fehler ignorieren. end; Try WordApp := Unassigned; Except // Fehlermeldung ausgeben oder sonstwas machen oder Fehler ignorieren. end; end; wdDoNotSaveChanges bzw. wdSaveChanges beziehen sich auf das WordApp.ActiveDocument.Close und werden diesem als Parameter übergeben. WordApp.ActiveDocument.SaveAs weiß davon nix. WordApp.ActiveDocument.Close(wdSaveChanges) speichert Änderungen im aktiven Dokument und schließt es. WordApp.ActiveDocument.Close(wdDoNotSaveChanges) verwirft Änderungen im aktiven Dokument und schließt es. WordApp.ActiveDocument.SaveAs('Dokumentenname.docx ') speichert das aktive Dokument, so wie es gerade ist, unter dem angegebenen Namen. Es wäre mal zu prüfen, ob sich durch SaveAs das aktive Dokument ändert (vermutlich ja). Mal folgende Annahme: Button1Click Dann Änderungen machen Button2Click Dann sind die Änderungen im Dokument unter neuem Namen gespeichert. Das per SaveAs gespeicherte Dokument entspricht damit nicht mehr dem mit Button1Click geöffneten Dokument.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin WordApp.Documents.Open('D:\Test1.docx'); WordApp.ActiveDocument.SaveAs('D:\Test2.docx'); // Hier sind die Dokumente Test1.docx und Test2.docx (noch) gleich. end; // Jetzt was im Dokument ändern. procedure TForm1.Button2Click(Sender: TObject); var vParam : OleVariant; begin // Aktuelles Dokument (ohne Änderungen zu speichern) schließen. vParam := wdDoNotSaveChanges; WordApp.ActiveDocument.Close(vParam); // Damit dürften dann die Änderungen in der per SaveAs erstellten Kopie // nicht enthalten sein. end; |
AW: Word-Datei einbinden, bearbeiten, speichern
Danke für die Hinweise.
Gibt es denn die Möglichkeit zu verhindern, dass der User Word manuell schließt und damit die Änderungen evtl. nicht gespeichert werden? Oder ein Event worauf man reagieren kann? Könnte man Word in die eigene Anwendung einbinden (Parent/Frame) sodass das manuelle Schließen gar nicht möglich ist. Ich will verhindern, dass der User etwas im Word ändert und es dann nicht abspeichert. Das Speichern über meine Software kann ich ja auslösen aber wenn der User vorher das Word geschlosse und nicht gespeichert hat, habe ich nichts mehr... |
AW: Word-Datei einbinden, bearbeiten, speichern
Bevor wir jetzt einzelne Probleme lösen, ohne den eigentlichen Zusammenhang zu kennen, beschreibe bitte zuerste einmal ganz abstrakt den anvisierten Arbeitsablauf.
Danach kann man dann ggfls. klären, ob und wie eine Umsetzung realisiert werden kann. Mir ist momentan z. B. unklar, ob der User das Worddokument bearbeiten kann oder ob er es bearbeiten muss, ... Wenn das Worddokument bearbeitet werden muss, was hat der User dort zu erledigen? Sind das individuelle Daten oder könnte man diese auch per Automatismus ins Dokument einfügen lassen, sofern man nur weiß, wie dieser Automatismus auszusehen hat? |
AW: Word-Datei einbinden, bearbeiten, speichern
Ok, relativ einfach beschrieben folgender Ablauf:
-in meiner Anwendung sind n-Word-Dokumente hinterlegt und können geöffnet werden (es sollte immer nur 1 Word Dokument geöffnet werden können) -die hinterlegten Dokumente sind Originale und dienen nur als "Vorlage" (sollen also nicht unter dem Dateinamen geändert werden können) -der User füllt da drinne Text aus und setzt hier und da in einer Tabelle ein paar Haken -Hinweis: jedes Word Dokument sieht anders aus, kein fester Aufbau -der User bestätigt in meiner Anwendung, dass er fertig ist -die Original-Datei bleibt wie sie war und der geänderte Inhalt wird unter einem festen Dateinamen (den meine Anwendung vergibt) irgendwo auf der Platte gespeichert Das wars eigentlich schon |
AW: Word-Datei einbinden, bearbeiten, speichern
Zitat:
Man erstellt ein neues Dokument unter Nutzung der Vorlage: Damit fällt dann schonmal das SaveAs und das Close des "Originals" unter Sicherstellung, dass es nicht verändert wurde, weg. Zitat:
Zitat:
Frei nach dem Motto: User sagt im Programm "Fertig", Programm merkt, das Word weg ist, dann schaut es halt nach der Datei und nimmt die zur weiteren Verarbeitung. Zitat:
Wenn das schon zu aufwändig ist, dann eben zuerst mit Delphimitteln von der Originaldatei eine Kopie erstellen (und nicht mit ferngesteuertem Word aus Delphi heraus). Dann hat die in Word zu öffnende Datei bereits den richtigen Namen (den von Deinem Programm zu vergebenden). Der User kann dann machen was er will. Wenn der den regulären Weg nimmt, dann kannst Du aus Deinem Programm heraus nochmal das Speichern und Schließen der Datei via Word veranlassen und die Datei weiterverarbeiten. Hat der User Word beendet und meldet erst dann in Deinem Programm, dass er fertig ist, so merkst Du das in Deinem Programm ja durch geschickte Fehlerbehandlung und da der Name der Datei bekannt ist, kannst Du sie von der Festplatte aus weiterverarbeiten. Hat der User vor dem Beenden von Word und der Fertigmeldung im Programm seine Änderungen nicht gespeichert, dann haben Du und der User schlicht und einfach Pech gehabt. Wenn das neue Dokument via Word aus einer Vorlage erstellt wurde, so merkst Du bei einem ungespeicherten Beenden von Word vor der Fertigmeldung des Users im Programm, dass die Datei fehlt. Dann muss der User halt nochmal ran (nach entsprechender Fehlermeldung ...) Hast Du das neue Dokument vorher per Copy aus Delphi heraus erstellt, kannst Du anhand des Erstelldatums oder des Datums der letzten Änderung im Programm prüfen, ob der User die Datei vorm Beenden von Word bearbeitet und gespeichert hat. Im Zweifelsfalle könnte man das auch über 'nen MD5-Checksummenvergleich (o. ä.) von Originaldatei und Userkopie überprüfen. Gegen Fehlbedienung, Nichteinhaltung der vorgesehene Verarbeitungsschritte, Nutzung "Deiner" Wordinstanz und deren Weiterverwendung für andere Dokumente, deren vorzeitiges Beenden, ... hast Du keine realistische Chance. Ist die Einhaltung der Verarbeitungsschritte zwingend erforderlich, dann muss der User halt dann, wenn er das Dokument und / oder Word vorzeitig beendet, aus Deinem Programm via Fehlermeldung darauf hingewiesen werden, dass er sich gefälligst an den vorgegeben Arbeitsablauf zu halten hat und muss den Verarbeitungsschritt solange wiederholen, bis er es in der richtigen Reihenfolge schafft. Glaubst garnicht, wie schnell die User dann lernfähig werden und sich an die vorgegebene Abfolge halten. Arbeit doppelt (oder nochmehrfach) machen, ist äußerst unbeliebt, da hält man sich dann doch eher an die Vorgaben, wenn deren Einhaltung im Endeffekt mit weniger Aufwand verbunden ist ;-) Und nein: Eine absolut (User)sichere Implementierung der von Dir aufgezeigten Verarbeitungsschritte, halte ich nicht für möglich. Neues Dokument anhand einer Vorlage erstellen:
Delphi-Quellcode:
Vorteil:
var
vDOT : OleVariant; vNewDOT : OleVariant; vDocType : OleVariant; vVisible : OleVariant; begin vDOT := 'Name der Vorlage.dotx'; // Mal ausprobieren, ob das auch mit 'nem .docx geht. vNewDOT := False; vVisible := True; vDocType := EmptyParam; WordApp.Documents.Add(vDOT, vNewDOT, vDocType, vVisible); // Weiterer Zugriff auf dieses neue Dokument dann per WordApp.ActiveDocument ... Das neue Worddokument hat noch keinen Namen. Wenn der User nun die Datei speichert, weiß er (hoffentlich) den zu vergebenden Namen nicht und scheitert daran, mit der Folge, dass er Word auch nicht ohne Datenverlust beenden kann. Eventuell ein gangbarer Weg? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz