Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

WIn32::OLE debug

by Anonymous Monk
on Oct 11, 2025 at 12:41 UTC ( [id://11166461]=perlquestion: print w/replies, xml ) Need Help??

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

I have the following code, which WORKS for a word file, but crashes for a similar word file (both docx)
use strict; use Excel::Writer::XLSX; use Spreadsheet::ParseXLSX; use Carp qw( croak ); use Cwd qw( abs_path ); use Path::Class; use Win32::OLE qw(in); use Win32::OLE::Const 'Microsoft Word'; ... my $path=....; my $word =Win32::OLE->new('Word.Application','Quit'); my $word_file = file(abs_path($path)); my $doc = $word->{Documents}->Open("$word_file"); print "after doc\n"; my $tables = $word->ActiveDocument->{Tables}; for my $table (in $tables) { my $numrows=$table->Rows->Count; $main::numcols=$table->Columns->Count; # Iterate through rows and count columns foreach my $rownum (1 .. $table->Rows->Count) { my $row = $table->Rows->Item($rownum);# code crashes here ... } }
The code crashes as indicated with the message

Win32::OLE(0.1712) error 0x8002000e: "Invalid number of parameters" in METHOD/PROPERTYGET "Item" at C:/Strawberry/perl/lib/Devel/ptkdb.pm line 2658.

When I try to debug with ptkdb it crashes as soon as I ask for a listing of $doc or $table How do I go about debugging this??

Replies are listed 'Best First'.
Re: WIn32::OLE debug
by Corion (Patriarch) on Oct 12, 2025 at 08:03 UTC

    It helps a bit to know about VBA / OLE. The ->Item method is what is used to enumerate arrays. The in function is what maps that to Perl.

    In your code, you have:

    my $tables = $word->ActiveDocument->{Tables}; for my $table (in $tables) {

    If the document has no tables, maybe $tables is undef. Check for that.

    If your debugger crashes, do print debugging:

    my $tables = $word->ActiveDocument->{Tables}; print "Tables is <$tables>"; print sprintf "Tables has %d items", $tables->Count; for my $table (in $tables) {
Re: WIn32::OLE debug
by Marshall (Canon) on Oct 12, 2025 at 04:43 UTC
    1. First step turn STDOUT buffering off
    $|=1; #put at top of code
    This allows error messages and normal prints to appear in the order of execution.

    2. You have one doc that works and one that doesn't.
    Add error checking on the opens and new operations.
    my $word =Win32::OLE->new('Word.Application','Quit') or die "blah$!";
    my $doc = $word->{Documents}->Open("$word_file") or die "bla2$!";

    3. Add some prints for each variable - look for something weird like undef value

    Update:
    From your description, it looks like tabler 1 in the failing doc is what is failing.
    Try cut and paste the table that works from doc 1 to doc 2.
    Again make sure the open worked. you could conceiveably get your error if the Word doc didn't open.

    Do both docs render ok on the screen? Can you print them without problems?

    It is possible with the drawing tools to make something that looks like a table, but is not a table in the Word sense.

      Thanks, I did try your advice. The result:

      Tables is <Win32::OLE=HASH(0x57d0ab0)>Tables has 70 itemsbefore table loop

      table=Win32::OLE=HASH(0x57d0c60) file=C:\Users\...\mydoc.docx

      numrows=23

      table rows count= Win32::OLE=HASH(0x5606e48)->Rows->Count

      OLE exception from "Microsoft Word":

      ?e? e??a? d??at? ? p??s▀as? ╡e╡???╡???? ??a╡╡?? se a?t?? t? s??????, epe?d? ? p??a?a? ??e? s?????e?╡??a ?e??? ?ata????fa.

      Win32::OLE(0.1712) error 0x800a1767 in METHOD/PROPERTYGET "Item" at parserworks16.pl line 188.

      The failing line is the last line shown
      print "table rows count= $table->Rows->Count \n"; # this print seems t +o indicate the problem foreach my $rownum (1 .. $table->Rows->Count) { my $row = $table->Rows->Item($rownum);
      So it looks like $table->Rows->Count is an object instead of a number! Why is that ?
        Method calls are not interpolated in double quoted strings. Therefore,
        print "table rows count= $table->Rows->Count \n";

        only interpolates $table. Instead, try

        print 'table rows count = ', $table->Rows->Count, ".\n";

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11166461]
Approved by marto
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2026-01-19 21:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What's your view on AI coding assistants?





    Results (124 votes). Check out past polls.

    Notices?
    hippoepoptai's answer Re: how do I set a cookie and redirect was blessed by hippo!
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.