Inhalt einer TXT-Datei in Word-Datei schreiben

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
pascalts
Beiträge: 61
Registriert: Fr 10. Okt 2014, 13:16

Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von pascalts »

Hallo!

Ich habe einige Text-Dateien, welche im Ordner

Code: Alles auswählen

SelectDirectoryDialogStammverzeichnis.FileName + '/Temp/TXT/'
liegen. Der komplette Inhalt dieser Dateien muss hintereinander in ein Word-Dokument geschrieben werden. Die Stelle im Word-Dokument ist durch eine Textmarke (Bookmark) gekennzeichnet (und heisst "VerwendeteFolgen").

Ich habe in der Wiki schon gelesen, dass ich damit arbeiten muss. Leider bin ich mir noch im unklaren, wie dies konkret umzusetzen ist (also a) das auslesen aus den TXT-Dateien und b) das stupide hintereinanderknallen des Inhalts in ein Word-Dokument).

Danach soll das Dokument auch noch unter einem anderen Name abgespeichert werden (das ursprüngliche Dokument ist eine Vorlage und sollte unangetastet bleiben).

Danke!

Boris
Beiträge: 18
Registriert: Mo 1. Okt 2007, 21:57
OS, Lazarus, FPC: Linux: KDE Neon, Sparky - akt. Lazarus stable, FPC 3.0.2
CPU-Target: 32/64Bit
Wohnort: Rommerskirchen, NRW

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von Boris »

Hallo Pascalts,

du könntest zum einen die Datei zum lesen öffnen und Zeilenweise bis zum Ende der Datei die Zeilen auslesen und in dein Word-Dokument schreiben. Hier findest du ein paar Anregungen: http://wiki.freepascal.org/File_Handling_In_Pascal

Zum anderen könntest du die Datei auch mit der Funktion LoadFromFile einer TStringlist einlesen und diese dann Zeilenweise weiterreichen, hier ein paar Anregungen dazu: http://wiki.freepascal.org/TStringList- ... utorial/de

Falls du dich für eine der beiden Varianten entscheidest, sieht eine Schleife, mit der du das auslesen und weiterreichen erledigst in etwa so aus:

Code: Alles auswählen

While not eof(Eingabedatei) do
    begin
      read ("aus Datei");
      write ("nach Word");
    end;
 


Bei der Stringlist sieht es dann so aus:

Code: Alles auswählen

 
for intI := 0 to strList.Count -1 do
  begin
   write ("Worddatei", strList[intI]);
  end;
 


Für etwas mehr Codegerüst etc. müsstest du aber selbst mal im Wiki oder mit Google schauen, da findest du sicher noch etwas mehr ergänzende Infos.

Viele Grüße

Boris

pascalts
Beiträge: 61
Registriert: Fr 10. Okt 2014, 13:16

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von pascalts »

So - hab das ganze jetzt mal ausprobiert...:

Code: Alles auswählen

unit uRTAWW;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, ComObj, lclproc;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
  varWdApp: oleVariant;      // Reserviert Speicher für die Programmsteuerung
  varDokument: oleVariant;   // Reserviert Speicher für die Steuerung des Worddokuments
  File1: TextFile;
  Str: String;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
begin
         try
           varWdApp := CreateOleObject('Word.Application'); // erstellt das Wordobjekt
           varWdApp.Visible := True
         except
           ShowMessage('MS Word kann nicht gestartet werden. Ist es installieret?'); // Fehlerbehandlung
         end;
         begin
          ShowMessage('File Reading:');
           AssignFile(File1, 'D:\Test.txt');
            {$I+}
             try
              Reset(File1);
              varDokument := varWdApp.Documents.Add;
              varDokument.Activate;
             repeat
              Readln(File1, Str); // Reads the whole line from the file
              // Writes the line read
              begin
                  varWdApp.Selection.TypeText(Text := Str); //Hier gibt es DAS PROBLEM
              end;
             until(EOF(File1)); // EOF(End Of File) The the program will keep reading new lines until there is none.
              CloseFile(File1);
              varDokument.SaveAs('D:\Test.doc'); // Speichert das Worddokument unter einem neuen Namen
             except
              on E: EInOutError do
               begin
                ShowMessage('File handling error occurred. Details: '+E.ClassName+'/'+E.Message);
               end;
             end;
             ShowMessage('Program finished. Press enter to stop.');
          end;
  varWdApp.Quit;
  varWdApp := Unassigned;
