Error reading Outlook HTML Body - vba

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.

Related

Changing Font Type of Messages in Outlook when double-clicking a .vbs file [duplicate]

This question already has an answer here:
How can I change the default font of Outlook 2016?
(1 answer)
Closed 3 months ago.
I have no experience nor any idea about VB scripts but I was tasked to create a .vbs file wherein when I double-click that file, it will automatically change the default font in Outlook 2016 to Montserrat. I've been picking up the pieces of whatever resource I could find online but it seems that the scripts I'm making do not change anything particular nor any message that it really ran successfully. I'm basically double-clicking the .vbs scripts I made and nothing happens. Below is what I had so far but I was told that that the .DefaultFont feature is not supported.
Sub ChangeFont()
Dim objOLApp
Dim NewTask
Set objOLApp = CreateObject("Outlook.Application")
Set NewTask = objOLApp.CreateItem(0)
with Newtask
.DefaultFont = "Montserrat"
End With
On Error GoTo 0
Set objOLApp = Nothing
Set NewTask = Nothing
END Sub
Basically what happens is when I run the script then open Outlook 2016, all the font configs will be set to Montserrat style like in the image below:
Is there any starting point anyone can recommend for this? Been stuck in this task for weeks. Thank you in advance.
I've already tried several code snippets I outsourced on the documentation and available resources online. Some kind-of makes sense to me but I'm not really sure how to match the pieces. I was expecting to create a .vbs file wherein when I double-click that file or open the file, the fonts of the running Outlook instance messages would change from the default font to Montserrat. I'm not really sure if this is possible but any help is highly appreciated.
First, in the code you are creating a new MailItem instance, not a task item like it was named.
Second, Outlook items like MailItem or TaskItem don't provide the DefaultFont property.
Third, I've already described possible ways of changing the font-related properties in Outlook. Check out your post - Automatically Change Default Font of Outlook 2016 using Visual Basic Script. In brief, you can use the HTML markup to specify a custom font or use the Word object model to deal with item bodies.
Fourth, you can find some Outlook settings in the Windows registry. So, to locate where exactly Outlook keeps Outlook settings I'd suggest using the Process Monitor utility, so you could do the required changes in the UI and track where they are saved.
You may also find similar questions posted over the internet, see Set Font Style and Size of email message called from VB.net.

How to keep executing code after a Documents.add in VBA (Word 2016)?

In our office we are currently using templates containing macro's. We are about to upgrade to Office 2016, but unfortunately the macro's don't work completely as they used to.
The current implentation is that a template is opened from a custom dialogue, and that a Document_New() is called in the template. This does not seem to work anymore: the Document_New() is only called when a template is opened from the file explorer, not when it's opened by a Documents.Add() in another macro.
Alternatively, I found a lot of solutions where Documents.Add is called, and then other functions are being invoked on that new document. For example
Set doc = Documents.Add(Template:=strSkeuze, NewTemplate:=True)
Call MsgBox(doc.Name)
In Word 2016 this doesn't seem to work. The MsgBox isn't invoked and when I step through the code in debugging mode, the code stops executing after the Documents.Add().
However I cannot find anywhere that this is a known change and I am looking for a workaround to still execute code, either from the template like with the Document_New() or from the parent Macro that opens the document.
Could someone tell me whether this is still possible and how to solve this?
You ought to be able to detect the added document using the Application's Document_New event, either that it fires (presuming that you have been using the Document's Document_New event) or by generating the event artificially by counting open documents on the first action taken after the document is added.

Outlook MailItem cache issue when saving in vb.net

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.

Word opens for real when trying to fill-in the blanks dynamically?

I'm currently using Word documents as templates where blanks have to be filled dynamically/programmatically in PwoerBuilder.
This has always worked fine until the company moves on Windows 7.
In short, the Word application is opened and made invisible.
Word.Application.Visible = false
Except that sometimes, and I don't know why, once the template is accessed, Word opens itself just as if I had double-clicked the template byself through the Explorer - but I didn't.
So, it asks whether I want to open it in read-only mode, since the application already has a handle on the file. And even if I click [Cancel] not to open the file, Word opens with no document, then the application crashes.
It reports PowerBuilder System Error 35.
Error Number 35.
Error text = Error calling external object function open at line 24 in function of_fusion of object n_cst_9999.
The external object that the application is trying to call a function against is Word.
oleobject lole_word
lole_word = create oleobject
lole_word = ConnectToNewObject("Word.Application")
lole_word.Documents.Open("templatefile.docx")
It may work for a few documents, and after a few, the problem comes up. This is the first time ever I meet with this issue.
I'll be glad to answer anyone's question who's trying to help.
Will, you may try setting DisplayAlerts and FeatureInstall properties on Word Application object.
That hid most of word alerts for us. (The code is from C# project and may not be exactly what you need)
Word.Application.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;
Word.Application.FeatureInstall = 0;
You may also try making a copy of the file before opening it to avoid accessing same .docx from different threads - if that may be the case.

How to determine if 'SaveChanges:=wdDoNotSaveChanges' was passed to Interop.Word.Document.Close()

I have an issue with an Office addin I'm working on, which is implemented for Office 2003 & 2007. The addin is written in VB.NET 3.5 using VSTO.
The problem comes from some external code which automates a mail merge, opening the mail merge template, merging and then closing the template document. The close is done with this code:
objWord.Documents(sDoco).Close SaveChanges:=wdDoNotSaveChanges, OriginalFormat:=wdPromptUser
Because of some logic in my addin, instigated from the Interop.Word.Application.DocumentBeforeClose event, a message box is opened which prevents the Office document from closing, which breaks the automation.
Is there a way for me to determine the SaveChanges parameter (if any) on a Close within an Office.Interop.Word.Application event, such as DocumentBeforeClose? I'm trying to capture this parameter and determine if it's set to wdDoNotSaveChanges so that I can work around this problem.
I'm pretty sure you get the DocumentSave event BEFORE the DocumentBeforeClose, so set a flag in it, and if that flag is set at close, you know the doc has been saved, but if not, it was not. I've had to do similar things to know whether a Document was SAVED-AS vs just SAVED.
I'm not aware of any way to interrogate the state of that parameter from DocumentBeforeClose.