in reply to Re^2: InsertSymbol usage to modify Word document
in thread InsertSymbol usage to modify Word document

I'm not an expert on the Word Object Model, but I did find Word Object Model Reference, which looks worth a read (if only as a cure for insomnia).

I cannot see a property of the Find Object which gives the position of a successful find... I do, however, note that you can set a Font property. You can also set the Font property of the Replacement Object. My guess is that you can use the Unicode "private use" character values used for Wingdings (ie 0xF000 + 0x21 ("\x{F021}") for Wingdings "pencil at 45 degrees") plus the font name for find or replace.

I note also that a Selection Object can have a Find property... which looks plausible ?

  • Comment on Re^3: InsertSymbol usage to modify Word document

Replies are listed 'Best First'.
Re^4: InsertSymbol usage to modify Word document
by merrymonk (Hermit) on Jan 01, 2009 at 17:47 UTC
    Thank you for everyone’s suggestions. I have looked at the various references and also ‘googled' for a solution.
    Frustratingly I found places where the insertion point was mentioned and even questions about how to ‘set’ it
    but no answers using either VBA or Perl code.
    Therefore I used the recording macro facility with Word to locate a character hoping that this would give a clue about what to do. This gave the following
    Selection.Find.ClearFormatting With Selection.Find .Text = "!" .Replacement.Text = "" .Forward = True .Wrap = wdFindContinue .Format = False .MatchCase = False .MatchWholeWord = False .MatchWildcards = False .MatchSoundsLike = False .MatchAllWordForms = False End With Selection.Find.Execute Selection.MoveRight Unit:=wdCharacter, Count:=1 Application.Run MacroName:="Normal.NewMacros.insertsymbol"
    I was not really sure what to do but I did make an attempt and included it in another Perl test.
    I ignored the last line and simply used what I knew should work to add a wingding character. The code is below
    use strict; use Win32::OLE; use Win32::OLE::Const 'Microsoft Word'; # set $filepath to the full path to the direcotry where the file to be + changed, test.doc, is stored my $filepath = 'C:\tmp'; my $oldfile = $filepath . '\wingding1.doc'; my $newfile = $filepath . '\wingding1-edit.doc'; my $word = Win32::OLE-> GetActiveObject('Word.Application') || Win32::OLE-> new('Word.Application','Quit'); my $doc = $word-> Documents->Open("$oldfile"); # is application visible 0=no 1=yes $word-> {visible} = 0; my $selection = $word->Selection; # select current position # start of Word macro conversion $selection->Find->ClearFormatting; $selection->Find ( Text => "!", ReplacementText => "", Forward => 1, Wrap => wdFindContinue, Format => 0, MatchCase => 0, MatchWholeWord => 0, MatchWildcards => 0, MatchSoundsLike => 0, MatchAllWordForms => 0); $selection->Find->Execute; $selection->MoveRight ( Unit => wdCharacter, Count => 1); $selection->InsertSymbol( { Font=> "Wingdings", CharacterNumber => -40 +63, Unicode => 1 }); # save word file $word-> ActiveDocument->SaveAs($newfile); # close word file $doc-> Close(); $word-> Quit();
    I used this with a document with a ! towards the end of the first line. Sadly this still put the inserted
    wingding at the beginning of the document. I even tried with just Text => "!" in the ->Find
    (partly because I was not at all sure that Replacement.Text should be converted as
    ReplacementText) but this also did not work.
    Has any Monk an idea how to make this work?

      While I can't help you with your specific task, I wonder whether your code works at all, as you seem to want to use named parameters but your syntax will pass them as positional parameters instead. (Re)read the Win32::OLE documentation to see how to actually pass named parameters. Or look at the difference between the line that I gave you, which works, and compare that line with the other lines, where I doubt that these work.

      I'd check the return values of the methods you're invoking, and perhaps scatter a few  Win32::OLE->LastError around, to see what it's doing. (Error Handling (COM) may or may not help here.)

      I agree, ReplacementText is probably a mistake. Do you want to remove the "!" ? The MoveRight later on appears to be to step past it ?

      But, as brother Corion says, the main issue is probably that:

      $selection->MoveRight ( Unit => wdCharacter, Count => 1);
      should be written:
      $selection->MoveRight ( { Unit => wdCharacter, Count => 1 } );
      and similarly everywhere you are using "named arguments".

        Many thanks for the latest comments from Brothers Corion and Oshalla. As shown below I now have a solution that:
        1. Moves the insertion point to a set of character(s);
        2. Adds a wingding symbol after the character(s)
        3. Removes the target string
        I looked again at my conversion from a word macro to Perl and made changes.
        Eventually I found something that worked! The following lines, find the target character(s), move the insertion point just after and then add the wingding symbol.
        $selection->Find->ClearFormatting; $selection->Find->{Text} = "*"; $find_exec_res = $selection->Find->Execute; $move_res = $selection->MoveRight ( {Unit => wdCharacter, Count => 1} +); $selection->InsertSymbol( { Font=> "Wingdings", CharacterNumber => -40 +62, Unicode => 1 });
        The search moves forward through the document and therefore will fail if the second target
        character is before the first. However, I found that the following moved the insertion point to the
        start of the document (perhaps not very elegantly but it works).
        $selection->MoveLeft ({Unit => wdCharacter, Count => 9999}); $selection->MoveUp ({Unit => wdLine, Count => 9999});
        I believe that there is an option as part of the ‘Find’ that allows you to set the replacement character(s) but I have not made this work as yet.
        However I can use the code I already have to remove the target character(s) after I have added the wingding symbol.
        I have found that the inserted wingding takes on the target characters characteristic’s such as height and colour.
        If there is more than one character in the target string the move is still one character.
        On my version of Word (2007) I find that the four ‘symbol’ fonts of wingdings, wingdings 2, wigding3 and webdings have the same ‘mapping’ between the number required in InsertSymbol line and their ASCII value.
        The number required is ASCII number – 4096.
        I hope this may help anyone else who is trying to modify a word document with Perl.