Let Navision Scan Inbox and extract attachment

Frank_HulsboschFrank_Hulsbosch Member Posts: 17
Hi everybody,

I'm currently looking for a solution for Navision 4.03 to read the Outlook Inbox and to save the attachment to a specified location from where it will be extracted and converted by Navision (since my code to save attachment within Outlook is not functioning anymore after Outlook is closed and restarted).

I've been playing with the 'NS Outlook Synchronization Handler' - scanning the inbox is fairly easy but once I've selected an oInboxItem I cannot set the oAttachments to this item. ](*,)

I seems to me that the creators of this automation have been focussing on sending a mail only...

I hope somebody has the right solution to solve this problem.


Thanks in advance,

Frank
FH

Comments

  • DenSterDenSter Member Posts: 8,304
    I knew I had this somewhere and I can't believe I found it in just a couple of minutes :mrgreen:. I wrote (I got most of the code from google :-$ ) this about 10 years ago in VBA to strip attachments from Outlook directly, so that must have been in Office 2000. I don't know if it will still work in your version, but the code might help to give you a direction.
    Public Sub StripAttachments()
        Dim objOL As Outlook.Application
        Dim objMsg As Object
        Dim objAttachments As Outlook.Attachments
        Dim objSelection As Outlook.Selection
        Dim i As Long
        Dim lngCount As Long
        Dim strFile As String
        Dim strFolder As String
    
        On Error Resume Next
    
        ' Instantiate an Outlook Application object.
        Set objOL = CreateObject("Outlook.Application")
        ' Get the collection of selected objects.
        Set objSelection = objOL.ActiveExplorer.Selection
    
        ' Get the Temp folder.
        strFolder = GetTempDir()
        If strFolder = "" Then
            MsgBox "Could not get Temp folder", vbOKOnly
            GoTo ExitSub
        End If
    
        ' Check each selected item for attachments.
        ' If attachments exist, save them to the Temp
        ' folder and strip them from the item.
        For Each objMsg In objSelection
            ' This code only strips attachments from mail items.
            If objMsg.Class = olMail Then
                ' Get the Attachments collection of the item.
                Set objAttachments = objMsg.Attachments
                lngCount = objAttachments.Count
                If lngCount > 0 Then
                    ' We need to use a count down loop for
                    ' removing items from a collection. Otherwise,
                    ' the loop counter gets confused and only every
                    ' other item is removed.
                    For i = lngCount To 1 Step -1
                        ' Save attachment before deleting from item.
                        ' Get the file name.
                        strFile = objAttachments.Item(i).FileName
                        ' Combine with the path to the Temp folder.
                        strFile = strFolder & strFile
                        ' Save the attachment as a file.
                        objAttachments.Item(i).SaveAsFile strFile
                        ' Delete the attachment.
                        objAttachments.Item(i).Delete
                    Next i
                End If
                objMsg.Save
            End If
        Next
    
    ExitSub:
        Set objAttachments = Nothing
        Set objMsg = Nothing
        Set objSelection = Nothing
        Set objOL = Nothing
    End Sub
    
    Private Function GetTempDir() As String
        Const TemporaryFolder = 2
    
        Dim fso As Scripting.FileSystemObject
        Dim tFolder As Scripting.Folder
    
        On Error Resume Next
    
        ' Instantiate a WSH (Windows Scripting Host)
        ' FileSystemObject.
        Set fso = CreateObject("Scripting.FileSystemObject")
        ' Get the Temp folder.
        Set tFolder = fso.GetSpecialFolder(TemporaryFolder)
    
        If Err Then
            GetTempDir = ""
        Else
            GetTempDir = LCase(tFolder.Path)
            ' Add "\" to the rightmost part of the path to
            ' the Temp folder if necessary.
            If Right$(GetTempDir, 1) <> "\" Then
                GetTempDir = GetTempDir & "\"
            End If
        End If
    
        Set fso = Nothing
        Set tFolder = Nothing
    End Function
    
    You can use most of these objects in C/AL code as well. Good luck, and let us know if you got this to work.
  • Frank_HulsboschFrank_Hulsbosch Member Posts: 17
    Thank you Denster,

    I did already solve this issue by accessing Outlook Automation directly ( :idea: ) , as long as Outlook remains backwards compatible it should work. Basically it is the same solution as your suggestion.


    // Variables

    Name DataType Subtype Length
    autOLAppl Automation 'Microsoft Outlook 11.0 Object Library'.Application
    autOLNamespace Automation 'Microsoft Outlook 11.0 Object Library'.NameSpace
    autOLItems Automation 'Microsoft Outlook 11.0 Object Library'.Items
    autOLMapiFolder Automation 'Microsoft Outlook 11.0 Object Library'.MAPIFolder
    autOLMailItem Automation 'Microsoft Outlook 11.0 Object Library'.MailItem
    oAttachments Automation 'Microsoft Outlook 11.0 Object Library'.Attachments
    oAttachment Automation 'Microsoft Outlook 11.0 Object Library'.Attachment
    txtFindCriteria Text 250
    intEndOfLoop Integer
    i Integer
    z Integer
    NoOfSavedFiles Integer

    // Code


    CLEAR(autOLAppl);
    CREATE(autOLAppl);
    autOLNamespace := autOLAppl.GetNamespace('MAPI');
    autOLNamespace.Logon('','',TRUE,FALSE);

    autOLMapiFolder := autOLNamespace.GetDefaultFolder(6);
    autOLItems := autOLMapiFolder.Items;
    txtFindCriteria := '[Sendername] = '<originator of mail>';
    autOLItems := autOLMapiFolder.Items.Restrict(txtFindCriteria);

    CLEAR(NoOfSavedFiles);

    i := 1;
    intEndOfLoop := autOLItems.Count;
    IF intEndOfLoop > 0 THEN
    Window.OPEN('Mail From #1############################################\' +
    'Subject #2############################################\' +
    'Attachments #3## #4#####################################');

    WHILE i <= intEndOfLoop DO BEGIN
    autOLMailItem := autOLItems.Item(i);

    // Only Process if UnRead yet
    IF (autOLMailItem.UnRead = TRUE) THEN BEGIN
    oAttachments := autOLMailItem.Attachments;

    Window.UPDATE(1, autOLMailItem.SenderName);
    Window.UPDATE(2, autOLMailItem.Subject);
    Window.UPDATE(3, FORMAT(oAttachments.Count) );

    IF oAttachments.Count <> 0 THEN BEGIN
    // Run Though Attachments
    FOR z := 1 TO oAttachments.Count DO BEGIN
    oAttachment := oAttachments.Item(z);
    Window.UPDATE(4, oAttachment.FileName);
    oAttachment.SaveAsFile('<save 2 location>', oAttachment.FileName);
    NoOfSavedFiles += 1;
    END;
    END;

    // Mark As READ (By Navision)
    autOLMailItem.UnRead(FALSE);
    autOLMailItem.Close(1);
    END;

    i := i + 1;
    END;

    CLEAR(autOLMailItem);
    CLEAR(autOLAppl);
    FH
  • DenSterDenSter Member Posts: 8,304
    The trick in doing this in C/AL is to use the actual office object model, and not the NAV dll's. For instance I had run into so many problems using the MSMQ busadapter (encoding problems, label problems, queue type problems) that at some point we started using the object model itself. It was a lot of trial and error, but in the end it was very close to the VB samples that we found online.

    You can basically use the VBA code as a template for C/AL code, you just have to make sure you handle type conversion, and events are difficult to use. Browse the automation subtypes, you'll be surprised at how much is available there.
Sign In or Register to comment.