merrymonk has asked for the wisdom of the Perl Monks concerning the following question:

This is a continuation of yesterdays Perl, Word and wingding question. However, I have started a new thread since I think a new set of questions arise.
I want to insert wingding symbols in existing documents. So far this has failed mainly because of difficulties with the ‘number’ associated with these in Word.
Therefore I have tried a new approach which uses the InsertSymbol method.
The idea is that I use search to get to the correct place in the document, use InsertSymbol to add the wingding symbol and finally remove the text used in the search.
To get the VBA code, I recorded a macro in Word which inserted a symbol. This gave
Selection.insertsymbol Font:="Wingdings", CharacterNumber:=-4063, Unic +ode :=True
I then added this to Perl code given some time ago by polypompholyx after changing it using the ‘rules’ in the same reply. This gave
use Win32::OLE; use Win32::OLE::Const "Microsoft Word 12.0 Object Library"; use Win32::OLE::Const "Microsoft Office 12.0 Object Library"; my $word = Win32::OLE->new( 'Word.Application', 'Quit' ) or die "Can't create Word OLE: " . Win32::OLE->LastError . "\n"; $word->{'Visible'} = 1; my $doc = $word->Documents->Add or die "Can't create new Word documen +t: " . Win32::OLE->LastError . "\n"; my $selection = $word->Selection; # select current position $selection->{'Style'} = 'Title'; $selection->TypeText( 'Document title' ); $selection->TypeParagraph; $selection->{'Style'} = 'Normal'; $selection->TypeText( 'Lorum ipsum' ); $selection->TypeParagraph; # new line $selection->insertsymbol ( Font=> "Wingdings", CharacterNumber => -406 +3, Unicode => 'True'); $word-> ActiveDocument->SaveAs('c:\tmp\foo.doc'); #$doc->SaveAs( 'foo.docx' ); $word->Quit;
The original set of Perl lines worked and added the text etc. Sadly the InsertSymbol line failed.
Can any wiser Monk than I explain what to do?

Replies are listed 'Best First'.
Re: InsertSymbol usage to modify Word document
by Corion (Patriarch) on Jan 01, 2009 at 09:52 UTC

    You don't tell us how the insertsymbol line failed. By using Google for document.insertsymbol, I found Win32::ole and MSWord, which seems to suggest that the method would be called InsertSymbol, and this seems also to be the usage in this Microsoft reference. To pass named arguments to a method call, the documentation says to use a hash reference. You also pass the string True for the Unicode parameter. That's certainly not wha the translation steps say. You should try passing a 1 or -1 as that parameter. So you should try the following method call, and maybe consider providing us with more exact information on how things fail for you so we can help you better:

    $selection->InsertSymbol( { Font=> "Wingdings", CharacterNumber => -40 +63, Unicode => 1 });
      I am sorry that I did not explain how it failed but simply it did not work and I did not get any error message!
      However, many thanks for your comments because I tried your suggestion and for the first time I got a wingding character in my Word document!!
      Almost of course, this leads to the next problem. How to get the character in the correct place?
      I can ‘see’ VBA word examples of inserting text at a particular position but I am struggling both to understand how to convert this to Perl and more importantly how to adapt this to get the wingding at the right place.
      What I could use is something like
      1. have a unique character string in the Word document;
      2. find that string;
      3. remove the string (perhaps by simply replacing it by ‘nothing’)
      4. add the wingding at that position;
      I have already got code that works for steps 2 and 3. I did hope that this would make the ‘current’ position (or whatever is required) to be where the original string was in the documents (so that the wingding symbol would be inserted at this point).
      Therefore I simply added the now working InsertSymbol line after these steps as shown next.
      $search_res = $search-> {Text} = "\x{0021}"; $replace-> {Text} = "\x{0022}"; $exec_res = $search-> Execute({Replace => wdReplaceAll}); $selection->InsertSymbol( { Font=> "Wingdings", CharacterNumber => -40 +63, Unicode => 1 });
      I used the lines on a Word file that contained an ! (the hex code 0021). This did replace the ! with a “ (hex code 0022). However, the wingding character was placed at the beginning of the document.
      How do I ‘set’ the position for the wingding character to be where the changed character string was in the original 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 ?

        You need to set $selection to be where you want to insert your symbol. However you do that with Word. I suggest reading the Word documentation on how to set the selection to a specific position, or even better, how to set the selection to a string that was searched.