How to detach an attachment from Lotus Notes

Is there a way to detach files from Lotus Notes,,,, say every hour or so.  There will be files coming into an email box and I want to detach the files to a directory every hour.  Either using Lotus Notes directly or using .net somehow.


Thanks
Tim
tbailey922Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
mbonaciCommented:
Hi tbailey922,
Yes you can schedule an agent to do it every hour.

To code it look at NotesEmbeddedObject class in Designer's help or here:

    http://www.kamat.co.uk/KamatHomePage.nsf/CatalogByTips/FAA62F2C875CBD6DC1256B91002F6EFE?OpenDocument&menu=ByCategory

Hope this helps,
Marko
marilyngCommented:
Hi tbailey922,

You need to test to make sure that the server can write to the directory you specify...
YOu can also add agentlog statements to this to send you a notification or list of files detached.
Be sure to change the detach directory to one that you want to use.
Also, this agent adds the yyyyymmddhhmmss to the filename so as not to overwrite same files.

Sub initialize
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Set db = session.currentDatabase    
    Dim coll As NotesDocumentCollection
    Set coll = db.unprocesseddocuments
   
    If coll.count <1 Then Exit Sub
    Dim count As Integer,nAttached As Variant
    Dim doc As NotesDocument
    Dim rtitem As Variant        
    Dim stamp As String, ext As String, fn As String, DetachFileName As String
    'CONFIGURE THESE FOR YOUR ENVIRONMENT...............................................................
    Const DETACH_DIRECTORY = "C:\DetachAll\"
            'Leave this blank if you don't want a log summary mailed to someone    
    Const str_SENDTO="ENTER A NAME"
    Dim doLog As Boolean
    If Not DirExists(DETACH_DIRECTORY + "*.*") Then
        Mkdir DETACH_DIRECTORY        
    End If
    'If you want to mail results then include this section
    If doLog Then
        Dim currentLog As NotesLog
        Set currentLog = New NotesLog( "Detach Log" )
        Call currentLog.OpenMailLog     (str_SENDTO, "Here's the Detach File Log" )
    End If
    Set doc = coll.GetFirstDocument
    While Not doc Is Nothing
        nAttached=Evaluate({@Attachments},doc)
        If nAttached(0)>0 Then
            '...set value of doc...
            If doc.HasItem("Body") Then
                Set rtitem = doc.GetFirstItem( "Body" )
                  'cycle through attachments in the rich text field - get duplicate names
                If ( rtitem.Type = RICHTEXT ) Then
                    Forall o In rtitem.EmbeddedObjects
                        If ( o.Type = EMBED_ATTACHMENT ) Then
                            If o.filesize >0 Then
                                If doesFileExist(DETACH_DIRECTORY + o.source) Then
                                       'there is already an o.source detached,
                                    stamp$ = "_" + Format(Now,"yyyymmddhhmmss")
                                    ext$="." + Strrightback(o.Source, ".")
                                    fn$ = Strleftback(o.Source,ext$)
                                    DetachFileName$ = DETACH_DIRECTORY + fn$ + stamp$ + ext$        
                                Else
                                       'this is a new version
                                    detachFileName$ = DETACH_DIRECTORY + o.source
                                End If
                                count = count +1
                                Call o.ExtractFile(DetachFileName$ )    
                                If doLog Then
                                        'This will build a list of detached files and their destination
                                    Call currentlog.LogAction("Detached: " + o.source + " to " + DetachFileName$)
                                End If
' Unremark these next if you want to  remove and save the document            
%REM
                      Call o.Remove
                      doc.save true, false, true
%END REM                    
                            End If
                        End If
                        stamp$=""
                        ext$=""
                        fn$=""                        
                    End Forall        
                End If
            End If
        End If
        Set doc = coll.GetNextDocument(doc)
    Wend
   
    If doLog Then
            'this will mail the log to the person who runs the agent
        currentlog.close
    End If
   
    Call coll.updateall
    Set coll = Nothing
    Print "finished detach agent"
End Sub

Function doesFileExist(strPath As String) As Integer
    Dim tmpFile As String
    doesFileExist = False
    If strPath="" Then Exit Function
    On Error Goto NoFile_Error    
    tmpFile = Dir$(strPath)
    If Len(tmpFile)<>0 Then doesFileExist = True
    Exit Function
   
NoFile_Error:
    Err = 0
    doesFileExist = False
    Exit Function
End Function

Function DirExists(DirName As String) As Boolean
    On Error Goto ErrorHandler
    ' test the directory attribute
    DirExists = Getattr(DirName)
    Exit Function
ErrorHandler:
    Err=0
    ' if an error occurs, this function returns False    
    Exit Function
End Function

Regards!
Build an E-Commerce Site with Angular 5

