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

Good day bros. I need to create a script to take multiple word documents and combine them into one. I've done a little Word automation for accessing text but never for writing it. I have looked at nodes here like this one about writing stuff to Word, but what I want to do it take the text unmodified with formatting etc. from a source file and add it to the end of a destination file using code like:
#!/usr/bin/perl -w use strict; use Win32::OLE; use Win32::OLE::Const 'Microsoft Word'; my $word = Win32::OLE->new('Word.Application') or die "Failure - word. + \n"; my $outputdoc = $word->Documents->Add; my @inputdocs = qw( foo.doc bar.doc); foreach my $f (@inputdocs) { my $inputdoc = $word->Documents->Open({FileName => "c:\\$f"}); my $inputparagraphs = $inputdoc->Paragraphs; foreach my $par (@$inputparagraphs) { #how to add to end of $outputdoc? } $inputdoc->close; } $outputdoc->SaveAs({FileName => 'c:\\combined.doc'});

So I guess my question is, is there a way to take a paragraph from the source doc and push it (with original formatting) onto the end of the paragraphs of the destination doc? The VBA reference for Word shows that there is a Paragraphs.Add method, but it seems that just adds a paragraph without putting anything in it. Any pointers appreciated.

Replies are listed 'Best First'.
Re: Win32 OLE Word combining docs
by pryrt (Abbot) on Aug 23, 2016 at 22:14 UTC
    MSDN Word Range.Copy gives an example of copying a paragraph, and pasting it in the same document.

    ActiveDocument.Paragraphs(1).Range.Copy Set myRange = ActiveDocument.Range _ (Start:=ActiveDocument.Content.End - 1, _ End:=ActiveDocument.Content.End - 1) myRange.Paste

    I think the same should work to copy from one document to another in VBA, just change make the copy-range be from $inputdoc and the paste-range be in $outputdoc (and perl-ify the VBA, of course)

      ++Thank you that did it. The working code is below, with a couple of mods to put a page break between files and put the file name in a heading at the start.

      If I may be permitted a small rant: What kind of twisted mind came up with this Office object model? It is the Rube Goldberg Device of object models. Six steps to insert a heading. REALLY? It took me forever to figure out that you make a selection in the document, but then the selection belongs to to system, not that document. Geez.

      #!/usr/bin/perl -w use strict; use Win32::OLE; use Win32::OLE::Const 'Microsoft Word'; my $word = Win32::OLE->new('Word.Application') or die "Failure - word. + \n"; $word->{'Visible'} = 1; my $outputdoc = $word->Documents->Add; my @inputdocs = qw( foo.doc bar.doc); foreach my $f (@inputdocs) { my $ip = $outputdoc->Range({Start=>$outputdoc->Content->End -1,End +=>$outputdoc->Content->End -1}); $ip->Select(); my $selection = $word->Selection; $selection->TypeText($f); $selection->{'Style'} = "Heading 2"; $selection->TypeParagraph; my $inputdoc = $word->Documents->Open({FileName => "c:\\temp\\work +\\$f"}); my $inputparagraphs = $inputdoc->Paragraphs; my $nparagraphs = $inputdoc->Paragraphs->Count; for my $i (1..$nparagraphs) { $inputdoc->Paragraphs($i)->Range->Copy; my $outrange = $outputdoc->Range({Start=>$outputdoc->Content-> +End -1,End=>$outputdoc->Content->End -1}); $outrange->Paste; } $inputdoc->close; my $outputend = $outputdoc->Range({Start=>$outputdoc->Content->End + -1,End=>$outputdoc->Content->End -1}); $outputend->InsertBreak(); } $outputdoc->SaveAs({FileName => 'c:\\temp\\work\\combined.doc'});