AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Word-Datei einbinden, bearbeiten, speichern
Thema durchsuchen
Ansicht
Themen-Optionen

Word-Datei einbinden, bearbeiten, speichern

Ein Thema von AJ_Oldendorf · begonnen am 23. Jun 2021 · letzter Beitrag vom 28. Jun 2021
Antwort Antwort
Seite 1 von 2  1 2      
AJ_Oldendorf

Registriert seit: 12. Jun 2009
385 Beiträge
 
Delphi 12 Athens
 
#1

Word-Datei einbinden, bearbeiten, speichern

  Alt 23. Jun 2021, 10:51
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?
  Mit Zitat antworten Zitat
Edelfix

Registriert seit: 6. Feb 2015
Ort: Stadtoldendorf
214 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Word-Datei einbinden, bearbeiten, speichern

  Alt 23. Jun 2021, 11:35
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.
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
385 Beiträge
 
Delphi 12 Athens
 
#3

AW: Word-Datei einbinden, bearbeiten, speichern

  Alt 23. Jun 2021, 12:39
Danke, die Pas-Datei kannte ich noch gar nicht

Delphi-Quellcode:
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;
Damit kann ich eine Datei öffnen und wieder abspeichern.
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.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#4

AW: Word-Datei einbinden, bearbeiten, speichern

  Alt 23. Jun 2021, 14:11
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;
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
385 Beiträge
 
Delphi 12 Athens
 
#5

AW: Word-Datei einbinden, bearbeiten, speichern

  Alt 23. Jun 2021, 14:25
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?

Geändert von AJ_Oldendorf (23. Jun 2021 um 14:32 Uhr)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#6

AW: Word-Datei einbinden, bearbeiten, speichern

  Alt 23. Jun 2021, 15:01
Delphi-Quellcode:
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;
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.

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;
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
385 Beiträge
 
Delphi 12 Athens
 
#7

AW: Word-Datei einbinden, bearbeiten, speichern

  Alt 24. Jun 2021, 12:23
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...
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#8

AW: Word-Datei einbinden, bearbeiten, speichern

  Alt 24. Jun 2021, 13:08
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?
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
385 Beiträge
 
Delphi 12 Athens
 
#9

AW: Word-Datei einbinden, bearbeiten, speichern

  Alt 24. Jun 2021, 14:42
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
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#10

AW: Word-Datei einbinden, bearbeiten, speichern

  Alt 24. Jun 2021, 15:55
Zitat:
-die hinterlegten Dokumente sind Originale und dienen nur als "Vorlage" (sollen also nicht unter dem Dateinamen geändert werden können)
Dafür nimmt man Vorlagen (.dotx), die können nicht versehentlich verändert und gespeichert werden.
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:
-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
Das heißt noch lange nicht, dass man das nicht trotzdem aus Delphi heraus per Word fernsteuern könnte. (Formularfelder, Sprungmarken, ...)

Zitat:
-der User bestätigt in meiner Anwendung, dass er fertig ist
Wenn er vorher das Dokument gespeichert hat und dann Word beendet, existiert die Datei trotzdem. Das sollte mit wenig Aufwand zu prüfen sein.

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:
-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
Wie oben schon gesagt: Vorlagen verwenden (.docx in .dotx umbenennen) und aus diesen jeweils ein neues Dokument erstellen.

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:
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
  ...
Vorteil:

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?

Geändert von Delphi.Narium (24. Jun 2021 um 16:15 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:24 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz