: (e-mail address removed) (Greg Bacon) wrote:
:
: : I was trying to put together a quick hack to extract review comments
: : (using the Comments property) from a Word document to jump start
: : compiling review minutes, but I found the MSDN Word object model
: : documentation surprisingly opaque. For example, the docs didn't say
: : which property held the comment tag (e.g., [b1]),
:
: What is your example "[b1]" meant to show? Is that the expected content
: of the document's comments property?
No, not the comment itself, the comment *tag*. I'm talking about the
tags identify each comment and show up in the document as hidden text.
The leader seems to be the author's initials because in a dummy doc I
just created, Word tagged my comments as [geb1] and so on.
The comment text itself is straightforward:
print "$_->{Range}{Text}\n" for in $Doc->{Comments};
: : and the empirical
: : measure of iterating over the keys didn't bear fruit.
:
: A splash of code will better show what you are talking about, and will
: probably show where the difficulty lies.
Here's the code I've been using to explore:
#! perl
use strict;
use Win32::OLE qw/ in /;
sub usage { "Usage: $0 [--active | --open]\n" }
## main
die usage unless @ARGV;
Win32::OLE->Option(Warn => 2);
my $Word;
my $Doc;
my $arg = shift;
if ($arg eq '--active') {
$Doc = Win32::OLE->GetActiveObject('Word.Application', 'Quit');
}
elsif ($arg eq '--open') {
$Word = Win32::OLE->new('Word.Application', 'Quit');
# requires absolute path?
$Doc = $Word->Documents->Open('c:\temp\foo.doc');
}
#$Doc->{Visible} = 1;
foreach my $Property (in $Doc->BuiltinDocumentProperties) {
my $Name = $Property->Name;
local $Win32::OLE::Warn = 0;
my $Value = $Property->Value;
$Value = '***Error***' if Win32::OLE->LastError;
$Value = '<undef>' unless defined $Value;
printf "%s %s = %s\n", $Name, '.' x (40-length($Name)), $Value;
}
foreach my $c (in $Doc->{Comments}) {
print $c->{Reference}{BookmarkID}, " - ", $c->{Range}{Text}, "\n";
}
#$Doc->{Saved} = 1;
In the loop over BuiltinDocumentProperties, I'd tried iterating
over keys %$Property and printing out the values, but the comment
tag didn't appear.
: : I played with the code in <
[email protected]> and found
: : that it made a difference whether I called Documents->Open or
: : GetActiveObject -- although the two seem equivalent in the docs.
:
: Which docs were you reading that suggested that the
: Win32::OLE->GetActiveObject method is similar to the Word application's
: Documents->Open method?
:
: Are you perhaps thinking of the Win32::OLE->GetObject method when you
: say GetActiveObject?
I see that I was unclear. I should have written "equivalent, assuming
the document we want is open". Using the code above with the --active
option, I get the following error:
Win32::OLE(0.1603) error 0x80020011: "Does not support a collection"
in METHOD/PROPERTYGET "" at props line 29
Can't call method "Name" on an undefined value at props line 30.
I obviously read more into the docs than was there, and I'm happy to
take correction. Where can I find a good orientation to thinking OLE?
: : Can people recommend a good resource?
:
: A resource on using Win32::OLE? The pods that come with ActivePerl are
: pretty much it, and pretty much all that is needed. Win32::OLE is not
: much more than a way for Perl to poke and prod at OLE libaries.
:
: A resource on how any of those libraries responds to being poked and
: prodded? That's a job for the library's author.
:
: The OLE Browser included with ActivePerl is a decent tool for navigating
: the various libraries and the classes within those libraries. Be sure
: to notice the clickable help icon in the bottom frame.
Didn't notice the help icon before. Thanks for the pointer. I'm
closer:
foreach my $c (in $Doc->{Comments}) {
my $tag = $c->{Initial} . $c->{Index};
print "$tag - ", $c->{Range}{Text}, "\n";
}
Now I'm trying to get at the highlighted portion of the document
associated with a given comment. Strike that:
foreach my $c (in $Doc->{Comments}) {
my $tag = $c->{Initial} . $c->{Index};
print $tag, " - ", $c->{Range}{Text}, "\n";
print $c->{Scope}{Text}, "\n";
}
: [...]
: As for your original quick hack program, see if this does not fill the
: need.
:
: #!perl
: use warnings;
: use strict;
: use Win32::OLE;
: use Win32::OLE::Const 'Microsoft Word';
: print
: Win32::OLE
: ->GetObject('foo.doc')
: ->BuiltinDocumentProperties(wdPropertyComments)
: ->Value;
That produced no output. (Yes, I used the appropriate path.)
A couple of remaining questions:
Why does iterating over the BuiltinDocumentProperties make the
application think I have changes that need saving? (I see that setting
the Saved property says nothing needs saving.)
What the difference between getting at the document via Documents->Open
versus GetActiveObject? I'd like to avoid typing long paths.
Greg, drifting off-topic :-(