end;
 
end.
 


Funktioniert schon etwas ;-) Bis zu dem Punkt, wo etwas ins Word Dokument soll. Es werden einige Kryptische (Chinesische?) Zeichen hinein geschrieben, dann gibt es folgende Fehlermeldung:

Projekt pRTAWW hat Exception-Klasse >>EOleSysError<< ausgelöst mit der Meldung: F?r diesen Vorgang ist nicht gen?gend Speicher verf?gbar.

Bei Adresse 55375D


Danke im Voraus!

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von wp_xyz »

Word will WideStrings, Lazarus hat aber nur UTF8Strings. Aber du kannst mit UTF8Decode die Lazaraus-Strings umwandeln. So läuft's bei mir:

Code: Alles auswählen

 
procedure TForm1.Button1Click(Sender: TObject);
var
  wstr: WideString;
  // Die folgenden Variablen brauchst du doch nur hier --> nicht global deklarieren
  str: String;
  varWdApp: oleVariant;
  varDokument: oleVariant;
  File1: TextFile;
begin
  varWdApp := CreateOleObject('Word.Application');
  varWdApp.Visible := True;
  varDokument := varWdApp.Documents.Add;
  varDokument.Activate;
 
  AssignFile(File1, 'c:\temp\test.txt');
  Reset(File1);
  while not EOF(File1) do begin
    ReadLn(File1, str);
    wStr := UTF8Decode(str);
    varWdApp.Selection.TypeText(wstr);
    varWdApp.Selection.TypeParagraph;
  end;
  CloseFile(File1);
 
  varDokument.SaveAs('c:\temp\test.doc');
  varWdApp.Quit;
  varWdApp := Unassigned;
end
 

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von theo »

Auf die Gefahr hin mich zu blamieren: Kann mir jemand dieses Konstrukt erklären, so wie es hier zu finden ist?

Code: Alles auswählen

varWdApp.Selection.TypeText(Text := 'Neuer Text. ');

Ist "TypeText" nicht eine Prozedur? Wieso "übergibt" man dort eine Zuweisung?
Stehe grad auf dem Schlauch.

Danke für Hinweise.

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von wp_xyz »

Ich glaube, in Visual Basic können Prozeduren "benannte Parameter" (o.ä.) haben, die nicht anhand der Reihenfolge, sondern anhand des Namens erkannt werden.

Seltsamerweise akzeptiert der fpc-Compiler dieses Konstrukt, aber später zur Laufzeit kommt die Fehlermeldung, dass die Methode TypeText vom Automationsobjekt nicht unterstützt wird; ohne die Zunweisung, so wie oben von mir gepostet, läuft die Methode jedoch problemlos durch.

pascalts
Beiträge: 61
Registriert: Fr 10. Okt 2014, 13:16

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von pascalts »

Vielen Dank! Damit komme ich endlich voran. :mrgreen:

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von theo »

wp_xyz hat geschrieben:Ich glaube, in Visual Basic können Prozeduren "benannte Parameter" (o.ä.) haben, die nicht anhand der Reihenfolge, sondern anhand des Namens erkannt werden.

Seltsamerweise akzeptiert der fpc-Compiler dieses Konstrukt, aber später zur Laufzeit kommt die Fehlermeldung, dass die Methode TypeText vom Automationsobjekt nicht unterstützt wird; ohne die Zunweisung, so wie oben von mir gepostet, läuft die Methode jedoch problemlos durch.


Danke. Somit müsste man das oben verlinkte Wiki Bsp. korrigieren, oder hat das in irgend einer Konstellation/Version seine Berechtigung?

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von Michl »

Wird wohl ein copy+paste-Fehler sein...geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

pascalts
Beiträge: 61
Registriert: Fr 10. Okt 2014, 13:16

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von pascalts »

Okay, da nun die Basis funktioniert bin ich schon weiter. ABER. Der Text soll an einem Bookmark gesetzt werden. Funktioniert auch. Aber mit deiner Schleife setzt er immer wieder an dem Bookmark an, und springt somit immer wieder vor den gerade geschriebenen Text...:

