Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Notes::OLE: Doc-Dumper?

by mhi (Friar)
on Jul 06, 2004 at 10:09 UTC ( [id://372057]=perlquestion: print w/replies, xml ) Need Help??

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

Esteemed Monks,

I'm looking at accessing my Lotus Notes Datebook through perl and would like to know how I can visualize the document structure of an appointment (i.e. show all its attributes and their respective values).

Is there a ready-made function to do this

  • with appointment documents in particular?
  • with mailbox (i.e. "Appointment" or "Memo") documents in general?
  • with any documents (maybe by looking at the structure of the "form" associated with the document)?

The (fully functional) code I'm currently using is the following, which finds a number of appointments in my calendar and prints their titles:

#!/usr/bin/perl -w use strict; use Notes::OLE; use vars qw( $SERVER ); $SERVER=''; # leave empty if querying local client my $mailfile='mail\myshortname.nsf'; my $maxdocs=50; # 0=all my $maxshowdocs=5; my $db = $S->GetDatabase($SERVER, $mailfile); my $docs=$db->Search( "Form = \"Appointment\"" , $DT, $maxdocs); # "Ap +pointment"(calendar) or "Memo"(email) my $count = $docs->Count; print "found ",$count," docs.\n\n"; # show the appointments' titles for(my $i=1; $i<=$maxshowdocs and $i<=$count ;++$i){ my $doc=$docs->GetNthDocument($i); if($doc->HasItem('Subject')){ print $doc->GetFirstItem('Subject')->{Text},"\n"; }else{ print "No Subject\n"; } }
I'm just hoping I don't have to write code to individually check every one of the attributes in these tables the same way as with the subject attribute above. (Not to mention possible multivalue and/or structured attributes... do they use those in Notes?)

Thanks for any suggestions!

Michael

Update: added clarification on "mailbox documents" and on first sentence.

Replies are listed 'Best First'.
Re: Notes::OLE: Doc-Dumper?
by diotalevi (Canon) on Jul 06, 2004 at 13:50 UTC

    Nope. It doesn't exist yet so you get to write it.

    As a matter of efficiency, do not use the GetNthDocument function (or use it sparingly). It is a dastardly slow call as it is just a loop from the beginning out $N number of times. Here's a sample of how it really works. Yuck!

    sub DumpDoc { my $doc = shift; return map +( $_->Name, [ @{ $_->Values } ] ), @{ sort { $a cmp $b } $doc->Items }; } Function GetFirstDocument( DC as NotesDocumentCollection, N As Long ) +As NotesDocument Dim Doc As NotesDocument Dim Count As Long If N < 1 Then Exit Function Set Doc = DC.GetFirstDocument Select Case N Case 1 Set GetFirstDocument = Doc Case Else While Not Doc Is Nothing And Count < N Set Doc = DC.GetNextDocument( Doc ) Count = Count + 1 Wend End Select Set GetFirstDocument = Doc End Function
Re: Notes::OLE: Doc-Dumper?
by Zero_Flop (Pilgrim) on Jul 06, 2004 at 19:15 UTC
    There are three ways to accomplish different aspects of what you want.

    Least helpful:
    Open an appointment and select FILE -> EXPORT. This will export the document to a text file and you can see all the fields. But you don’t get any information about the fields.

    More helpful:
    Right click on the document and open the document properties. Select the second tab and you will have a list of all of the fields and their properties.

    Probably most helpful:
    Write a generic perl script that uses the property of NotesForm -> Fields to determine the name of all of the fields, then use the method GetFieldType to determine the type of each field.

    Writing the code should not be too difficult and it would be helpful for future projects if you have any.
    ZeroFlop
Re: Notes::OLE: Doc-Dumper?
by mhi (Friar) on Jul 07, 2004 at 12:30 UTC
    Ok, I wrote it and tested it with form=appointment-documents, but it might work with pretty much any notes document (see code below).

    Thanks diotalevi and Zero_Flop for your insights! Since I don't need to look at more than a handful of documents, I'll stick to GetNthDocument for the time being.

    As it turns out, the most difficult thing to analyze is the array returned by GetItemValueDateTimeArray since it can contain either NotesDateRange or DateTime. Is there any better way of telling which it is other than looking at the ItemName like I've done here?

    #!/usr/bin/perl -w use strict; use Notes::OLE; use vars qw( $SERVER ); $SERVER=''; # empty when querying local client my $mailfile='mail\myshortname.nsf'; my $maxdocs=50; # 0=all my $maxshowdocs=1; my $n="\n"; my $db = $S->GetDatabase($SERVER, $mailfile); my $docs=$db->Search( "Form = \"Appointment\"" , $DT, $maxdocs); # "Ap +pointment"(calendar) or "Memo"(email) my $count = $docs->Count; print "found ",$count," docs.\n\n"; for(my $i=1;$i<=$maxshowdocs and $i<=$count ;++$i){ print "############## Document $i ###################\n\n"; my $doc=$docs->GetNthDocument($i); my $items=$doc->Items; foreach my $item (@$items){ my $name=$item->Name; my $type=$item->Type; print "ItemName: $name / ItemType: $type"; my $val; if( $type==1024 ){ # Type-Value for DateTime Type my $dtarr=$doc->GetItemValueDateTimeArray($name); print " [", scalar @$dtarr," value(s) in Item]"; print " (DateTime) "; foreach my $dtelem (@$dtarr){ if( $name=~/Range$/ ){ # DateTime or NotesDateRange? ***** $val .= ($dtelem->{StartDateTime}->{LocalTime})." - ". ($dtelem->{EndDateTime}->{LocalTime})." "; }else{ $val .= ($dtelem->{LocalTime})." "; } } }else{ $val=$doc->GetItemValue($name); print " [", scalar @$val," value(s) in Item]"; $val=join($n, @$val); } print "$n$val$n$n"; } }

    Update: Added smartass comment as first sentence. ;-) Made first sentence into a new and improved first paragraph.

      Type property ->returns constants like ATTACHMENT, DATETIMES, HTML, EMBEDDEDOBJECT, RICHTEXT, TEXT...

      TypeName -> type of data each element in the array is, like NotesDateRange or DateTime. This can also be used for the other fields.

      Zero_Flop
        I only see the type property returning numeric constants such as 1024 for DateTime. Am I looking at it the wrong way? But that's not a problem as these codes are documented.

        How would you use the LotusScript function TypeName in the OLE-Interface?
        Using $dtelem->{TypeName} in the code above delivers an error Win32::OLE(0.1502) error 0x80020003: "Member not found" in METHOD/PROPERTYGET "TypeName" at ./dumpdocs.pl line 38 so it's obviously not implemented as a method on the array element... This is no fun poking around in the dark. :-(

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-04-16 19:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found