Prevent Outlook Adding unwanted Signatures repeatedly in VBA - vba

I want to prevent Outlook from Appending a Signature to any newly opened Outlook MailItem. When using Outlook.CreateItemFromTemplate(TemplateName) a default signature is automatically appended to the new MailItem. When working with multiple accounts attached to the Outlook Client that Signature is often unwanted, or is simply the wrong one. To make things worse, many Outlook Methods append further duplicate copies of the unwanted signature. It is possible to wind up with a whole slew of them attached.
When opening a Template, the Signature appended is the Default for the Account that was active when TemplateName was saved. It is not the Default for the currently active Account. One idea is to temporarily switch off the signature for the relevant Account and add the required Signature directly as this would be a fairly simple fix for the problem. Is there a way to switch off the signature for a specific account? I can't find one.
The signature for the Default account can be Switched off by setting
appWd.EmailOptions.EmailSignature.NewMessageSignature = vbNullString and it can also be restored later but this does not help. An idea for a possible workaround was to programattically change the default account, switch off the default account's signature, open the required TemplateName and then restore everything back to the original state. However, it doesn't work because:
a) I can't find a way to switch the Default Account programattically. It seems that this is only possible by clicking in the User Interface.
b) And it would make no difference, anyway, because the Signature for the
Account that saved TemplateName would be used despite the change.
Underlying this requirement is the fact that I need to merge parts of existing MailItems in Outlook using VBA. The objective is to merge parts of multiple items into a new MailItem for onward distribution to a mail list. The merging all works effectively using MailItem.GetInspector.WordEditor and I have sorted out the issues related to attachments and embedded pictures but the multiple Signatures, which would seem to be such a simple matter in comparison, are causing a problem. Is there way to switch them off? Getting rid of them in the WordEditor or in the HTML would be very difficult as Signatures have arbitrary structures.

Not the most elegant solution, but something like this should work.
Basically, store the HTML of the email prior to displaying, then compare it after it's shown and update the HTML if it's different.
Public Sub OutlookTest()
Dim Outlook As Object
Dim MyTemplateItem As Object
Dim OriginalBody As String
Set Outlook = CreateObject("Outlook.application")
Set MyTemplateItem = Outlook.CreateItemFromTemplate("C:\SomePath\Example.oft")
OriginalBody = MyTemplateItem.HTMLBody
MyTemplateItem.Display
If MyTemplateItem.HTMLBody <> OriginalBody Then MyTemplateItem.HTMLBody = OriginalBody
End Sub

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.

Delete default signature in Outlook and replace with content from doc/htm file

My workplace has introduced an draconian new uniform signature across the entire business which looks absolutely repulsive, and I can't in good conscience email clients without having to manually change it every single time.
I'm assuming it's being created via a macro that runs at start up. I'd like to set up a macro that I can activate from the ribbon that deletes the default signature that is in place when Outlook starts, and replace it with a new signature that is sourced (including formatting) from either a doc or a html file.
I've been searching for a couple of hours and can't find any macro code that either a) deletes a signature or b) allows for the creation of a new one by way of data from another file.
Can VB do what I'm looking for?
Many thanks in advance!
If you can't change the default signature for your e-mail account with the Outlook Options, take a look at
C:\Users\%username%\AppData\Roaming\Microsoft\Signatures
You will find the HTML files containing your signatures. Edit it directly...
Create a new signature, that way you only need to select it from a drop-down menu in the ribbon, and the policies that enforce the default will not see the custom one.

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.

Using the Addressbook in Outlook VBA

