Debugging an Outlook 2007 script fired by a rule - vba

I'm trying to debug an Outlook 2007 VBA script that's fired by a rule. I've set a breakpoint in the script but it doesn't get hit.
The script is actually a Sub in the ThisOutlookSession object.
When I run the rule on a specified folder nothing seems to happen.
What am I doing wrong?
Update:
I've added a MsgBox "Processing: " & mailItem.Subject to the script and that pops up just fine when I run the rule. However I can't seem to get the script to stop on breakpoints.

I think you may not be doing anything wrong, because I have experienced exactly the same behaviour.
However, in order to debug your VBA, I suggest that you create a macro (via the Tools|Macro|Macros menu) that calls your script function with a test e-mail item that you create in the macro.
Maybe something like this:
Sub TestScript()
Dim testMail As MailItem
Set testMail = Application.CreateItem(olMailItem)
testMail.Subject = "Test subject"
testMail.Body = "Test body"
Project1.ThisOutlookSession.YourScriptForDebugging testMail
End Sub
This way you can "Step Into" the macro via that Macro dialog again, and do all the debugging you need. It solved my problem, anyway.

Any existing item can be used to test code that requires one.
Sub passOpenItem()
'first open an item
codeRequiringItemParameter ActiveInspector.CurrentItem
End Sub
Sub passSeletion()
'first select an item
codeRequiringItemParameter ActiveExplorer.Selection(1)
End Sub
Sub codeRequiringItemParameter(itm As Object)
Debug.Print "TypeName: " & TypeName(itm)
Debug.Print "Class...: " & itm.Class
End Sub

Related

Custom Outlook Macro only runs in VBA editor

I've created a Macro based on a blog post that only successfully runs in the VBA editor. When I run it from Outlook itself, nothing happens. Maybe you can see something obvious that I'm missing.
Pressed Alt+F11 to open the editor.
Named the module and pasted in the code.
Compiled and run. The e-mail in question opened in HTML-format as expected.
Closed the editor and added the button to the toolbar I wanted. Nothing happens.
Returned to the VBA editor and run the code. It works as expected.
Closed and re-opened Outlook to try the button again. Nothing happens.
Here's the code, with a screenshot of the code in the editor to follow.
Sub ReplyInHtmlFormat()
Dim olSel As Selection
Dim oMail As MailItem
Dim oReply As MailItem
Set olSel = Application.ActiveExplorer.Selection
Set oMail = olSel.Item(1)
If oMail.BodyFormat = olFormatPlain Or olFormatRichText Or olFormatUnspecified Then
oMail.BodyFormat = olFormatHTML
oMail.Save
End If
Set oReply = oMail.Reply
oReply.Display
Set olSel = Nothing
Set oMail = Nothing
Set oReply = Nothing
End Sub
You may want to check the macro permissions to make sure it is allowed to run. I hope that helps! ;-)
Try to add MsgBox statement outside of any If statement and you will be able to understand whether it is actually running or not when you click a button added to the toolbar.
Also, I'd recommend adding an error-handling routine to the function:
Public Sub OnErrorDemo()
On Error GoTo ErrorHandler ' Enable error-handling routine.
Dim x, y, z As Integer
x = 50
y = 0
z = x / y ' Divide by ZERO Error Raises
ErrorHandler: ' Error-handling routine.
Select Case Err.Number ' Evaluate error number.
Case 10 ' Divide by zero error
MsgBox ("You attempted to divide by zero!")
Case Else
MsgBox "UNKNOWN ERROR - Error# " & Err.Number & " : " & Err.Description
End Select
Resume Next
End Sub
So, you will be aware of any issues if any.

Application_Startup() not firing

