Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

MS-Word OLE and Joining Tables

by BrianP6 (Initiate)
on Dec 30, 2012 at 17:50 UTC ( #1010946=perlquestion: print w/replies, xml ) Need Help??
BrianP6 has asked for the wisdom of the Perl Monks concerning the following question:

Hello All

I am automating the "magazine run" process for a Classic Car club, this involves creating renewal letters in which I include in the letter all the cars that each member owns. I do this via a "catalog" mail merge in word which I control through a Perl script. Adding the cars into a table in this method creates a small one-line table for each car added in the mail merge. When finished, I need to run a "TableJoiner" macro so that all of these individual tables are joined up into one. I found this macro on the internet from a very helpful tutorial on the "catalog" mail merge, it works superbly and it looks like this:

Sub TableJoiner() Application.ScreenUpdating = False Dim oPara As Paragraph For Each oPara In ActiveDocument.Paragraphs With oPara.Range If .Information(wdWithInTable) = True Then With .Next If .Information(wdWithInTable) = False Then If .Text = vbCr Then .Delete End If End With End If End With Next Application.ScreenUpdating = True End Sub

I want to turn this into Perl OLE script so that I can run it on any PC without installing the macro into MS-Word first. Can anyone help me with this please? I have got as far as this:

foreach my $oPara (%{$Word->ActiveDocument->Paragraphs}) { if ($oPara->Range->Information(wdWithInTable)) { if ($oPara->Next->Information(wdWithInTable) eq False) { if ($oPara->Next->Text eq "\r") #vbCr { logoutput("Deleting Line\n"); $oPara->Range->Next->Delete; } } } }

I did start the foreach loop with:

foreach my $oPara ($Word->ActiveDocument->Paragraphs)

But I thought I needed to 'persuade' perl that it was a hash. Any help you can give me would be much appreciated.


Replies are listed 'Best First'.
Re: MS-Word OLE and Joining Tables
by roboticus (Chancellor) on Dec 30, 2012 at 18:14 UTC


    OK, you've converted the code as shown. What happens when you run it? (I can't run it because I don't have the necessary infrastructure here.) The error message and/or other symptoms might have the clue needed to help solve your problem.


    When your only tool is a hammer, all problems look like your thumb.

      Hi Roboticus, You are absolutely right, my apologies. When I run my code I get the error:

      Can't locate object method "Range" via package "Count"

      So, I printed out the contents of $oPara and I got the word "Count" out of it .... so I guess it's not a hash.

      If I remove the hashing and turn it back to "foreach my $oPara ($Word->ActiveDocument->Paragraphs)", then the error message I get is:

      Can't call method "information" on an undefined value"

      Thanks for taking the time to look

Re: MS-Word OLE and Joining Tables
by NetWallah (Canon) on Dec 30, 2012 at 18:41 UTC
    Here is my (untested) take on what the perl equivalent is:
    use Win32::OLE qw(in valof with OVERLOAD); Win32::OLE->Option(_NewEnum => 1); for my $oPara (in $Word->ActiveDocument->Paragraphs) { my $oRange = $oPara->Range; next unless $oRange->Information(wdWithInTable) ; $oRange = $oRange->Next; next if $oRange->Information(wdWithInTable) ; $oRange->Delete() if $oRange->Text eq vbCr; }
    Update 1: Showing the "in <object>" syntax - this is what you seem to be struggling with.

                 "By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."           -Confucius

      Hi NetWallah

      Thanks for that, I pasted it into my file, ran it and got.....

      Not an ARRAY reference at the 'foreach' line

      Thanks for taking the time to help me

      Hi NetWallah,

      Fantastic, that does the job!! Now I'm about to start googling the use of 'in' that you've used here to find out how it works.

      One thing that I really didn't expect, is just how much it has slowed my script down. I did think it would to some extent, but it's actually gone from a total run time of 8 minutes to 36 minutes (yes I've got quite a few tables being joined). No, my PC is a fully up to date desktop running a quad core i5 - I only built it earlier this year, so it is the OLE that is slow. By comparison, the old script took 1 hour to run on my little netbook, I guess I wont be using it on this new script!

      I will be investigating better ways to issue some of the reports - maybe write them to excel and then output as PDF instead of word tables, that will improve things dramatically. But my renewal letters need to stay in Word and use this new script.

      Many thanks again oh wise one!

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1010946]
Approved by marto
[Discipulus]: damn I missed a possible employer for seconds..

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2018-04-20 19:00 GMT
Find Nodes?
    Voting Booth?