Someone at work asked me if I could implement an easy system for him to send out Outlook template-mails based on a few parameters he could enter.
An example would be a message like this:
"Hello,
Please be informed that system **Parameter1** is current down.
Regards,"
I was thinking about making a Form in Outlook VBA that would dynamically look for the amount of times a string styled like a parameter (e.g. ##parameters##) was found in a certain template and subsequently create a editbox in the form for each found parameter.
The problem is that I obviously would like to add an box for the recipients. I would need to find a way to make the call the Outlook Addressbook and make it behave like one. This was less intuitive than I had hoped. So far I have only managed to do the following:
Dim snd As Outlook.SelectNamesDialog
Dim displayLL As Boolean
Set snd = Application.Session.GetSelectNamesDialog()
snd.NumberOfRecipientSelectors = Outlook.OlRecipientSelectors.olShowTo
snd.AllowMultipleSelection = True
displayLL = snd.display()
As you can see, this only pops up the addressbook and allows me to select an few addresses. But I'm stumped on how I can actually make some fields that will actually act like the "To:" and "CC:" fields in a regular Outlook mail.
Not sure how relevant this is, considering I eventually took quite a different route, but I thought I'd still add this since no-one answered.
I simply created a form that would list all templates by searching through the templates folder in the %AppData%. I would then loop through the entire mail looking for parameter-styled strings and ask for the desired value each time I would encounter such a string (through a simply inputbox). Instead of adding a custom "recipients" box, I simply opened a new mail with the parameters filled out correctly.
The user could then simply add recipients to the mail like he usually would, and he was fine with this. That way, he was also able to double-check if the mail indeed looked exactly like he wanted to.
Nothing fancy or something that a 7-year old wouldn't be able to do, but it works.

Opening/Activating Word Documents in a VBA macro

I'm hoping a VB/VBA expert can help me out. Consider the following:
The user opens a document in Word 2003, and within the Normal.dot AutoOpen macro, we look at current document, and if it has been opened by clicking on a link on a webpage, and meets certain other application specific criteria, close the streamed 'copy' and open the source document (found on a shared drive we can assume the user has access to):
Documents.Open origDoc
Documents(ActiveDocument.FullName).Close SaveChanges:=wdDoNotSaveChanges
Documents(origDoc).Activate
With ActiveDocument
''# Do work
End With
My thought was that I needed to call Activate to ensure that the original document was the ActiveDocument, but I'm getting a 4160 'Bad file name' error on the .Activate call. If I comment out the call to .Activate, it appears that ActiveDocument is set to the origDoc document, even if there were other documents already opened (I'm not really sure how the Documents Collection is managed, and how Word determines what next ActiveDocument would be if you programatically close the current ActiveDocument)
So, does calling .Open on a document explicitly set the Document to be the ActiveDocument? Also, does calling .Activate on the already active document cause an error?
I haven't really been able to find much documentation about this, so thanks in advance for any suggestions and insight!
The simple answer is yes. By opening the document with your code you make it the active document, which you then close in the next line and try to activate in the next, and this fails because the document is no longer open. VBA in general seems to work this way.
It is important to be careful with ActiveDocument, because it's not always self-evident what actions, in code or elsewhere, will make a document 'active' (i have no proof but even an autosave might do it). IF there's any doubt you're better off referring to a document through the Documents collection, though this can also cause errors if the document is no longer open, and you might have to resort to iterating through the collection to be sure the document is, in fact, open. I run into this a lot with excel VBA, and Word VBA seems to function identically in that regard.
Also, VBA is flaky about releasing application objects. If you're not careful you'll end up with multiple WINWORD processes,viewable in task manager, regardless of whether you Close or Quit them in your code. The code I've found to work around this amounts to simulating the process of selecting END PROCESS in task manager. It works, but there should be a better solution.
Beware that there are a variety of problems that can be encountered:
if you want to re-open the document after closing it
once....Word/Windows DOES NOT
'release' the filename and you get a 'file busy' message, or message about 'creating
a temporary copy'.
to deal with this problem, I've had to develop an elaborate system of creating/saving and
tidying up multiple versions of any other documents I open/manipulate in my Word applications
because of this design flaw in Office Open/Close/Save methods.
Use the ReadOnlyRecommended property set to False with the
.Open method
referring to the document object (named doc, above) can cause
serious errors if you do not assure
that the doc object still exists before you try and manipulate it. Remember always, that
Word is an 'open' application platform....and the user can be doing things you didn't count
on...in the last millisecond or so. This advice holds for any other object or property you may
wish to manipulate in Word.
if you manipulate the Documents collection (or any other) without
assuring that the document or other object is still there and
valid before deleting or moving it within the collection you may
get 'stack overflow' errors. Particularly if you try and
close/delete objects in a collection starting at .item(1). You
must delete items in a collection from the last one, and remember
that the collection idicies and pointers change whenever you
.add/.remove/.close items from them.
You have an error here:
Document(origDoc).Activate
Should be Documents.
Yes, you can activate the active document. Nothing happens then.
Yes, opened document becomes active.
If you are not sure, use Documents.Open(origDoc).Activate.
You shouldn't be using the ActiveDocument object in the first place unless absolutely necessary because it's very unreliable. The preferred approach would be this:
Documents(ActiveDocument.FullName).Close SaveChanges:=wdDoNotSaveChanges
Dim doc as Document
Set doc = Documents.Open(origDoc)
With doc
'Do work
End With