Learn how to build an E-Commerce site with Angular 5, a JavaScript framework used by developers to build web, desktop, and mobile applications.

tbailey922Author Commented:
Hey marilyng,


What if I get the ERROR: "Path/file access error"?  does that mean I don't have rights?

Thanks
Tim
tbailey922Author Commented:
Took care of the "Path/file access error"  Now I get the error: "Type Mismatch"   Any ideas??


Thanks
Tim
marilyngCommented:
Is this running on server or are you attempting to debug locally?

Only way to tell is first run locally, turn on debugger, remark out the On Error goto  lines by putting ' in front of the line(s), And hit run.. it should stop on the line that is throwing the error.  

My guess is it's the agentlog, because I'm not seeing the dolog =false and testing for dolog.  So, for instance, the dolog should start as false

if str_SendTo = "" then
  dolog = false
else
  doLog = true
end if

The only other could be if the document doesn't have an attachment and nattached isn't returning a variant.
What does the agentlog email tell you? (if you fill in your name, you get a summary of what it processed)


marilyngCommented:
Ok, my apologies... pasted the wrong version without all the error logs.  There was a typo in the dirExists, and this one was also set to detach .xls files.  So I modified it, if you want to filter a certain file type, then change the

Const str_SENDTO="" to Const str_SENDTO=".xls" or whatever extension you want to specify, otherwise it will detach all files.
If you want a log then add your name to the const STR_SENDTO ="youremailaddress"

You will get an email log like this:
3/13/2006 08:22:56 PM  Detach Log starting
03/13/2006 08:22:56 PM  Detached: actn015.gif to
C:\Lotus\Notes6\Data\Detached\actn015.gif
03/13/2006 08:22:56 PM  Detached: actn038.gif to
C:\Lotus\Notes6\Data\Detached\actn038.gif

Try first setting the agent to manual on selected documents
This will trap for a directory, and if the directory doesn't exist it will attempt to create one.


Corrected:
----------------------------------------------------------------------------
Option Public
Option Declare

Sub initialize
      'YOUR DETACH DIRECTORY.....................................................
      Const DETACH_DIRECTORY = "C:\Lotus\Notes6\Data\Detached\"      
      'LEAVE THIS BLANK IF YOU DON'T WANT A LOG OR MEMO SENT
      Const STR_SENDTO=""
      'Add extension ie: .XLS if you want to specify file type to detach else leave null
      Const STR_DETACHEXT=""
      
      Dim session As New NotesSession
      Dim db As NotesDatabase
      Set db = session.currentDatabase      
      Dim coll As NotesDocumentCollection
      Set coll = db.unprocesseddocuments
      Dim doLog As Boolean
      Dim msg As String
      Dim currentLog As NotesLog
      
      If STR_SENDTO = "" Then doLog = False Else doLog = True
      If coll.count <1 Then
            msg ="No Documents to process..."
            If doLog Then
                  Call currentlog.logaction(msg)
                  Call currentlog.close
            End If
            Exit Sub
      End If
      
      On Error Goto Handle_Error
      Dim count As Integer,nAttached As Variant
      Dim doc As NotesDocument
      Dim rtitem As Variant            
      Dim stamp As String, ext As String, fn As String, DetachFileName As String      
      
      
      On Error Goto CreateDir_Error
      If Not DirExists(DETACH_DIRECTORY) Then            
            Mkdir DETACH_DIRECTORY            
      End If
      
      On Error Goto Handle_Error      
      If STR_SENDTO = "" Then doLog = False Else doLog = True
      'If you want to mail results then include this section
      If doLog Then            
            Set currentLog = New NotesLog( "Detach Log" )
            Call currentLog.OpenMailLog       (str_SENDTO, "Here's the Detach File Log" )
      End If
      Dim DETACH_FILENAME As String
      Set doc = coll.GetFirstDocument
      While Not doc Is Nothing
            nAttached=Evaluate({@Attachments},doc)
            If nAttached(0)>0 Then
            '...set value of doc...
                  If doc.HasItem("Body") Then
                        Set rtitem = doc.GetFirstItem( "Body" )
                    'cycle through attachments in the rich text field - get duplicate names
                        If ( rtitem.Type = RICHTEXT ) Then
                              Forall o In rtitem.EmbeddedObjects
                                    If ( o.Type = EMBED_ATTACHMENT ) Then
                                          If o.filesize >0 Then
                                                DETACH_FILENAME = o.source
                                                Select Case STR_DETACHEXT
                                                Case Is=""
                                                      'if no extension is specified then detach the file
                                                      DetachFileName$ = DETACH_DIRECTORY + DETACH_FILENAME                                                      
                                                      count = count +1
                                                      Call o.ExtractFile(DetachFileName$ )      
                                                      If doLog Then
                                                             'This will build a list of detached files and their destination
                                                            Call currentlog.LogAction("Detached: " + o.source + " to " + DetachFileName$)
                                                      End If      
                                                Case Else
                                                      'Extension is specified so only detach these files with these extensions
                                                      If Instr(1,o.source, STR_DETACHEXT,5)>0 Then
                                                            DetachFileName$ = DETACH_DIRECTORY + DETACH_FILENAME                                                      
                                                            count = count +1
                                                            Call o.ExtractFile(DetachFileName$ )      
                                                            If doLog Then
                                                             'This will build a list of detached files and their destination
                                                                  Call currentlog.LogAction("Detached: " + o.source + " to " + DetachFileName$)
                                                            End If      
                                                      End If                                                      
                                                End Select            
                                          End If
                                    End If                                          
                              End Forall            
                        End If
                  End If
            End If
            'if you want to import here before you overwrite your excel file, then you need to call the import agent here
            'Otherwise, this will next loop simply overwrite the previously detached filename before you can import it
            Set doc = coll.GetNextDocument(doc)
      Wend
      
      If doLog Then
            'this will mail the log to the person who runs the agent
            currentlog.close
      End If
      
      Call coll.updateall
      Set coll = Nothing
      Print "Finished detach agent"
      Exit Sub
      
