Solved

MAPI and attachments

Posted on 2002-06-11
8
509 Views
Last Modified: 2007-11-27
Hi,

I've written a VB6 program that creates a compressed and encrypted ascii file that needs to be e-mailed out.  The program is running on a PC with Windows NT Workstation and Outlook98.

Basically, on the first attempt to send the email (with the option to view msg first) I get an error message saying "Could not open one or more attachments".  The email is displayed, but has no attachment.  Strangely enough, if you manually attach the file and send it, when the e-mail arrives at its destination there are two copies of the file attached.

If I then restart the program and attempt to generate another e-mail it all works fine, no error messages or anything.

Any help would be gratefully received!

Thanks,

Julian
0
Comment
Question by:JulianDavies
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
8 Comments
 
LVL 6

Expert Comment

by:simonbennett
ID: 7070125
Can we see the code?

Thanks
0
 

Author Comment

by:JulianDavies
ID: 7070240
This is the routine I'm using....

Private Sub GenerateEmail(Optional strSingleFile As String)

Dim strFile As String
Dim strText As String

' Generate a new e-mail
    mapiMail.Compose

' Get the address
    If mblnRSM = True Then
        ' Use the address from the relevant tab
        mapiMail.RecipAddress = mstrEmailRcpt
        'mapiMail.RecipDisplayName = mstrEmailRcpt
        strFile = strSingleFile
    Else
        ' Use the RSM's own address
        mapiMail.RecipAddress = mobjRSMs(mintSelectedRSM).Email
        'mapiMail.RecipDisplayName = mobjRSMs(mintSelectedRSM).Name
        strFile = mobjRSMs(mintSelectedRSM).ClientFile
    End If

' Add subject line
    mapiMail.MsgSubject = mobjActions(mintSelectedAction).Subject

' Add body text
    strText = " " & vbCrLf & vbCrLf & mobjActions(mintSelectedAction).Subject & vbCrLf & vbCrLf
    If txtEmailText.Text <> "" Then
         strText = strText & "Information: " & txtEmailText.Text
    End If
    mapiMail.MsgNoteText = strText
   
' Add file attachment
    mapiMail.AttachmentIndex = mapiMail.AttachmentCount
    mapiMail.AttachmentType = 0
    mapiMail.AttachmentPathName = strFile
    mapiMail.AttachmentName = ""
    mapiMail.AttachmentPosition = 0    
    mapiMail.send True
   
End Sub
0
 
LVL 18

Expert Comment

by:mdougan
ID: 7070298
You might need to reset the AttachmentCount if you are re-using this same mapiMail object.  I've normally created a New mapiMail object, composed it, attached files and sent it out, and then set the mapiMail object = Nothing.  This ensures that the attachmentcount etc always gets set back to the default values for each new composition.

Also, I remember something funny about setting the AttachmentIndex also increments the AttachmentCount, so, put a breakpoint on that line and verify that the count is what you think it should be and that the attachmentindex is what you think it should be each time.........
0
Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

 

Author Comment

by:JulianDavies
ID: 7070496
Will try it, but not sure if that will help... it's only on first use that the problem occurs!

Setting the object to nothing could be a problem as it's a control on the form, rather than just an object instantiated in code.
0
 
LVL 18

Expert Comment

by:mdougan
ID: 7070538
You have a point.  I've been working mostly with object variables.  Keep in mind that you don't need to have a physical control on the form.  You can keep the Project Component checked (which references the object library) and then just declare a variable as:

Dim x as MAPI.Session

Set x = New MAPI.Session

(you'd have to double check the actual class names, but the auto-complete should give you the right objects to work with).

Then, you could work with the object as I described.

It's likely that the AttachmentIndex needs to be a 1 based index (so, the first attachment has an index of 1), and the first time through, your AttachmentCount = 0.  So, it has a problem.  However, setting the AttachmentIndex (maybe even when setting it incorrectly) may be bumping up the attachmentcount to 1, which will then succeed the next time.  However, if the attachmentcount keeps incrementing you'll start getting weird results, like the double-attachments.  So, you either need to remove all attachments (maybe by setting the attachmentcount = 0 each time through) or, set the mapimail object = nothing
0
 

Author Comment

by:JulianDavies
ID: 7077595
Sorry for the delay, but I've now tried your suggestions and the incidences of the problem went down, but didn't totally go away.  Interestingly (?) I've done trials with Outlook Express instead of Outlook and the problem doesn't occur!  Not sure if that is significant or not, but I'd still like to get it working with Outlook98.
0
 
LVL 18

Accepted Solution

by:
mdougan earned 300 total points
ID: 7078189
I experimented with attachments using the mapi objects that I'd suggested, and came up with this code that seems to work pretty reliably.  It probably wouldn't take much effort to change this sub to mirror the functionality of your existing sub.  I'd suggest you try it, keeping your original code there to fall back on if it doesn't work for you.  I believe that it's using the CDO library, though because I'm using CreateObject, I don't have to reference it in the application.  You may need to do something else with the session object's logon, but it should be similar to whatever you're doing now:

Public Sub EventNotice()
Dim objSession As Object
Dim objMessage As Object
Dim objRecipient As Object
Dim objAttachment As Object
    On Error GoTo ErrorRtn

    'Create the Session Object
    Set objSession = CreateObject("mapi.session")
   
    objSession.Logon profileName:="Outlook"
                       
    'Add a new message object to the OutBox
    Set objMessage = objSession.Outbox.Messages.Add
    objMessage.Subject = "Test with Attachments"
    objMessage.Text = "Test with Attachment Bodytext"
   
    Set objRecipient = objMessage.Recipients.Add
    objRecipient.Address = "SMTP:mike.dougan@csfb.com"
    objRecipient.Type = 1
    objRecipient.Resolve
   
    Set objAttachment = objMessage.Attachments.Add
    objAttachment.Type = 1
    objAttachment.Position = 0
    objAttachment.Name = "c:\test1.jpg"
    objAttachment.ReadFromFile "c:\test1.jpg"
   
    Set objAttachment = objMessage.Attachments.Add
    objAttachment.Type = 1
    objAttachment.Position = 1
    objAttachment.Name = "c:\test2.jpg"
    objAttachment.ReadFromFile "c:\test2.jpg"
           
    objMessage.Update
    objMessage.send showDialog:=False
    objSession.Logoff
     
ExitRtn:
    Set objSession = Nothing
    Set objMessage = Nothing
    Set objRecipient = Nothing
    Set objAttachment = Nothing
   
    Exit Sub
ErrorRtn:
    MsgBox Err.Description
    GoTo ExitRtn

End Sub
0
 

Author Comment

by:JulianDavies
ID: 7086347
Thanks for your help.... that's working fine.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question