I've code in the "ThisOutlookSession" module.
Application_ItemSend works, events are triggered when sending mail.
Application_Startup runs when I initiate it manually after Outlook has been opened - not upon startup.
Making the sub private makes no difference - neither does making the variables public.
I have macro settings on "Enable all macros" in the Trust Center.
I'm on Outlook 2016 on a PC running Windows 10 Enterprise.
I have researched the issue intensively.
Option Explicit
Dim add_str As String
Public Sub Application_Startup()
Dim olNs As Outlook.NameSpace
Dim Folder As Outlook.MAPIFolder
Dim SubFolder As Outlook.MAPIFolder
Dim Item As Object
Set olNs = Application.GetNamespace("MAPI")
Set Folder = olNs.Folders("albrobin#workmail.com").Folders("WORKFLOW").Folders("Reporting")
For Each SubFolder In Folder.Folders
If SubFolder.items.Restrict("[UnRead] = True").Count > 0 Then
For Each Item In SubFolder.items
Item.UnRead = False
Next
End If
Next
End Sub
Public Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
If TypeName(Item) <> "MailItem" Then
Exit Sub
End If
If Item.Subject Like "RE: *" _
Or Item.Subject Like "AW: *" _
Or Item.Subject Like "FW: *" Then
Exit Sub
End If
UserForm1.Show
If add_str = "[URGENT] " Then
Item.Importance = olImportanceHigh
End If
Item.Subject = add_str & Item.Subject
add_str = vbNullString
End Sub
Public Sub routine(str_ As String)
add_str = Replace(str_, vbCrLf, " ")
add_str = "[" & add_str & "] "
End Sub
Sub show_form1()
UserForm1.Show
End Sub
I tested your code and I’ve ran into the same problem.
I have solved this problem by restarting my PC and adding the Public Sub Application_Quit() method.
There seems to be a flag in outlook which checks for VBA code. If it can't find any it sets the registry value (HKEY_CURRENT_USER\Software\Microsoft\Office\XX.0\Outlook\LoadMacroProviderOnBoot) to 0 every time it closes. It doesn't seem to be setup so that it detects when code is added by copying the OTM file.
I have discovered 2 scenarios (there may be more) which cause the flag to be set causing outlook to change the registry value to 1 on close.
If any macro is run
The visual basic editor is opened.
The issue arose in my situation when I try to roll out the VBA code to a new PC with no existing VBA code.
I use a batch script to roll out my VBA code to other machines and to fix it I simply added a REG ADD command to the bat file after the code is copied to the machine which sets the key to 1.
REG ADD HKCU\Software\Microsoft\Office\XX.0\Outlook /v LoadMacroProviderOnBoot /t REG_DWORD /d 1 /f
You need to change “XX.0” to the version of office you are dealing with. Check the registry to find out.
This seems to force Outlook to check for VBA code when it starts.
(Thanks to Sergik718 on Microsoft TechNet forums for pointing out that changing this registry entry helps.)
Was experiencing same problem with Application_Startup() procedure not firing after a system reload and restore of my VBAProject. Checked macro settings, digitally signed the project - no luck. Received no button to Enable VBA during startup, like in Office 2010. VBA would function, but required me to manually fire the Application_Startup() procedure.
Tried creating a new, temporary "Private Application_Startup()" procedure, but no joy.
I deleted "Public" statement that preceded the Application_Startup() declaration. Saved, closed VBA and Outlook. Re-opened and suddenly it started working. Have restored the "Public", saved, re-opened, and it now seems to work properly. No explanation.
Had a similar problem. Application_Startup didn't trigger on restarting Outlook and hence my changes in the function didn't load. The reason Application_Startup didn't trigger was because I had another program holding a reference open to Outlook

Activate specific URL contained in an email message

I know virtually nothing about VBA but am attempting to learn. I am trying to assist a blind client who gets messages from a specific agency he uses to get freelance engagements. These messages have to be responded to almost instantly by clicking on an "Accept" link in the message or there is no chance of getting the job. Since he uses a screen reader this complicates matters.
I have tried to adapt what I've found at stackoverflow to take the message on receipt, triggered by a message rule, to invoke VBA code to dig out the URL and immediately activate it.
Sub LaunchURL(itm As MailItem)
Dim MsgBody As String
Dim AllMsgLines
Dim IndividualLine
Dim AllLineWords
Dim SingleWord
Dim MboxReply
MsgBody = itm.Body
AllMsgLines = Split(MsgBody, vbCrLf)
For Each IndividualLine In AllMsgLines
AllLineWords = Split(IndividualLine, " ")
For Each SingleWord In AllLineWords
If SingleWord Like "http://*" Then
MboxReply = MessageBox.Show("I've found a URL", "LaunchURL Script", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk)
Set itm = Nothing
Exit Sub
End If
Next SingleWord
Next IndividualLine
Set itm = Nothing
End Sub
Private Sub TestLaunchURL()
Dim currItem As MailItem
Set currItem = ActiveInspector.CurrentItem
LaunchURL currItem
End Sub
The code above is what I've been experimenting with. I will actually replace the message box either with:
Shell ("C:\Program Files\Internet Explorer\IEXPLORE.EXE" & " " & SingleWord)
or
FollowHyperlink SingleWord
When I run this I get "Runtime Error 91: Object variable or With block variable not set". I've tried stepping into the code and from what I can tell the problem originates at the SET statement in the TestLaunchURL subroutine.
I am trying to snag the message I currently have focus on in my Outlook inbox and parse it apart for the first instance of "http://", at least at the moment.
Also, what would I expect to be getting back in "SingleWord" if I have a URL that has click-through text that is shown to the user tied to the actual URL itself? I might be able to exploit that to look for the word "Accept" just ahead of the URL itself were "Accept" the click through text.