Handle_Error:
      msg="Sorry, there was an error running the agent:  Error: "  + Error$ + "-" + Str(Err) + " Line: " + Str(Erl)
      Print msg
      On Error Goto 0
      If doLog Then
            Call  currentLog.logAction(msg)
            Call currentLog.close
      End If
      Exit Sub
      
CreateDir_Error:
      msg="Sorry, there was an error creating the target directory: " + DETACH_DIRECTORY + " Error: "  + Error$ + "-" + Str(Err)
      Print msg
      On Error Goto 0
      If doLog Then
            Call currentLog.logAction(msg)
            Call currentLog.close
      End If
      Exit Sub
End Sub


Function doesFileExist(strPath As String) As Integer
      Dim tmpFile As String
      doesFileExist = False
      If strPath="" Then Exit Function
      On Error Goto NoFile_Error      
      tmpFile = Dir$(strPath)
      If Len(tmpFile)<>0 Then doesFileExist = True
      Exit Function
      
NoFile_Error:
      Err = 0
      doesFileExist = False
      Exit Function
End Function

Function DirExists(DirName As String) As Boolean
      On Error Goto ErrorHandler
    ' test the directory attribute
      DirExists = Getattr(DirName)
      If dirExists And 16 = 16 Then
            dirExists = True
      End If
      Exit Function
ErrorHandler:
      Err=0
    ' if an error occurs, this function returns False      
      Exit Function
End Function
mbonaciCommented:
If this should be split at all, my suggestion is to give Marilyng at least 200 pts.
But the fair thing here would be to accept only the Marilyng's answer (and in all other cases where there's much usefull code written - much time spent).
marilyngCommented:
Marko, I will recommend that way when I am not the person writing the code and making the recommendation.
mbonaciCommented:
Marilyng,
then that's one more argument not to suggest on questions you're in:

      1. We all know that the recomandation for acceptance should be the guideline for the people looking for answers (and when he finds the question will he look at who participated, who suggested and who closed it or he will just look who's answer is accepted?) - You see my point?

      2. Why would you lose points if you deserve them?

C'ya
mbonaciCommented:
Annie
I'll help when you decide to pay, like the users pay you for the points (then you wont need the ghosts, you'll have a bunch of "volunteers").
It just isn't polite to acuse someone for not "donating his work" (that "EVER" especially bothered me).

> "Spending more or less time on a question does not mean getting more/less points."
This is my sentence, notice the key word USEFUL:
"and in all other cases where there's much useful code written - much time spent"
I think all of the experts understood what I was talking about, but here you are:
It's not the same thing when you write the solution in words as when you code the solution (which is the case in this question).

And one more thing, I was talking about principles here (read the whole thing one more time), noone acused Marilyng of nothing, so the smiley was not appropriate at the end (you cannot write that kind of post and then smile).
mbonaciCommented:
> > It's not the same thing when you write the solution in words as when you code the solution (which is the case in this question).

> It depends. Sometime a written in words solution is even better - as you can do your own coding. And I am a developer - I happen to work with code every day so I > know what I am talking about here.

YEAH

One question, do you get paid for your work at EE?
mbonaciCommented:
I think that all will agree that good code is the best the user can get, and it should be rewarded accordingly.
Not to mention well commented code.

What technology are you working on?
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Lotus IBM

From novice to tech pro — start learning today.