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

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.

Related

Prevent Outlook Adding unwanted Signatures repeatedly in 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

Prevent Word macro in Normal.dotm for some templates

I have a Normal.dotm file that contains an AutoNew macro.
This macro is automatically executed each time a new document is created using any other template.
Is there any way I can prevent this automatic behavior for a specific template?
I have a Word VSTO add-in running, so I can hook into Word's events, but so far I havn't found a way to prevent this.
I do know that I can prevent macro execution when using templates programmatically, for example like this:
' Disable auto-macros before opening document
wordApplication.WordBasic.DisableAutoMacros(1)
' Open document
newWordDocument = wordApplication.Documents.Open(template.FullName, ConfirmConversions:=False, [ReadOnly]:=True, AddToRecentFiles:=False, Revert:=True)
' Re-enable auto-macros
wordApplication.WordBasic.DisableAutoMacros(0)
But this solution doesn't work when the user uses a Word template from Windows explorer or the Open-dialog in Word, since in those cases I can't execute code before it's too late already.
Or can I?
I hope someone has a trick for me :-)
-
Edit: While trying different solutions, I discovered something that might help others in similar situations, though unfortunately it doesn't help me.
It seems that if a template contains a module containing an AutoNew (or AutoOpen for that matter), that local macro is executed instead of the one in Normal.dotm.
Example:
Normal.dotm contains the following macro:
Sub AutoNew()
MsgBox "Normal.dotm"
End Sub
Test.dotm contains the following macro:
Sub AutoNew()
MsgBox "Test.dotm"
End Sub
When executing Test.dotm the message "Test.dotm" is displayed, while the message "Normal.dotm" is not displayed.
If the AutoNew macro is removed from the Test.dotm template, the message "Normal.dotm" is indeed displayed.
So it is possible to easily override the auto-macros.
The local versions of AutoNew and AutoOpen can even be empty subs that do nothing. It still works.
This is not possible in my case though, since the template I use is generated by code, and cannot contain macros (because adding macros to templates programmatically requires the user to manually activate the option "Trust access to the VBA project object model", and that's something I cannot ask my customers to do for all users. It's also a security risk.)
Based on the workaround described in the "Edit" part of the question - providing a template with "empty" Auto-macros - it's possible to use the Open XML SDK to create a template and add the VBA project to it in order to provide this functionality. This approach avoids the user needing to allow access to the VBA project on his installation. The only "macro security" that could be triggered is that for not allowing macros to run. But since the client uses macros, anyway, this should not be a major obstacle.
The simplest method is to create as much of the basic template as possible in the Word UI and use this as a starting point.
Since you're unfamiliar with the Open XML SDK, the next step would be to create one (or more) templates in the Word UI using the basic template as the starting point, saving under a different file name.
You can then use Open XML SDK Productivity Tool to see the code required to generate any one of these files, as well as, using the Compare tool, the code for converting the basic template to the derived version. This should give you a decent start with the SDK and it's object model. Once you get a feel for how the Open XML SDK works, if you're familiar with Word's object model, using that provided by the SDK is relatively straight-forward as an effort was made to make it correspond as closely as possible to the "COM" object model.
The VBA project can be added later, but you can also include it in the basic template. That would be the simplest approach.
Include this "starting point" basic template as part of your solution, installing it as part of the solution.
Within the AutoNew macro you can check the AttachedTemplate property. Only if it is a template where you want to apply the cleaning you can execute the respective macros.
Sub AutoNew()
If ActiveDocument.AttachedTemplate <> "Normal.dotm" Then
Exit Sub
End If
' rest of the macro
End Sub
If you don't control the Normal.dotm you can put an empty AutoNew macro in your own templates. As Word only executes the auto macro in the closest context, the macro in the Normal.dotm file would not be executed.
If you don't control the other templates either, you can tell your users to hold down the SHIFT key while creating a document. This prevents the execution of the auto macro.
Probably it is best, however, if you ask the owner of the other system to find another solution that does not rely on polluting the Normal.dotm file.

Add a Document_Open vba script to document when created from a template?

I have a template, Template.dotm, which is taken by a server and populated with data, then saved to a .doc. A user is then passed a link to this document so they can download it. I want to run a VBA script on that document when the user opens it.
Is there a way to accomplish this from within the template's vba script? The script of course runs fine if I simply double click the template to open an instance of it, but since the server saves a copy first, the script is gone by the time the user sees the document.
It turns out since the file was stored locally to the template but was being opened over the network, Word was confused and severed the connection to the template. I now have a copy of the template in a shared network drive, which I set to the attached template in Document_New.
Not the nicest solution, but it's working and was easy to implement. Thought I'd post for anyone who finds themselves in a similar situation.

Exclude template reference and macros from document

I am creating a template which has some macros inside. What the macros do is to open a user form which will prompt the user for some information which will then go into the new document.
The problem is that once the new document is created, it still somehow have a reference to this template and the macro code.
I have to send the document to people outside of the organization and they get a warning that the document contains macros.
Is there a way to avoid this? I want the document to be created without any of the macros or referrence to the original template.
Try creating the new document with "Normal" as a parameter for the Documents.Add method. The default seems to be to create a document off of the current open template (or Normal if none).

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.