http://www.perlmonks.org?node_id=235101

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

Here is the Error I get:
Can't call method "Content" on an undefined value at c:\scripts\sr.pl +line 19.
Here is the Code:
#!/perl/bin use strict; use Win32::OLE; use Win32::OLE::Const 'Microsoft Word'; my $oldfile = 'c:\tmp\test.doc'; my $newfile = 'c:\tmp\test1.doc'; my $oldtext = 'change me'; my $newtext = 'I am changed'; my $word = Win32::OLE->GetActiveObject('Word.Application') || Win32::OLE->new('Word.Application','Quit'); my $doc = $word->Documents->Open("$oldfile"); # is application visible 0=no 1=yes $word->{visible} = 0; my $search = $doc->Content->Find; my $replace = $search->Replacement; $search->{Text} = $oldtext; $replace->{Text} = $newtext; $search->Execute({Replace => wdReplaceAll}); # save word file $word->ActiveDocument->SaveAs($newfile); # close word file $doc->Close(); $word->Quit();
P.S. I have the same program written for Excel that works fine both locally and part of a CGI

Replies are listed 'Best First'.
Re: Win32::OLE Word Search and Replace Script Runs Locally but not as part of CGI
by bart (Canon) on Feb 13, 2003 at 20:57 UTC
    Here is the Error I get:

    Can't call method "Content" on an undefined value at c:\scripts\sr.pl line 19.

    Let's see where it could come from:
    my $doc = $word->Documents->Open("$oldfile"); my $search = $doc->Content->Find;
    Apparently, $doc is not defined. The Open must have failed. You don't check.
Re: Win32::OLE Word Search and Replace Script Runs Locally but not as part of CGI
by Nitrox (Chaplain) on Feb 13, 2003 at 20:56 UTC
    Add some error reporting after interacting with the OLE object. It appears that $doc isn't being defined which would lead me to suspect that the OLE call is failing.

    Update
    To be more explicit, change line 19 to:

    my $doc = $word->Documents->Open("$oldfile") or die("Couldn't open $ol +dfile");

    -Nitrox

Re: Win32::OLE Word Search and Replace Script Runs Locally but not as part of CGI
by tachyon (Chancellor) on Feb 14, 2003 at 13:38 UTC

    The problem is that $doc is not defined, ergo and therfore your file open has failed as this is where it gets defined. If you check LastError it will tell you why it is failing (permissions or path) but you don't. If you do check you will no doubt be able to answer your own question. Do:

    my $doc = $word->Documents->Open($oldfile) or die_nice( "Failed to ope +n $oldfie " . $word->LastError() ); ... sub die_nice { print "Content-type: text/html\n\n" . shift }

    I don't see why you want to quote "$oldfile" so I have not. I doubt that this is the problem but your are interfacing with Win32 with a virus like language (to quote M$)

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Perl is a virus-like language? Can you provide a link to back up that quote? I don't doubt for a minute that some MS PR weasel said it. I used to work for the Borg, and that's the attitude over there: if we can't control it, we have to destroy it. Still, I'd like to see a link to back up your statement.

      -Logan
      "What do I want? I'm an American. I want more."

Re: Win32::OLE Word Search and Replace Script Runs Locally but not as part of CGI
by helgi (Hermit) on Feb 14, 2003 at 11:49 UTC
    This is a FAQ. Frequently Asked Questions are answered in the Perl documentation which comes bundled with every Perl distribution. It can be browsed and searched using the perldoc program. Have a look at

    perldoc -q 500 also known as

    My CGI script runs from the command line but not the browser.  (500 Server Error)

    My stab in the dark guess is that httpd, iusr, nobody or whatever does not have permission to read your Word document.

    --
    Regards,
    Helgi Briem
    helgi AT decode DOT is

Re: Win32::OLE Word Search and Replace Script Runs Locally but not as part of CGI
by webfiend (Vicar) on Feb 14, 2003 at 17:42 UTC

    I felt compelled to downvote this one, which is very very rare for me. Since it's so unusual, I also felt compelled to explain myself. There is no mention in the post or the code about error checking. It simply assumes that the attempt to open the Word file is successful. What happens when it doesn't? You get an error about undefined values.

    How do you make sure that you don't get these mysterious errors?

    my $doc = $word->Documents->Open($oldfile) || die("Unable to open '$oldfile': $!\n");

    That's all. Just tell the program to choke and report an error if it can't get the file for some reason.

    In retrospect, downvoting may have been an overreaction on my part. Still, this is one of my pet peeves, since it's generally one of the first errors we meet, and often the most common. I've become intimately familiar with that one :-)


    I just realized that I was using the same sig for nearly three years.

Re: Win32::OLE Word Search and Replace Script Runs Locally but not as part of CGI
by grantm (Parson) on Feb 16, 2003 at 02:20 UTC

    I also suspect your problem relates to permissions (the web server runs under a different user ID than you use at the command line). You might want to check out the recent thread on OLE from CGI. In particular the link to the MS knowledgebase article which says "don't do it".

Re: Win32::OLE Word Search and Replace Script Runs Locally but not as part of CGI
by helgi (Hermit) on Feb 14, 2003 at 15:32 UTC
    I belatedly realised why your program is not working:

    my $oldfile = 'c:\tmp\test.doc'; my $newfile = 'c:\tmp\test1.doc';
    Do your filenames REALLY have tab-stops in them?

    Using proper slashes will almost certainly solve your problem.

    my $oldfile = 'c/tmp/test.doc'; my $newfile = 'c:/tmp/test1.doc';

    --
    Regards,
    Helgi Briem
    helgi AT decode DOT is

      No, that's not right. In single quotes, the backslash escapes do not apply (backslash only escapes the ' character). Had he been using double quotes, tabs would have been interpolated for the \t sequence.

      Try it:

      > perl -de 1 Default die handler restored. Loading DB routines from perl5db.pl version 1.07 Editor support available. Enter h or `h h' for help, or `perldoc perldebug' for more help. main::(-e:1): 1 DB<1> $x = 'c:\tab' DB<2> p $x c:\tab DB<3> $x = "c:\tab" DB<4> p $x c: ab DB<5> q

      The most likely cause of the problem, as others have pointed out above, is that the script doesn't have permission to read the file it's trying to open, but the error is not being trapped.

      I agree with you that the way these paths are defined, is unclean. In general, for use in perl alone, I'd agree with your conclusion: to use forward slashes. However, this is not just perl: the paths are passed as parameters via OLE to Word. I cannot test my hyphotesis, but I seriously doubt whether Word would accept paths with forward slashes. From what I remember with my experience with OLE and Excel, a program from the same stable as Word, is that it was extremely unhappy about forward slashes in file paths: it only accepted backslashes as a valid directory separator.

      Conclusion: using backslashes in the paths is more than justified here. However, the way they're used in writing down these strings, is still unclean.