Sending E-Mail through application

I

Ivan Weiss

I get the error:
'Send' is ambiguous across the inherited interfaces
'...frmNewCustomerForm.vb'
with the following code:

Dim objOutlook As New Outlook.Application()
Dim objMail as MailItem = objOutlook.CreateItem(OlItemType.OlMailItem)

With objMail
.To = "(e-mail address removed)"
.Subject = "Testing"
.HTMLBody = ...some html code which works...
'.Display()
.Send()
End With

objMail = Nothing
objOutlook = Nothing

Any ideas why I am getting this error? .Display() works perfectly when
not commented.

Also, is there a faster more efficient way of sending e-mail. Creating
an outlook object is slow!!!

-Ivan
 
F

Fergus Cooney

Hi Ivan,

Are you sure that Display() is having the problem? It should be on the
Send! I'm going to answer as if you had said Send. Forgive me if I'm wrong.

This is a bug in something or other, and I don't care which.

What it is, is that there are two candidates for your Send. Is it the
Outlook._MailItem Send that you refer to or is it the
Outlook.ItemEvents_Event.Send? What? you ask. Well, that's the bug. It's
getting confused. Interop wrappers or something.

Try this instead.
Dim objMail As _MailItem = etc.

If you were using Option Strict On, you'd need this horrendous thing
Dim objMail As _MailItem = DirectCast (objOutlook. CreateItem _
(OlItemType.olMailItem),
_MailItem)

Instead of creating a MailItem object, it creates an object which conforms
to the _MailItem Interface. And there's a difference. How were you supposed to
know that? Lol. Very good question! What am I talking about? Ask me if you
want to know. It's irrelevant otherwise (and too much to say, if so).

Now, is there a better way?

Well whenever anyone mentions mail here, we suggest having a look at the
SmtpMail and mailMessage classes.

Regards,
Fergus
 
I

Ivan Weiss

The .Display() did work perfectly, I put it in there for debugging
purposes to see if that works when I comment out .Send(). I appreciate
the correct reponse but I am not sure I am following your response. You
are saying by putting the _ (underscore) in front of MailItem it will
solve all my problems?

As much as I love the simplicity of that would you mind providing some
insight to what that actually is doing, or is there a better way to
accomplish what I am looking to do?

As far as the SMTP goes, does SMTPMail class provide a simple method for
sending e-mail through an Exchange server (which is obviously smtp
compliant) because if that is faster it is probably more efficient
resource wise also. Is that simple or should I just stick with my
Outlook VBA?

Thanks for the quick response Fergus!

-Ivan
 
I

Ivan Weiss

And I almost forgot one more question you pointed out, How was I or
anyone else supposed to know and/or figure that one out?

-Ivan
 
F

Fergus Cooney

Hi Ivan,

I'm afraid I can't say anything about using SmtpMail and Exchange Server.
Maybe post that as a separate question and/or do a Google search (do you know
how to Google these groups?)
http://www.google.co.uk/advanced_group_search?hl=en&scoring=d


But I <can> tell you more about why an '_' makes Send work.

Outlook contains MailItem which is the class that provides MailItems.
There's a surprise ;-) This MailItem class, like many complex classes is
inherited from a base class and also contracts to implement various
Interfaces. One of these interfaces is _MailItem and it's this one that
declares the Send method. Another interface is ItemEvents_Event and it
declares the Send event.

So when you have objMail.Send, the compiler finds that there's a choice of
two Sends and tells you that it doesn't know how to decide between them.

You have two choices. You can either tell it there and then which
particular Send you want by casting the MailItem to the appropriate Interface:
This effectively removes the other Interface and, with it, the ambiguity.
DirectCast (objMail, _MailItem).Send

Or, the one I suggested, you declared your objMail to be an Object which
conforms to the _MailItem Interface. This means that you can <only> access the
methods that belong to the _MailItem Interface. Even though the underlying
object is a full-on MailItem, you have chosen, with that declaration, to
restrict it. So objMail.Send is again unambiguous as the other Interface
hasn't even been allowed a look in.

In use it doesn't matter that you are limited to the _MailItem Interface
because that, as the name, suggests, defines most of the required
functionality.

Now, how were you supposed to figure it out? Well let's take out the
'supposed to' for a start, and change it to how <might> you have figured it
out? Because this is one of those thousands of times when you need enough of
the jigsaw already completed before you can fit the new pieces in.

The first clue is in the error message.
"Send" is ambiguous across the inherited interfaces
'Outlook._MailItem' and 'Outlook.ItemEvents_Event'

The wording is pretty ambiguous itself (spelled gobbledegook) until you
know what it means. But the key is 'interface'. If you've implemented or
studied or otherwise got familiar with Interfaces, you start to think, not
just in terms of Type, what an object <is>, but in terms of the portions of
what it <does>, ie. its Interfaces.

For instance, you can define a routine which adds passengers to an object
passed in. This object could be a Bus, Plane, an Elephant or an
InflatableBanana at the seaside. Obviously you can't have a class type common
to all these as they are so different. But you <can> have an Interface type
which is common to all of them. They must all implement IPassengerCarrier.

So inside your routine you are thinking in terms <only> of the methods
that belong to that Interface. The Trunk property of the Elephant is gone -
even when you have an actual Elephant object. The Wings collection of the
Plane is gone, etc. There's nothing allowed except the PassengerCarrierness.

So, back to the error message. That word 'interface' now tells you that
there is an Interface involved somewhere. And this suggests limiting your
objMailItem from what it <is> (MailItem) to the just the Interface mentioned
(_MailItem). Thus you try the DirectCast that I showed. Hey, it works!! But it
looks strange having this DirectCast in the middle of the code. The next
question is to wonder whether you can use the Interface when you <declare> the
variable - won't it lose some of the other methods? But you try it and Hey, it
works!!. So you stick with that because it's
a single-character solution - a more discreet way round the bug.

There, that how you might fix the problem. Like I say, it helps to have
all the bits in place. It also help, perhaps to have a read of:
http://support.microsoft.com/?kbid=315981

Regards,
Fergus
 
V

Versteijn

Also, is there a faster more efficient way of sending e-mail. Creating
an outlook object is slow!!!

-Ivan

Hi Ivan,

Sure there is. See the System.Web.Mail namespace.

Regards,
Freek Versteijn
 
I

Ivan Weiss

Hey everyone, I will try your suggestions later on and I am pretty sure
they will fix it. Thank you for your help, it is truly appreciated!

-Ivan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top