We have a small macro (added to the ribbon) which on click is supposed to attach some files from a certain folder.
This works, when creating a "new" Mail from within Outlook. When you use (for example) Adobe Acrobats "send as email" Function, the email in Outlook is opened as modal dialog.
The button on the ribbon now has no effect. It simple does nothing. (Not even a MessageBox in the first line would be displayed)
Using Developer Tools -> Macros and selecting the macro from "there" works.
Why isn't the button on the ribbon, calling the very same macro NOT working with modal emails?
the macro - but as mentioned not even a MessageBox would appear.
Sub AddAttachments()
Dim Path As String
Path = "C:\test\"
Dim NewMail As MailItem, oInspector As Inspector
Set oInspector = Application.ActiveInspector
If oInspector Is Nothing Then
MsgBox "No active inspector"
Else
Set NewMail = oInspector.CurrentItem
If NewMail.Sent Then
MsgBox "This is not an editable email"
Else
With NewMail
d = Dir(Path & "*.*")
While d <> ""
.Attachments.Add Path & d
d = Dir
Wend
End With
End If
End If
End Sub
Update:
With another application offering more settings for the email-sending application, I was able to figure the following out:
When using "Outlook OLE" als Email-Sending Method, everything works as expected.
When using "MAPI" as Email-Sending Method, the effect mentioned above appears.
So, Adobe Acrobat seems to use (Simple) MAPI by default.
Edit: After knowing the actual cause, I found this: https://www.msoutlook.info/question/203 - Seems to be a known, not solvable limitation for Applications creating their emails through MAPI because Outlook is not loaded "fully" but just some basic stub.
Update:
When clicking on the "Send as mail Button" (1) the following Window appears. Clicking on the "Macro-Button" inside the ribbon (2) does nothing.
Switching to DeveloperTools, Selecting "Macros" and selecting the same Macro from there however works:
The Button on the other hand works for "New Emails" created via Outlook and "New Mails" created by using Outlook OLE rathen than MAPI.
Okay, to summarize the problem and the missing solution:
I was in touch with the support of various applications showing this problem and they confirmed, that this problem is caused by using MAPI as entrypoint.
For Example, "PDF24" allows you to specify wheter it should use MAPI or Outlook OLE: Choosing MAPI results in the same problem, while choosing Outlook OLE makes VBA-Macros work...
I also noted, that the Addin responsible for processing VBA-Scripts (Microsoft.VbaAddinForOutlook) is not loaded, when Outlook is triggered using MAPI:
The Eventlog (Application) shows that several Addins are loaded during startup:
Outlook loaded the following add-in(s):
Name: Microsoft Exchange Add-in
Description: Exchange support for Unified Messaging, e-mail permission rules, and calendar availability.
ProgID: UmOutlookAddin.FormRegionAddin
GUID: {F959DBBB-3867-41F2-8E5F-3B8BEFAA81B3}
Load Behavior: 3
HKLM: 1
Location: C:\Program Files (x86)\Microsoft Office\Root\Office16\ADDINS\UmOutlookAddin.dll
Boot Time (Milliseconds): 0
Name: Outlook Social Connector 2016
Description: Connects to social networking sites and provides people, activity, and status information.
ProgID: OscAddin.Connect
GUID: {2163EB1F-3FD9-4212-A41F-81D1F933597F}
Load Behavior: 3
HKLM: 1
Location: C:\Program Files (x86)\Microsoft Office\Root\Office16\SOCIALCONNECTOR.DLL
Boot Time (Milliseconds): 0
...
But the VBA-Addin is only loaded, when "clicking" on the macro-button for the first time, because it's LoadBehavior: 9 rather than LoadBehavior: 3:
(This event appears "onclick"):
Name: Microsoft VBA for Outlook Addin
Description:
ProgID: Microsoft.VbaAddinForOutlook.1
GUID: {799ED9EA-FB5E-11D1-B7D6-00C04FC2AAE2}
Load Behavior: 9
HKLM: 1
Location: C:\Program Files (x86)\Microsoft Office\Root\Office16\ADDINS\OUTLVBA.DLL
Boot Time (Milliseconds): 0
(The event is completly missing, when the Window is created through a MAPI-Call)
I managed to "fake" a Entry in the Registry in order to load the Addin right away:
[HCU\SOFTWARE\Microsoft\Office\Outlook\Addins\Microsoft.VbaAddinForOutlook.1]
"LoadBehavior"=dword:00000003
Which indeed made the Addin load during Outlook-Startup - but without the desired impact of having VB-Macros working in MAPI-generated Email-Windows.
Name: Microsoft VBA for Outlook Addin
Description:
ProgID: Microsoft.VbaAddinForOutlook.1
GUID: {799ED9EA-FB5E-11D1-B7D6-00C04FC2AAE2}
Load Behavior: 3
HKLM: 1
Location: C:\Program Files (x86)\Microsoft Office\Root\Office16\ADDINS\OUTLVBA.DLL
Boot Time (Milliseconds): 0
But maybe "this" might be a good starting point for somebody facing the same Problem and seeking for a solution.
Related
I'm hoping someone on here can point me in the right direction with some expertise. I have a situation with a client's outlook where we need to close any open draft windows after a new message/draft is opened. Ideally after the 4th new window has opened.
Any "new message" window that opens after this we need the script to close 1st window that opened. Either killing the process, or something similar.
Recently have been looking into Outlook macros, but am unsure if they will help in this instance. (Maybe they are?). Being more familiar with Powershell, figured we could start there.
Looking to get help writing a powershell script, macro, etc to do this on the backend.
The Outlook object model provides all the required events, methods and properties for that. So, VBA macros is the right choice if you don't need to distribute the solution on multiple machines. Otherwise, you need to consider developing a COM add-in instead (for example, a VSTO based one should work for you). See Walkthrough: Create your first VSTO Add-in for Outlook for more information.
You can handle the NewInspector event which is fired whenever a new inspector window is opened, either as a result of user action or through program code. The event occurs after the new Inspector object is created but before the inspector window appears.
You can also check the number of opened inspector windows in Outlook by using the Inspectors.Count property which returns a long indicating the count of objects in the specified collection.
Finally, the Inspector.Close method closes the Inspector and optionally saves changes to the displayed Outlook item. For example, a VBA sample which closes the active inspector instance:
Sub CloseItem()
Dim myinspector As Outlook.Inspector
Dim myItem As Outlook.MailItem
Set myinspector = Application.ActiveInspector
Set myItem = myinspector.CurrentItem
myItem.Close olSave
End Sub
I'm getting error 438 : object doesn't support this property or methodwhen I am trying to run the macro on a new machine:
Set HTMLdoc = New MSHTML.HTMLDocument
With HTMLdoc
.body.innerHTML = OutlookMail.HTMLBody **'******** Error Line**
Set tables = .getElementsByTagName("table")
End With
Yes it is working fine in my system. But when I tried to install this in new system, it creates this error.
No changes in the code, I am running the same excel macro file on some outllok mails.
Even the outlook mails which I used for testing, i am using the same files in the new machine.
Also, the Tool>>Reference libraries, I have checked all the Items like MS HTML object library, MS Outlook 16.0 Object library and other default checkboxes are maintained same in the system.
The code abruptly breaks when it reaches this line :
. Body. Innerhtml = Outlookmail. HTMLBody
.body.innerHTML = OutlookMail.HTMLBody
The inner HTML markup of the body doesn't equal to the HTML markup of the Outlook's message body. It includes other outer html markup that should be removed before.
Anyway, VBA macros are not designed for distributing them on multiple machines. That is exactly COM add-ins were introduced for. In that case you will be able to create an installer for your solution to get it deployed automatically for all users. Moreover, you will be able to check and install (if needed) the required prerequisites at the installation time. See Walkthrough: Create your first VSTO Add-in for Outlook to get started quickly.
We have a vb.net windows application that creates an instance of Outlook.Application to open an email .MSG file, and save it as a .HTML by calling the Outlook.Application SaveAs() method.
However, sometimes the call to .SaveAs() causes a popup to appear, for example when saving a .MSG that is digitally signed, there is a confirmation popup.
This popup causes the code execution to halt until the user interacts and clicks YES or NO on the pop up. Since our application runs on a server and requires no user interaction this causes the application to halt periodically until a technician logs into the server and clicks 'yes' on the popup.
Is there a way to avoid this pop up, or have 'YES' automatically get selected?
I've tried investigating the documentation for Outlook.Application but of course the documentation is very lacking on MSDN.
Here is some example vb.net code:
outlookapp = CreateObject("Outlook.Application")
Dim olItem As Object = outlookapp.CreateItemFromTemplate("C:\msg\message.msg")
olItem.SaveAs("C:\html\convertedmessage.html", 5)
If message.msg is digitally signed, when calling SaveAs() to save it as an HTML file, you get a pop up that the MSG is digitally signed, this halts the code until you click yes or no.
Note: Outlook objects do not support the DisplayAlerts flag of Word objects.
Firstly, Outlook is not designed to be used in a service or a server side application with no user present.
In your particular case, you can do the following:
1 Use Extended MAPI (C++ or Delphi only) to open the MSG file (OpenIMsgOnIStg etc.), then construct the HTML file explicitly in your code.
2 Parse the MSG file (its format is documented) or use one of several commercial components (such as the one from Aspose) to read the MSG files.
3 Use Redemption (I am its author) and its RDOSession.GetMessageFromMsgFile / RDOMail.SaveAs(..., olHTML) methods to open the MSG file and perform the conversion.
dim Session As RDOSession = CreateObject("Redemption.RDOSession")
dim Msg As RDOMail = Session.GetMessageFromMsgFile("C:\msg\message.msg")
Msg.SaveAs("C:\html\convertedmessage.html", 5)
I have a macros that starts running when a document opens. It looks like this:
Private Sub Document_Open()
....
Dim strInput As String
strInput = ActiveDocument.Content
....
In office 2010 this macros works nicely, however, in office 2013 I get this error message (translation to English):
This command is not available, because there are no documents opened
And when I hit on Debug button, I see that this line of code is highligthed:
strInput = ActiveDocument.Content
I think it's a bug of office 2013, because for some insane reason it invokes this macros before the document is opened, even though I clearly force it to do right after opening - Private Sub Document_Open(). So, what is wrong with that and how can I fix that?
If you're seeing the yellow message bar then this isn't a bug. It's because your document isn't "trusted" - it's "sandboxed". You need to check whether it's a ProtectedViewWindow - introduced in Office 2010 - and take appropriate action.
The Protected View is explained in this article: https://support.office.com/en-us/article/What-is-Protected-View-d6f09ac7-e6b9-4495-8e43-2bbcdbcb6653. Basically, it prevents code from running in any document that comes from an origin / author that isn't trusted. The user needs to make an explicit decision to trust the document in order to go into Edit mode.
Obviously, this is a major impediment to VBA code, so you have the ProtectedViewWindow object in the object model. There are application-level events that can be used to manage this state in the entire Word environment, such as ProtectedViewWindowOpen that triggers when a document is opened "sandboxed". After determining whether the document is trustworthy, the code can make the document editable using the ProtectedViewWindow.Edit method.
For example, to trust all documents that come from a specific file path:
Private Sub app_ProtectedViewWindowOpen(ByVal PvWindow _
As ProtectedViewWindow)
If PvWindow.SourcePath = "C:\Test" Then
PvWindow.Edit
End If
End Sub
The above needs to be in an application-level class module and events for this class need to be active on the application. If you're not familiar with using application-level events, see https://msdn.microsoft.com/en-us/library/office/ff821218.aspx
I have a small WinForms program that allows my users to create email blasts for our clients. The app has two options: one is an HTML editor to design the email (works great) and the second is to import .msg or .oft template.
Once the email is complete it is moved to a shared outlook mailing folder for a nightly macro send job.
Pretty simple stuff!
The problem: Once the template is open in the application outlook seems cache that version. If the user decided to get out make a change in the template Outlook doesn't pick up the update.
Note: If the users clicks on the "Preview" button they received the correct UPDATED version in their inbox. But when they submit the MailItem it picks up the old version.
Dim newItem as Outlook.MailItem = gobjOutlook.CreateItemFromTemplate(fileEmailTemplate.FileName)
The send command works fine newItem.Send()
But when I move it to the shared folder it gets the original version from somewhere.
Dim addFldr As Outlook.MAPIFolder
addFldr = StoreFLDR.Folders.Add(gobjNamespace.CurrentUser.Name & ": " & DateTime.Now.ToString())
newItem.Save()
newItem.Move(addFldr )
I have tried forcing the GC and SaveAs to another location and reload the template, no luck.
I'd suggest starting from releasing underlying COM objects instantly. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object.
You may find the How To: Create a new Outlook message based on a template article helpful. Anyway, it would be great to see your full source code related to Outlook.