Wysyłanie wiadomości e-mail programu Outlook za pomocą Delphi

Oct 05 2020

Mogę pomyślnie wysłać wiadomość e-mail przez OLE między Delphi 10.4 a Outlook 365.

try
  Outlook:=GetActiveOleObject('Outlook.Application');
except
  Outlook:=CreateOleObject('Outlook.Application');
end;

try
  MailItem:= Outlook.CreateItem(olMailItem) ;

  SubjectLine:= 'Whatver';
  MailItem.Subject:= SubjectLine;

  EmailTo:= '[email protected]';
  MailItem.Recipients.Add(EmailTo);

  MailItem.BodyFormat := olFormatPlain;
  MailItem.GetInspector;

  Attachment:= 'C:\File.doc';
  MailItem.Attachments.Add(Attachment);

  MessageBodyStr:= 'Dear Friend';
  MailItem.Body:= MessageBodyStr;

  MailItem.Display(False);

finally
  Outlook := Unassigned;
end;

To działa dobrze. Ale wolałbym wysłać wiadomość e-mail bezpośrednio, bez wyświetlania edytora wiadomości e-mail

Kiedy tego używam

MailItem.Send;

rozumiem

EOleSysError: The parameter is incorrect

Co jest nie tak ? Jak mogę pominąć edytor i po prostu wysłać e-mail? Jakieś sugestie ?

Dzięki

Odpowiedzi

2 fiveloop Oct 15 2020 at 19:26

Dzisiaj może być twój szczęśliwy dzień, Bob!

Utrzymuję aplikację, która używa Outlook Object Model do wysyłania e-maili. Kod do wysyłania wiadomości e-mail pozostaje niezmieniony od kilku lat, a tysiące użytkowników z powodzeniem z niego korzysta.

W ciągu ostatnich kilku tygodni niektórzy z tych użytkowników zaktualizowali Office 365 do najnowszych wersji i zaczęli napotykać dokładnie ten sam błąd „Parametr jest nieprawidłowy” po wywołaniu MailItem.Send. Wszyscy ci użytkownicy mieli te same cechy wspólne:

  1. Zrobili NIE zaktualizować naszej aplikacji (są one nadal pracuje w tej samej wersji, że było dobrze pracuje od lat)
  2. Oni DID uaktualnić Office 365.

Biorąc pod uwagę te dwa punkty powyżej, nie trzeba naukowca zajmującego się rakietami, aby stwierdzić, że Microsoft musiał coś zmienić w najnowszych wersjach Office 365 i ta zmiana powoduje ten błąd.

Otworzyłem sprawę z zespołem pomocy technicznej Microsoft Office 365 i, jak można się było spodziewać, sprawa krążyła w kółko, a Microsoft nie zapewniał żadnego rozwiązania.

Głupią rzeczą w komunikacie o błędzie „Parametr jest nieprawidłowy” jest to, że MailItem.Send nie przyjmuje żadnych parametrów!

W każdym razie zrezygnowałem z zespołu wsparcia Microsoft Office 365 i zacząłem majstrować przy kodzie, który nie był zmieniany od wielu lat.

Po wielu próbach odkryłem, że z jakiegoś nieznanego i nieudokumentowanego powodu wywołanie MailItem.GetInspector wydaje się powodować kolejne wywołanie MailItem.Send, aby zgłosić błąd. Kiedy skomentowałem MailItem.GetInspector, MailItem.Send działał idealnie i nie zgłosił błędu.

Ale dla mnie komentowanie MailItem.GetInspector nie jest długoterminową opcją, ponieważ używam Inspectora do wykonywania kilku operacji na treści wiadomości e-mail.

Przeczytałem więc dokumentację obiektu Inspector i znalazłem metodę Close. Dodałem wywołanie do Inspector.Close po manipulowaniu treścią wiadomości e-mail i przed wywołaniem MailItem.Send. Bingo! To naprawiło błąd !!!!

Oto przykładowy kod VBA, który działa. Przetestowałem to w Excelu.

Sub TestSendEmail()
    Dim app As Outlook.Application
    Dim nameSpace As Outlook.nameSpace
    Dim folder As Outlook.MAPIFolder
    Dim mailItem As Outlook.mailItem
    Dim insp As Outlook.Inspector
    Dim wordDocumentEditor As Word.Document
    
    On Error GoTo errorHandler
    Set app = New Outlook.Application
    Set nameSpace = app.GetNameSpace("MAPI")
    Set folder = nameSpace.GetDefaultFolder(Outlook.olFolderOutbox)
    Set mailItem = app.CreateItem(Outlook.olMailItem)
    mailItem.Subject = "Test Subject"
    mailItem.To = "[email protected]"
    Set insp = mailItem.GetInspector
    Set wordDocumentEditor = insp.WordEditor
    wordDocumentEditor.Range(0, 0).InsertBefore ("Test Body")
    insp.Close (olSave)
    MsgBox "Calling Send"
    mailItem.Send
    MsgBox "Send Complete"
Done:
    Exit Sub
errorHandler:
    MsgBox "The following error occurred: " & Err.Number & ": " & Err.Description
End Sub

Bob, proszę o odpowiedź i daj mi znać, czy Inspector.Close naprawił błąd.