Application_Startup variable disappears after sub finishes

This is a followup to a previous question I had asked. Thank you to the community for your help with that.
I'm trying to create WithEvents code for the first time to check a folder for new items. Eventual plan is to use the ItemsAdd event to trigger a bunch of other processing, but for now, just trying to save it to a folder and not getting that far.
When I run the Application_Startup code below, the immediate window shows that I've found the right clntFldrItms. Problem is, if I then drag an item into the folder in question, the ItemAdd macro doesn't fire. When I try to add a watch for clntFldrItms, the variable isn't set to anything. It looks like as soon as the Application_Startup sub finishes, the assignment stops.
All code is in the ThisOutlookSession object.
Could this be because I'm working with an SMTP email address (rather than Exchange, for example)?
Thanks again for your help.
EDIT Adding my response to Eugene's comment. I noticed that when I open the editor and step into the Application_Startup sub, clntFldrItms is properly assigned, even before I get to the Set clntFldrItms = clntFldr.Items line. As soon as I finish stepping through, it's gone again. I can't step into the ItemAdd sub, but when I step into other code clntFldrItms is Nothing.
FINAL EDIT Sorry, I realize I forgot to close this off. I wasn't able to solve the problem per se, but I realized it was due to my SMTP account. When I tried it at work with Exchange, it worked. It seems that the event doesn't fire unless I'm working in Exchange.
Option Explicit
Public WithEvents clntFldrItms As Outlook.Items
Private Sub Application_Startup()
Dim clntFldr As MAPIFolder
Set clntFldr = Application.Session.GetDefaultFolder(olFolderSentMail).Folders("Client Emails")
Set clntFldrItms = clntFldr.Items
Set clntFldr = Nothing
Debug.Print clntFldrItms.item(1).Subject
End Sub
Private Sub clntFldrItms_ItemAdd(ByVal item As Object)
Dim bChar As String
bChar = "\/:*?™""® <>|.&##_+`©~;-+=^$!,'" & Chr(34)
Dim saveName As String
If item.Class = olMail Then
saveName = item.Subject
For x = 1 To Len(bChar)
saveName = Replace(saveName, Mid(bChar, x, 1), "-")
Next x
item.SaveAs "C:\Users\User\Google Drive\8 - VBA work\Preparation for Assisted Responder\Sent Messages Folder\" & _
saveName & ".msg", olMSG
End If
End Sub
Try to set a breakpoint in the ItemAdd event handler and check out the clntFldrItms object there when the breakpoint is hit.
Be aware, the ItemAdd event is not fired when multiple items were added at the same time (more than 16 - this is a well-known issue in Outlook).
You may find the Getting Started with VBA in Outlook 2010 article hellpful.
EDIT The clntFldrItms is set because the Startup event handler is run when you start Outlook. So, the object is initialized at startup behind the scene.

Forwarding Macro not working in Outlook 2013

I autofoward all messages in a folder that I ran this macro on. I upgraded yesterday to 2013 and it does not work. I searched the commands used and couldn't find any of the ones I'm using not being recognized in Outlook 2013.
Sub ChangeSubjectForward(Item As Outlook.MailItem)
Item.Subject = "TAG NUMBER1234" & Item.Subject
Item.Save
Set myForward = Item.Forward
myForward.Recipients.Add "Email#email.com"
myForward.Send
End Sub
Your code looks good, I don't see anything strange in the code. It looks like you need to create a rule and assign the VBA macro sub to run.
Some Questions:
What are your rule settings that run this?
Are you manually running the rule on the folder, or is the rule automatically running on a trigger?
Are you getting any error messages?
Try the following:
Make sure the rule that runs your autoforward macro is lower on the rule list than the rule that files messages in that subfolder (if you're using one).
Also, since I don't know what triggers your macro, exactly, it's possible it is stopping when it is encountering a non MailItem object. Try this change:
Sub ChangeSubjectForward(olObj As Object)
dim Item As Outlook.MailItem
If olObj.Class <> olMail Then 'Making sure it is an email message
msgbox("Object Was Not MailItem")
Exit Sub
End If
Set Item = olObj
Item.Subject = "TAG NUMBER1234" & Item.Subject
Item.Save
Set myForward = Item.Forward
myForward.Recipients.Add "Email#email.com"
myForward.Send
End Sub
If you keep getting the message "Object Was Not MailItem" then the wrong objects are getting passed to your sub.