Code: Alles auswählen

procedure TForm1.Button3Click(Sender: TObject);
var
   wstr: WideString;
   str: String;
   varWdApp: oleVariant;
   varDokument: oleVariant;
   File1: TextFile;
   varBookmark: oleVariant;
 
begin
  varWdApp := CreateOleObject('Word.Application');
  varWdApp.Visible := True;
  varDokument := varWdApp.Documents.Open('D:\vorlage.docm'); //vorhandenes Dokument öffnen
  if varDokument.Bookmarks.Exists('Folgen') then ShowMessage('Ja')//Prüft, ob eine Bookmark vorhanden ist
  varBookmark := Unassigned;  //Bookmark befreien...
  AssignFile(File1, 'D:\Test.txt')
  Reset(File1);
 
  while not EOF(File1) do
   begin
    ReadLn(File1, str);
    wStr := UTF8Decode(str);
    varBookmark := varDokument.Bookmarks.Item('Folgen'); //zu Bookmark "Folgen springen"
    varBookmark.Range.Text := wStr; //den Text eintragen
  end;
 
  varDokument.SaveAs('D:\Test.doc');
  varWdApp.Quit;                                                                     //Word beenden
  varWdApp := Unassigned;
end;
 


Es wird halt immer wieder an die selbe Stelle geschrieben... wie mache ich, das es nacheinander schreibt?

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2640
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von m.fuchs »

Zum Beispiel indem du die Dateiinhalte erst einmal nacheinander in einen String schreibst und diesen danach in einem Rutsch an die Stelle des Bookmarks.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

pascalts
Beiträge: 61
Registriert: Fr 10. Okt 2014, 13:16

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von pascalts »

Soweit vielen Dank, komme durchaus voran - was für mich sehr wichtig ist. Ein Problem habe ich noch, wenn ich ein Dokument über eine Variable öffnen möchte...:

Code: Alles auswählen

vorlagepfad := SelectDirectoryDialogVorlage.FileName + '\vorlage.docm';
ShowMessage(vorlagepfad);
varDokument := varWdApp.Documents.Open(vorlagepfad);


Word ist in dem Moment schon offen... wenn ich

Code: Alles auswählen

varDokument := varWdApp.Documents.Open('C:\ordner\vorlage.docm');
öffne geht das... der selbe Pfad als Variable geht nicht... verzweifle gerade :cry:

Projekt pROBOTERDOKUTOOL hat Exception-Klasse >>EOleSysError<< ausgelöst mit der Meldung: F?r diesen Vorgang ist nicht gen?gend Speicher verf?gbar.

Und wie mache ich das, erst alles in einen String zu schreiben?

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von wp_xyz »

Wahrscheinlich musst du den Dateinamen, der ja ein UTF8String ist, wieder in einen WideString für Word umwandeln

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von Komoluna »

Irgendwie hakts immer bei irgendwelchen Zeichenkodierungen oder???
Das scheint mir eines der öftesten Probleme zu sein(abgesehen vom Zugriff auf NIL-Pointer).

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

pascalts
Beiträge: 61
Registriert: Fr 10. Okt 2014, 13:16

Re: Inhalt einer TXT-Datei in Word-Datei schreiben

Beitrag von pascalts »

Ja, die Zeichenkodierung war es mal wieder:

Code: Alles auswählen

 vorlagepfad := UTF8ToUTF16(SelectDirectoryDialogVorlage.FileName + '\vorlage.docm'); //Pfad der Vorlgae erstellen (UTF8 zu WideString)
varDokument := varWdApp.Documents.Open(vorlagepfad); //öffnet Vorlage, geht!

geht 1a.

So Jungs / Mädels, wir nähern uns dem Ziel :mrgreen: ! Ich brauche nur noch bei folgendem Hilfe: Der zweite Teil der Variable "vorlagepfad" soll dem Text (also der Auswahl) einer TComboBox entsprechen... was muss ich da nehmen? Die TComboBox heißt "cbVorlageAuswahl" - sicher nimmt man da nicht cbVorlageAuswahl.Text oder?

Antworten