Office 365 Protected View Breaking Excel Marcos - vba

Our client has updated to Microsoft Office 365 (Version 1708) and when receiving a generated Excel file (xlt) via email which contains a vb macro, it now displays "PROTECTED VIEW Be careful - email attachments can contain viruses. Unless you need to edit, it's safer to stay in Protected View." - and doesn't run the macro (of course).
Clicking the "Enable Editing" the user gets a runtime error, but in Office 2013 it works fine.
Also in Office 365 if we untick "Enable Protected View for Outlook attachments" and resend the file, it works okay.
Any ideas?
Cheers,
Steve

After many hours of hacking and googling, we found that this is an existing bug in Office 365.
A workable workaround for us was to change:
Private Sub Workbook_Open()
Call formatData
End Sub
To:
Private Sub Workbook_Activate()
Call formatData
End Sub

Related

Why did application.reminder stop working?

Using Outlook 365.
I needed code to bring Outlook reminders to the front of all other windows. I found this code on the Extend Office website, and entered it into the ThisOutlookSession module:
Private Sub Application_Reminder(ByVal Item As Object)
'Updated by ExtendOffice 20180814
Dim xAppointment As AppointmentItem
If Item.Class = olAppointment Then
Set xAppointment = Item
MsgBox xAppointment.Subject, 4096 + vbInformation + vbOKOnly, "Outlook reminders"
End If
End Sub
Last week, it worked fine; whenever a reminder fired, I'd see a Msgbox reiterate its message.
This week, I realized that the Msgbox was no longer popping up. I believe my computer had restarted over the weekend, but that's the only change I can think of. I've tried trapping the code with breakpoints, and as near as I can tell, it's just not running.
I'm not familiar with "ThisOutlookSession", but just to be safe I tried restarting Outlook, and it didn't help. I use two different Desktops in Windows, and I tried running Outlook on each, but that didn't seem to matter.
First of all, you need to check the Trust Center settings in Outlook whether VBA macros are allowed to run. Then try to enable macros in Outlook by following:
"File"->"Options"->"Trust Center"->"Trust Center Settings..."->"Macro Settings"->"Enable all macros"
You may find similar issues posted in the Outlook Not Running Visual Basic After Restart and VB Macro runs successfully at first, but fails after Outlook restart posts.

Launch Userform when Outlook Template is opened

I have a User Access Request form that I created in Word, and have now been asked to replicate in an outlook email template. This .oft file will be placed on our website, so that when users click on the link, they will download the .oft file. When the user opens the file, an email with the User Access Request form in the body will load.
I was able to set up the bookmarks, and import the Userform from Word, and have even gotten everything to populate correctly in the email from the Userform...however I have hit a wall.
I can only get the Userform to appear when I run it from Visual Basic in the Developer tab.
What I am looking to do is have the Userform pop up as soon as the template is opened, and only when that specific template is opened by a user (I don't want the Userform to open if they are trying to create a new email, or when they open outlook, etc). I have tried adding a module with the Userform.show code, I have tried adding the code below into the UserForm's code as well, with no luck.
Private Sub UserForm_Activate()
UserForm1.Show
End Sub
Do you have any suggestions as to how I can get this to work properly?
Thanks in advance!
You will need your custom logic to be present on every user's PC in order for this to work. Since you have created a UserForm in your Outlook VBA project, you will need to copy that form and supporting macros to every user's Outlook VBA project.
Often it is better to develop a COM Add-in to host your logic, and deploy it using a Windows Installer package. Deploying the .otm file where the VBA is stored is not supported.
Looks like I was able to get it to work. I added the following code:
Private Sub Application_ItemLoad(ByVal Item As Object)
R1AccessRequest.Show vbModeless
End Sub
Worked beautifully... until I sent the template over to a colleague to test... Userform appears to be tied to my outlook, and didn't appear for him. We opened up VB on his laptop, and saw that the form was not present :( From what I have been able to gather online, it doesn't seem possible.

macros on document open. Bug in ms office 2013?

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

Application.OnTime in Add-In Workbook_Open

I've built a custom Excel add-in and I'm currently trying to figure out a way to prompt users via VBA when new versions of the add-in are available.
I tried just using the workbook_open event to check for the latest version and then prompt the user with a userform, but I discovered that when Excel loads an add-in that trigger a userform, Excel stops loading the workbook the user actually tried to open and reloads the add-in. So while the userform works like I wanted, the user gets a blank (read no sheets) Excel shell with a loaded add-in.
So I considered using Application.OnTime to postpone the VBA until after the add-in and target file were both open. I got the impression both here and here that this is possible, but I am only able to make it work in an .xlsm file and not a .xlam file.
Here's the code I'm testing with:
Sub Workbook_Open()
Application.OnTime Now() + TimeValue("00:00:05"), "Test_Addin.xlam!Versioning.Notify_User"
End Sub
And in a regular code module:
Sub Notify_User()
MsgBox "Hello"
End Sub
So, my question: Am I doing something wrong here?
I'm wondering if there's something about how an add-in is loaded/designed that keeps it from allowing this type of action to be performed.
Alternatively, is there a different way to do this that you can think of?
I read an interesting blog post (and comments) by Dick Kusleika on this topic, but it sounded like some people put a version check in each sub procedure... I have a lot of procedures, so this doesn't sound like a good alternative, although I may have to resort to it.
Well, time is of the essence so I resorted to the least desirable option: a check at the beginning of each procedure.
To the interested parties, here's how I did it:
Somewhere towards the beginning of each sub procedure I put this line of code:
If Version_Check Then Call Notify_User
And in my Versioning module I put this function and procedure:
Function Version_Check() As Boolean
Installed = FileDateTime(ThisWorkbook.FullName)
Available = FileDateTime("\\NetworkDrive\Test_AddIn.xlam")
If Installed < Available Then Version_Check = True
End Function
Sub Notify_User()
Update_Check.Show
End Sub
So each time a procedure is run this code checks for a version on our corporate network with a modified datetime greater than the datetime of the installed add-in.
I'm still very open to alternative ways of checking for new versions so feel free to post an answer.

How to add MS outlook reminders event handlers with VBA

I want to extend MS Outlook so that when a calendar reminder pops up, I can run a VBA hook that can run an external program (like a batch script). In my case, I want to "forward" the reminder to a Linux desktop since I work in both environments and I don't always have the Windows desktop visible.
I see an example at http://office.microsoft.com/en-us/outlook-help/HV080803406.aspx and have opened VBA Developer view in MS outlook 2010 and inserted a class module and added that VBA code, but I do not see how to activate this code - when a reminder pops up, this code is not activated.
Update
Here is what I ended up adding to Outlook's ThisOutlookSession to run an external batch script when a reminder pops up.
Public WithEvents objReminders As Outlook.Reminders
Private Sub Application_Startup()
Set objReminders = Application.Reminders
End Sub
Private Sub objReminders_ReminderFire(ByVal ReminderObject As Reminder)
Cmd = "C:\path\to\my\reminder-hook.cmd" & " " & ReminderObject.Caption
Call Shell(Cmd, vbHide)
End Sub
Put it in the "ThisOutlookSession" module and restart Outlook.
Also, ensure that macros are enabled in Outlook settings.