locked
Word-Automation durch VFP RRS feed

  • Frage

  • Liebe VFPler

    Ich muss Daten aus einer FoxPro-Tabelle in ein Word-Dokument übertragen. Das Worddokument hat aber relativ viel statischen Text. Es ist sozusagen ein Formular in das FoxPro-Feldinhalte eingefügt werden sollen. Meine Idee war nun das Worddokument als Word-Template zu erstellen und die einzelnen VFP-Felder dort als Platzhalter anzugeben. In einem VFP-Programm wird das Template geöffnet und die Platzhalter werden mit Hilfe von Wordautomation gesucht und durch deren Inhalt ersetzt.

    Ein kurzes Beispiel, wie das in Etwa aussieht:

    Name des Teilnehmers <teilnname>    Kunden-Nr. <kdnr>   Rechnungs-Nr. <renr>

    In Programm sollen nun alle Wörter, die mit < anfangen und mit > enden gesucht und durch den Inhalt der gleichnamigen Felder in der dazugehörigen Tabelle ersetzt werden.

    Das klappt auch gut, solange keine Word-Textboxen vorkommen. Da ich aber z. T. sehr lange Feldinhalte habe, die innerhalb eines begrenzten Bereichs auf das Word-Dokument ausgegeben werden müssen, sehe ich fast keine andere Möglilchkeit als Textboxen zu verwenden.

    Ich habe versucht, mich ein wenig schlauer über Wordautomation zu machen und bin auf den Begriff StoryRanges gestossen. Wenn ich das richtig verstanden habe, wird ein Worddokument jeweils in sogenannte Dokumentbereiche, StoryRanges, eingeteilt. Benutzt man die Storyranges werden beim Suchen/Ersetzen auch die Textboxen berücksichtigt. Ich habe mein Programm umgebaut und das klappt auch, ABER... nach zwei Feldern ist jeweils Schluss. Mein Wordtemplate hat aber ungefähr 20 Felder.

    Ich habe dann weiter nachgeforscht und herausgefunden, dass ein Worddokument auch noch aus Sections (wird wohl deutsch Abschnitte heissen) besteht, die den Storyranges übergeordnet sind (vermute ich mal). Ich dachte, dann müsse ich halt eine weitere Schleife einbauen, die alle Sections durchsucht, aber das Resultat blieb das gleiche, 2 Felder wurden ersetzt, dann war Schluss. Das heisst nach dem ersten Durchgang der FOR-Schleife für loRange (siehe Code-Beispiel unten) gibt es keinen weiteren Druchgang mehr durch die FOR-Schleife Sections. Es wird also nur eine Section durchlaufen.

    Hier ein Auszug aus dem Code. Ich habe den Teil, wo das Worddokument erstellt wird und die SearchReplace-Routine  weggelassen, weil ich glaube, dass dort nicht das Problem liegt. Ich hoffe, ich konnte mein Problem einigermassen verständlich darstellen. Danke jedenfalls im Voraus für jeden Tipp.

    PROCEDURE SearchReplaceInDoc(tcDoc) ************************* #DEFINE wdEvenPagesHeaderStory 6 #DEFINE wdPrimaryHeaderStory 7 #DEFINE wdEvenPagesFooterStory 8 #DEFINE wdPrimaryFooterStory 9 #DEFINE wdFirstPageHeaderStory 10 #DEFINE wdFirstPageFooterStory 11 LOCAL loRange, loSection FOR EACH loSection IN tcDoc.Sections FOR EACH loRange IN tcDoc.StoryRanges

    *-- Ursprungscode stammt aus dem Internet. Dort werden weiter unten explizit allfaellige
    *-- Header- und Footer-Bereiche durchsucht. Mein Worddokument hat aber keine Kopf- und Fusszeile
    *-- abgefüllt. Der folgende Selektion klammert die Header- und Footerbereich vom Search/Replace
    *-- aus.

    IF !INLIST(loRange.StoryType, wdEvenPagesHeaderStory, wdPrimaryHeaderStory, ; wdEvenPagesFooterStory, wdPrimaryFooterStory, wdFirstPageHeaderStory, ; wdFirstPageFooterStory) SearchReplaceInRange(loRange) DO WHILE !ISNULL(loRange.NextStoryRange) loRange = loRange.NextStoryRange SearchReplaceInRange(loRange) ENDDO ENDIF NEXT loRange NEXT loSection


            



    Montag, 12. Mai 2014 19:40

Alle Antworten

  • Hallo Alex,
    mein aktive Foxpro Zeit ist zwar schon eine Weile her, doch folgender Ansatz:
    Versuche doch einen Serienbrief daraus zu machen. Du hast ja Feldinhalte die ersetzt werden sollen.
    Hier ein Link zum erstellen eines Serienbriefes via Ole-Automation aus Foxpro heraus:
    http://support.microsoft.com/kb/508978/de
    HTH
    Grüße Alexander
    Dienstag, 13. Mai 2014 05:55
  • Hallo Alexander

    Ein interessanter Ansatz. Danke dafür.

    Grüsse
    Alex
    Mittwoch, 14. Mai 2014 14:02
  • Moin, moin

    wir machen das mit Bookmarks, etwa :

    For nBookmarks = 1 To ow.ActiveDocument.Bookmarks.Count
      obook = ow.ActiveDocument.Bookmarks(nBookmarks)
      Do Case
        Case Upper(obook.Name) == "NAME"
          obook.Range.Text = cName+CHR(13)+CHR(10)+cAnschrift1+CHR(13)+CHR(10)+;
          CHR(13)+CHR(10)+chr(13)+CHR(10) + cOrt
    *  oder obook.range.insertafter
    ...

    Grüße aus HH

    Tom

    Mittwoch, 14. Mai 2014 14:12
  • FOR EACH loSection IN tcDoc.Sections
      FOR EACH loRange IN tcDoc.StoryRanges

    Ich würde sagen klassischer Fall von zu wenig eingelegten Pausen.

    Die innere FOR läuft ja nun unabhängig von der äußeren über das tcDoc Object. Vorausgesetzt StoryRanges sind in Sections verschachtelt und auf tcDoc Ebene ist zwar auch eine StoryRanges Collection, aber nur die der ersten Section, dann müßte die innere Schleife über loSection.StoryRanges laufen, nicht übner tcDoc.StoryRanges...

    FOR EACH loSection IN tcDoc.Sections
      FOR EACH loRange IN loSection.StoryRanges

    Ich hab's jetzt nicht ausprobiert, aber so oder ähnlich muß die Schleifenabhängigkeit hergestellt sein, sonst gehst Du immer wieder die gleichen StoryRanges unabhängig von der aktuellen Section in loSection durch.

    By the way, in .NET gibt es gute Third Party Module, z.B. von Gembox. Word/Excel Automation ohne Word/Excel Installation, wesentlich schneller, nicht auf die OpenXML Formate beschränkt.

    Tschüß, Olaf.


    Olaf Doschke - TMN Systemberatung GmbH

    http://www.tmn-systemberatung.de

    Dienstag, 20. Mai 2014 16:46