Word-Automation mit C++ Builder - Textmarken



  • Hallo,

    ich bin was C++ betrifft, eher noch ein Anfänger, aber trotzdem will ich ein Programm schreiben, mit dem ich in einer Word-Vorlage vorhandene Textmarken ersetzen kann und das Dokument anschließend an den Drucker schicke.

    Das Dokument habe ich bereits geöffnet. Nur fehlt mir momentan noch der Befehl, mit dem ich auf die Textmarken zugreifen kann und diese ersetzen kann. Drucken ist kein Problem.

    OleVariant Filename;
        if (OpenDialog1->Execute())
            Filename = OpenDialog1->FileName;
        else
            exit(1);
    
        WordApplication1->Connect();      //Verbindung zu Word
        WordApplication1->Documents->OpenOld(Filename, EmptyParam, EmptyParam,      
                     EmptyParam, EmptyParam, EmptyParam,
                     EmptyParam, EmptyParam, EmptyParam,
                     EmptyParam);
    
        WordDocument1->ConnectTo(WordApplication1->ActiveDocument);
        WordApplication1->Visible = false;
    
        // Hier müsste der Teil mit den Textmarken rein
    
        WordDocument1->PrintOut();
    

    Ich hoffe, ich habe das Problem richtig beschrieben und dass mir jemand von euch helfen kann.

    Gruß
    Player1007



  • Hallo

    Dazu must du die gleichen Aufrufe ausführen wie in Word-VBA. Hier ein Beispiel aus einem altem Projekt von mir.

    AnsiString Find = "..";
    AnsiString Replace = "..";
    WordApp->Selection->Find->Execute(
      OleVariant(StringToOleStr(Find)), // FindText : Der zu suchende Text
      OleVariant(true), // MatchCase : ob Groß/Kleinschreibung beachtet werden soll
      OleVariant(false), // MatchWholeWord : ob nur nach ganzen Worten gesucht werden soll
      OleVariant(false), // MatchWildcards : ob ein Suchoperator verwendet werden soll
      OleVariant(false), // MatchSoundsLike : ob nach ähnlich lautenden Worten gesucht werden soll
      OleVariant(false), // MatchAllWordForms : ob alle Formen des Suchtextes gesucht werden soll
      OleVariant(true), // Forward : ob vorwärts gesucht werden soll
      OleVariant(wdFindContinue), // Wrap : Verhalten bei Erreichen des Suchbereichs-Endes
        // wdFindAsk : Abfrage, ob Suche im restlichen Dokument fortgesetzt werden soll
        // wdFindContinue : automatisch Suche fortsetzen
        // wdFindStop : Suche beenden
      OleVariant(false), // Format : ob nach einer Formatierung gesucht werden soll
      OleVariant(StringToOleStr(Replace)), // ReplaceWith : der einzusetzende Text
      OleVariant(wdReplaceOne), // Replace : gibt die Anzahl der Ersetzungen an
            // wdReplaceAll : alle Fundstellen ersetzen
            // wdReplaceNone : keine ersetzen
            // wdReplaceOne : die erste Fundstelle ersetzen
      OleVariant(false), // MatchKashida : ob in einem arabischen Text nach übereinstimmenden Kashidas gesucht werden soll
      OleVariant(false), // MatchDiacritics : ob in einen Text mit Schreibrichtung rechts nach links nach diakritische Zeichen gesucht werden soll
      OleVariant(false), // MatchAlefHamza : ob in einem arabischen Text nach übereinstimmenden Alef Hamzas gesucht werden soll
      OleVariant(false)); // MatchControl : ob in einen Text mit Schreibrichtung rechts nach links und mit übereinstimmenden bidirektionalen Steuerzeichen gesucht werden soll
    

    Das führt ein automatisches Suchen-und-Ersetzten durch.

    Wenn du das Ersetzen manuell machen willst übergibst du Replace nur einen leeren String, führst natürlich die Suche nur bis zur nächsten Stelle aus und packst den Execute-Aufruf in eine while-Schleife.
    Die Abbruchbedingung kannst du nun nach jedem Execute so bestimmen :

    bool Search = WordApp->Selection->Find->Found;
    

    Dann hast du bei jeder erfolgreichen Suche das Ergebnis vorselektiert. Du kannst nun die entsprechenden VBA-Möglichkeiten die Textauswahl manuell modifizieren. Willst du nun die Auswahl durch etwas eigenes ersetzten must du nur noch

    WordApp->Selection->TypeText(StringToOleStr(Replace));
    

    aufrufen.

    /Edit : Das gilt für die Word2000-Schnittstelle des BCB5. Wenn du in moderneren Builder-Versionen eine veränderte Schnittstelle für modernere Words brauchst must du vielleicht anpassen. Dazu must du in die entsprechende Hilfe zu Word-VBA schauen.

    bis bald
    akari



  • Super, es funktioniert 🙂

    Nur speichert er das Dokument mit dem ersetzten Platzhalter ab.
    Kann man das irgendwie unterdrücken, damit ich bei den nächsten Aufrufen
    immer das selbe Dokument vorliegen habe?

    Gruß
    Player1007



  • Hallo

    Du must natürlich das Word-Dokument unter einem anderem Namen speichern als die Ausgangsvorlage bzw. das geänderte Dokument gar nicht erst abspeichern wenn du Word beendest.

    bis bald
    akari



  • akari schrieb:

    Du must natürlich das Word-Dokument unter einem anderem Namen speichern als die Ausgangsvorlage bzw. das geänderte Dokument gar nicht erst abspeichern wenn du Word beendest.

    Und das funzt wie?

    Bei mir siehts jetzt so aus:

    WordDocument1->ConnectTo(WordApplication1->ActiveDocument);
        WordApplication1->Visible = false;
    
    AnsiString Find = "Platzhalter2";
    AnsiString Replace = "Huhu, es funzt";
    WordApplication1->Selection->Find->Execute(
      OleVariant(StringToOleStr(Find)), // FindText : Der zu suchende Text
      OleVariant(true), // MatchCase : ob Groß/Kleinschreibung beachtet werden soll
      OleVariant(false), // MatchWholeWord : ob nur nach ganzen Worten gesucht werden soll
      OleVariant(false), // MatchWildcards : ob ein Suchoperator verwendet werden soll
      OleVariant(false), // MatchSoundsLike : ob nach ähnlich lautenden Worten gesucht werden soll
      OleVariant(false), // MatchAllWordForms : ob alle Formen des Suchtextes gesucht werden soll
      OleVariant(true), // Forward : ob vorwärts gesucht werden soll
      OleVariant(wdFindContinue), // Wrap : Verhalten bei Erreichen des Suchbereichs-Endes
        // wdFindAsk : Abfrage, ob Suche im restlichen Dokument fortgesetzt werden soll
        // wdFindContinue : automatisch Suche fortsetzen
        // wdFindStop : Suche beenden
      OleVariant(false), // Format : ob nach einer Formatierung gesucht werden soll
      OleVariant(StringToOleStr(Replace)), // ReplaceWith : der einzusetzende Text
      OleVariant(wdReplaceOne), // Replace : gibt die Anzahl der Ersetzungen an
            // wdReplaceAll : alle Fundstellen ersetzen
            // wdReplaceNone : keine ersetzen
            // wdReplaceOne : die erste Fundstelle ersetzen
      OleVariant(false), // MatchKashida : ob in einem arabischen Text nach übereinstimmenden Kashidas gesucht werden soll
      OleVariant(false), // MatchDiacritics : ob in einen Text mit Schreibrichtung rechts nach links nach diakritische Zeichen gesucht werden soll
      OleVariant(false), // MatchAlefHamza : ob in einem arabischen Text nach übereinstimmenden Alef Hamzas gesucht werden soll
      OleVariant(false)); // MatchControl : ob in einen Text mit Schreibrichtung rechts nach links und mit übereinstimmenden bidirektionalen Steuerzeichen gesucht werden soll
    
        WordDocument1->PrintOut();
        WordDocument1->Close();
        WordDocument1->Disconnect();
    
        WordApplication1->Quit();
        WordApplication1->Disconnect();
    


  • Hallo

    AnsiString NewFile = "...";
    WordDoc->SaveAs(OleVariant(StringToOleStr(NewName)),   
      OleVariant(wdFormatDocument));
    // oder/und
    WordApp->Quit(OleVariant(wdDoNotSaveChanges));
    // zu letzteren must du aber die beiden vorhergehenden Zeilen Close und Disconnect weglassen, die sind eh unnötig.
    

    bis bald
    akari



  • Sehr schön, jetzt funzt alles wie gewollt...

    Aber ich glaub, ich hab diese Suchen/Ersetzen-Methode en bissl kompliziert eingebunden^^

    Ein riesengroßes Dankeschön 🙂


Anmelden zum Antworten