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

I'm attempting to iterate through a mailbox in Outlook, and apply a substitution regex to each message. Currently my script runs without error, but no changes are actually made to the messages in the mailbox. Does anyone have any experience with OLE who can give me an idea as to why this isn't working? Pertinent part of the code below:
for my $itemIndex (1..$items->Count) { my $body = $items->Item($itemIndex)->Body; $body =~ s/\s+<\//<\//g; $items->Item($itemIndex)->{'Body'} = $body; $items->Item($itemIndex)->Save; }
Thanks!

Replies are listed 'Best First'.
Re: Outlook MailItem Body Question
by maa (Pilgrim) on Jan 06, 2004 at 19:05 UTC

    Hi,

    Not sure why that's not doing anything... have you tried inserting the lines

    #assume a debug file opened elsewhere print DEBUG "\n\nItem: $itemIndex\n\n$body\n"; #... your code print DEBUG "\n\nAfter modification ($itemIndex)\n$body\n";

    If it's only doing a bit, perhaps local $/; inside the for(){...}.

    I'm also assuming that you created a Recipient object and resolved it against the Exchange server somewhere in your script before you try iterating through a mailbox (unless this is part of a form).

    Don't have Outlook on this PC - will have a look at work tomorrow, tho...

    HTH - Mark

      Right... I've messed about in Perl and VBScrip this morning and my findings are this... I can do what you want in VB but not in Perl. Weird... (Outlook97, btw).

      #!C:/ActivePerl/bin/perl.exe use strict; use warnings; use Win32::OLE; #Tset case - I know the app is running... my $Outlook = Win32::OLE->GetActiveObject("Outlook.Application"); my ($MAPI,$Inbox,$TestFolder,$Message,$bodytext,$newtext); $MAPI=$Outlook->GetNameSpace("MAPI"); $Inbox=$MAPI->GetDefaultFolder(6); $TestFolder=$Inbox->Folders("Perlmonks"); print "There are " . $TestFolder->{Items}->{Count} . " items in the in +box.\n\n"; for my $x (1) { $bodytext = $TestFolder->Items($x)->Body; print "Message Subject:\n" . $TestFolder->Items($x)->Subject . "\n +"; print "Body Text:\n$bodytext\n"; print "Replacing entire body with \"foo bar\"\n\n"; $TestFolder->Items($x)->{'Body'} = "foo bar"; #Doesn't work.. $TestFolder->Items($x)->LetProperty('Body',"foo bar") ; #Does't wo +rk.. $TestFolder->Items($x)->Save; #Doesn't make a difference! print "Body is now supposedly:\n\n" .$TestFolder->Items($x)->Body +. "\n"; #Hasn't updated! my $NewItem = $TestFolder->Items($x)->Copy; #Works fine }

      And in VBScript...

      '..snip... For Each M In objInbox.Items Text = Text & M.Subject & vbCr x=x+1 M.Body= "foo bar" 'Assignment msgbox M.Body 'Works perfectly M.Save Next '..snip...

      I'm no expert but I couldn't get the SetProperty(property,@args,value) syntax to work in Win32::OLE... perhaps it's a bug? The VBScript/Automation of Outlook97 is pretty shoddy at the best of times. Outlook89 and above have VBA (rather than VBScript) automation, AFAIK, tho...

Re: Outlook MailItem Body Question
by BrowserUk (Patriarch) on Jan 06, 2004 at 19:09 UTC

    I know nothing about Outlook, and very little about OLE, but you read a value from an attribute

    my $body = $items->Item($itemIndex)->Body;

    modify it and then write it back to a hash element?

    $items->Item($itemIndex)->{'Body'} = $body;

    Which just doesn't seem right to me. It's a pure guess, but you might try

    $items->Item($itemIndex)->Body = $body;

    Assuming the Body attribute is writable through Win32::OLE, and I see no reason it shouldn't be, then that might give you the result you're after.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Hooray!

      I attempted that, but when it's written as you suggested, I get an error reading: "Can't modify non-lvalue subroutine call at ..." The method I came up with I found elsewhere on the web. Not sure if it's right, though. : )

        If Body is a subroutine, then the syntax for setting the value back would (probably) be

        $items->Item($itemIndex)->Body( $body );

        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        Hooray!