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

Please have mercy on me,

I humbly submit my plea to those more enlightened who have prevailed over the evils of Lotus Notes.

I'm stuck with a situation where an object returns an array. In perl I receive a reference to an array. When I go through that I get back Win32::OLE=HASH{0xnnn) which I don't know how to handle. I'm trying to do the 'forall' statement in the following notes code:

# Dim rtitem As Variant # Set rtitem = doc.GetFirstItem( "Body" ) # Forall o In rtitem.EmbeddedObjects # If o.Type = EMBED_ATTACHMENT Then # Call o.ExtractFile( "c:\newfiles\" & o.Source ) # Call o.Remove # Call doc.Save( True, True ) # End If # End Forall #End Sub
I think the key is the 'Variant' type but I don't understand what that could be done in PERL.

foreach my $embeddedDoc ( $DocumentBody->{EmbeddedObjects} ) { my $edocType =$embeddedDoc->{Type}; # Above returns a blank if ( $edocType eq 'EMBED_ATTACHMENT' ) { print "Embedded Attachment!\n"; } elseif ( $edocType eq 'RICH_TEXT' ) { print "Some sort of Rich Document\n"; } else { print "Unknown Attachment!\n"; } }
Here's the full text of my code. The program is supposed to loop into a Notes e-mail database and tell me if the documents inside have an attachment and what kind. It's based on the code sample in the ActiveState 5.6 PERL HTML.

use strict; use Win32::OLE; my $Notes = Win32::OLE->new('Notes.NotesSession') or die "Cannot start Lotus Notes Session object.\n"; my ($Version) = ($Notes->{NotesVersion} =~ /\s*(.*\S)\s*$/); print "The current user is $Notes->{UserName}.\n"; print "Running Notes \"$Version\" on \"$Notes->{Platform}\".\n"; #my $Database = $Notes->GetDatabase('', 'help4.nsf'); # muser.nsf -- local mail file my $Database = $Notes->GetDatabase('', 'muser.nsf'); my $AllDocuments = $Database->AllDocuments; my $Count = $AllDocuments->Count; print "There are $Count documents in the database.\n"; for (my $Index = 1 ; $Index <= $Count ; ++$Index) { my $Document = $AllDocuments->GetNthDocument($Index); # Get subget of document printf "$Index. %s\n", $Document->GetFirstItem('Subject')->{Text}; # He called the Text property of Subject, how did he know?-^^^^^^ if ( $Document->HasEmbedded ) { my $DocumentBody = $Document->GetFirstItem('Body'); #my $bodytext = $Document->GetFirstItem('Body')->{Text}; #print $bodytext."\n"; # Works occasionally, but not always foreach my $embeddedDoc ( $DocumentBody->{EmbeddedObjects} ) { # I asked for an array of embedded objects # but what I get back is an array reference my $edocType =$embeddedDoc->{Type}; # This yields nothing if ( $edocType eq 'EMBED_ATTACHMENT' ) { print "Embedded Attachment!\n"; } elseif ( $edocType eq 'RICH_TEXT' ) { print "Some sort of Rich Document\n"; } else { print "Unknown Attachment!\n"; } # I get back Win32::OLE=hash(0xnnnn) #my $embed_type = ${$embeddedDoc}{Type} #print $embed_type."\n" } } # limiter last unless $Index < 100; # Get only 5 entries } # Sample notes code that I'm trying to copy # #Sub Click(Source As Button) # Dim session As New NotesSession # Dim db As NotesDatabase # Dim collection As NotesDocumentCollection # Dim doc As NotesDocument # Set db = session.CurrentDatabase # Set collection = db.AllDocuments # For i = 1 To collection.Count # Set doc = collection.GetNthDocument( i ) # If doc.HasEmbedded Then # Call detachFiles( doc ) # End If # Next #End Sub #Sub detachFiles( doc As NotesDocument ) # Dim rtitem As Variant # Set rtitem = doc.GetFirstItem( "Body" ) # Forall o In rtitem.EmbeddedObjects # If o.Type = EMBED_ATTACHMENT Then # Call o.ExtractFile( "c:\newfiles\" & o.Source ) # Call o.Remove # Call doc.Save( True, True ) # End If # End Forall #End Sub # You can get documentation on Notes objects from # http://www.lotus.com/products/lotusscript.nsf

Replies are listed 'Best First'.
Re: PERL
by Shendal (Hermit) on Aug 29, 2000 at 20:03 UTC
    I'd start by checking what is in that hash ref. Have you tried putting in some diagnostic code such as:
    foreach (keys %{ $embeddedDoc }) { print "$_ = $embeddedDoc->{$_}\n"; }
    This will show you what's in that hash, and perhaps point you to the data you want.

    Cheers,
    Shendal
Re: PERL
by Anonymous Monk on Aug 29, 2000 at 21:34 UTC
    Looks like I've been getting the correct responses in the firstplace. I'm only starting to use and pass references plus I don't know Lotus Notes at all ... ingredients for confusion. I'm posting my discoveries for anyone who cares.

    foreach my $embeddedDoc ( $DocumentBody->{EmbeddedObjects} ) { print ref($embeddedDoc) if ( ref($embeddedDoc)); print "\n"; #reply-> ARRAY foreach my $arryele ( @{$embeddedDoc } ) { print "Array Element: $arryele\n"; #reply-> Array Element: Win32::OLE=HASH(0x183a66c) print ref($arryele) if ( ref($arryele)); print "\n"; #reply-> Win32::OLE #I am so stupid, $arryele is a referenced object that has b +een # blessed into a package ... it says so in the documentatio +n for ref! my @array = $arryele->{Source}; print "@array\n"; # This returns the filename of the attachment my @array = $arryele->{Type}; print "@array\n"; # This returns some numeric value, EMBED_ATTACHMENT and # RICH_TEXT must be constants within Lotus Notes! It doesn +'t # return text. I've been away from MS-style object program +ming # too long ... that's a good thing right? # 1454 - File attachment # 1453 - Embedded document -- Notes internal format? #foreach my $whatisit ( @{$arryele} ) { # print "arryele: $whatisit\n"; #} # This won't work, Not an ARRAY reference at notesmail.pl +line 85 #foreach my $hashval ( keys %{$arryele} ) { # print "$hashval = $arryele->{$hashval}\n"; #} # This would never work since it's not a hash as I origina +lly thought }
RE: PERL, Win32::OLE - Lotus Notes and passing objects
by Anonymous Monk on Aug 29, 2000 at 20:08 UTC
    Oops, the code above had 'elseif' instead of 'elsif', otherwise it would run. Everything works except the code that is supposed to determine the type of attachment.

    The code was supposed to this.

    foreach my $embeddedDoc ( $DocumentBody->{EmbeddedObjects} ) { my $edocType =$embeddedDoc->{Type}; if ( $edocType eq 'EMBED_ATTACHMENT' ) { print "Embedded Attachment!\n"; } elsif ( $edocType eq 'RICH_TEXT' ) { print "Some sort of Rich Document\n"; } else { print "Unknown Attachment! [ $edocType ] \n"; } }
    Output is:

    ..snip.. Running Notes "Release 4.5.5 (Intl)|14 April 1998" on "Windows/32". There are 470 documents in the database. 1. Test 2. Test .. snip .. 74. Metrics for the past 2 weeks. Unknown Attachment! .. snip .. All I get is a null string. 8-(

RE: PERL, Win32::OLE - Lotus Notes and passing objects
by Anonymous Monk on Aug 29, 2000 at 20:09 UTC
    Oops, the code above had 'elseif' instead of 'elsif', otherwise it would run. Everything works except the code that is supposed to determine the type of attachment.

    The code was supposed to this.

    foreach my $embeddedDoc ( $DocumentBody->{EmbeddedObjects} ) { my $edocType =$embeddedDoc->{Type}; if ( $edocType eq 'EMBED_ATTACHMENT' ) { print "Embedded Attachment!\n"; } elsif ( $edocType eq 'RICH_TEXT' ) { print "Some sort of Rich Document\n"; } else { print "Unknown Attachment! [ $edocType ] \n"; } }
    Output is:

    ..snip.. Running Notes "Release 4.5.5 (Intl)|14 April 1998" on "Windows/32". There are 470 documents in the database. 1. Test 2. Test .. snip .. 74. Metrics for the past 2 weeks. Unknown Attachment! [ ] .. snip ..
    All I get is a null string. 8-(

RE: PERL, Win32::OLE - Lotus Notes and passing objects
by Anonymous Monk on Aug 29, 2000 at 20:29 UTC
    Shendal,

    Thanks for the tip. What I get back is Win32:OLE=HASH(nnnnn). The following code is my 'diagnostic' version. As you can see I get back an unusual type from the ref() on $arryele. What am I missing?

    foreach my $embeddedDoc ( $DocumentBody->{EmbeddedObjects} ) { print ref($embeddedDoc) if ( ref($embeddedDoc)); print "\n"; #reply-> ARRAY foreach my $arryele ( @{$embeddedDoc } ) { print "Array Element: $arryele\n"; #reply-> Array Element: Win32::OLE=HASH(0x183a66c) print ref($arryele) if ( ref($arryele)); print "\n"; #reply-> Win32::OLE # now I'm stuck # The following does nothing foreach my $hashval ( keys %{$arryele} ) { print "$hashval = $arryele->{$hashval}\n"; } } my $edocType =$embeddedDoc->{Type}; if ( $edocType eq 'EMBED_ATTACHMENT' ) { print "Embedded Attachment!\n"; } elsif ( $edocType eq 'RICH_TEXT' ) { print "Some sort of Rich Document\n"; } else { print "Unknown Attachment! [ $edocType ] \n"; } } }