Call outlook macro from code - vba

I get an error when I run the InvokeMember method below. The error is UNKNOWN NAME. I have checked the spelling and it is correct. In Outlook I have Enable Macros in the trust center. Is there anything I might be missing to get this working? Thanks
VB code:
olApp.GetType().InvokeMember("Run", Reflection.BindingFlags.Default Or
Reflection.BindingFlags.InvokeMember,
Nothing, olApp, New Object() {"nameOfMacro"})
Research

Well, it seems InvokeMember will not work. The answer is to make the code as you would in the macro and run that. Example:
Private Sub MoveAttachmentToFolder()
Dim olNs = olApp.GetNamespace("MAPI")
Dim subFolderA = olNs.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox).Parent.Folders("subFolderA")
Dim subFolderB = olNs.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox).Parent.Folders("subFolderB")
For Each mi As Outlook.MailItem In subFolderA.Items
If mi.Attachments.Count = 1 Then
'remember interops use 1 based arrays not zero
Dim fileName As String = "some path" & mi.Attachments(1).FileName
mi.Attachments(1).SaveAsFile(fileName)
mi.Move(subFolderB)
End If
Next
End Sub

Related

My access to word merge code is not working

I have made a form in access and I'm trying to code a "merge to word" button but my code has a problem and I dont know how to fix it.
Here's the code:
Private Sub Command102_Click()
Dim LWordDoc As String
Dim oApp As Object
'Path to the word document
LWordDoc = "C:\school\information tech\document.docx"
If Dir(LWordDoc) = "" Then
MsgBox "Document not found."
Else
'Create an instance of MS Word
Set oApp = CreateObject(Class:="Word.Application")
oApp.Visible = True
'Open the Document
oApp.Documents.Open FileName:=Document.docx
End If
End Sub
If someone could help that would be great. Ill attach screenshots of the error I get when I click the button and the code as the debugger is pointing to the problem. (pointing to the start of the "oApp.Documents.Open FileName:=Document.docx" line)
Thanks heaps
Since you create a variable to hold the filename, try using that:
oApp.Documents.Open FileName:=LWordDoc

Filter Outlook 2010 tasks using VBA

I need to create custom filters in Outlook to save me from having to manually adjust the filter setting each time, preferably with VBA.
Below is my attempt. I inserted the message box line to check the correct items are being restricted. On running the macro I get a number of message boxes displayed with "1" indicating to me that it is working as expected (message box appears for each 'In Progress' item).
For Each Task_List In CreateObject("Outlook.Application").GetNamespace("MAPI").GetDefaultFolder(13).Items.Restrict("[Status]='In Progress'")
MsgBox Task_List.Status
sFilter = "[Status]=Task_List.Status"
Next
However, the tasks in the task folder are not filtered, all the tasks are displayed regardless of criteria.
What am I missing from my code? Or am I completely barking up the wrong tree.
Thanks, and apologies in advance for the simplistic question.
Once you manually set up different views you can get to them this way.
Where the view is named for instance "In Progress"
Sub TaskView_InProgress()
' No error if the view does not exist
' No error if not currently in Tasks folder
ActiveExplorer.CurrentView = "In Progress"
End Sub
This demonstrates how to access the In Progress tasks. Albeit much less helpful than a view if you have many tasks.
Private Sub task_Filter()
' Folders may contain any type of item
Dim myItem As Object
Dim myItems As items
Dim resItems As items
Dim myTaskFolder As Folder
Dim sFilter As String
Dim msgPrompt As String
Set myTaskFolder = Session.GetDefaultFolder(olFolderTasks)
Set myItems = myTaskFolder.items
sFilter = "[Status]='In Progress'"
Set resItems = myItems.Restrict(sFilter)
For Each myItem In resItems
If myItem.Class = OlTask Then
myItem.Display
End If
Next
End Sub
This sub worked great for my purpose. I wanted to also input a string in the search field of the task window from excel. So I loaded the string to the clipboard and used send keys to "Ctrl E" (enter search field) then "Ctrl V" paste. This routine turns num lock off. So I added a toggle for that.
Sub btn_GotoTask()
Set cl = New clsClient
' Folders may contain any type of item
Dim myItem As Object
Dim myItems As items
Dim resItems As items
Dim myTaskFolder As Folder
Dim sFilter As String
Dim msgPrompt As String
On Error GoTo outlookError
Set myTaskFolder = Session.GetDefaultFolder(olFolderTasks)
myTaskFolder.Display
SetClipboard cl.Pol
'Activate task window
myTaskFolder.Application.ActiveWindow
SendKeys "^{e}"
SendKeys "^{v}"
SendKeys "{NUMLOCK}"
Exit Sub
outlookError:
MsgBox "Outlook may not be open"
End Sub

Outlook VBA \ Macro conversion to Add-in

I'm in the process of converting some Outlook VBA \ Macros into add-ins.
So far I'm not having a lot of luck piping this code over to VS2015 w\Office Dev Tools.
I've created a ribbon \ group \ buttons \ I can see it in Outlook and everything looks good but I'm receiving an error.
--ORIGINAL MACRO--
Sub Request()
Set myOlApp = CreateObject("Outlook.Application")
Set myNameSpace = myOlApp.Application.GetNamespace("MAPI")
Set objFolder = Session.GetDefaultFolder(olPublicFoldersAllPublicFolders).Folders("Shared Documents")
Set myItem = objFolder.Items.Add("IPM.Note.Request")
myItem.Display
End Sub
I'm seeing that Set is no longer permitted so they've all been defined.
This particular line seems to be the problem.
Session and\or GetDefaultFolder are returning Null and causing a runtime exception.
Error -- "System.NullReferenceException" --
objFolder = Session.GetDefaultFolder(olPublicFoldersAllPublicFolders).Folders("Shared Documents")
The suggestion from VS is to use the Sub "New" along with a few others that don't seem applicable.
A little help please. :-)
Seems that I'm getting a mix of programming types mixed up from the VS error resolution suggestions.
Thank you. -Chris
Alrighty, it's working meow.
Found this handy dandy webpage in case someone needs some pointers:
https://support.microsoft.com/en-us/kb/313800
When you create a project for Outlook Add-ins it's being coded in VB.Net
Thank you DanL for the input, it got me thinking and searching again.
Private Sub Button1_Click(sender As Object, e As RibbonControlEventArgs) Handles Button1.Click
Dim objOutlook As Outlook._Application
objOutlook = New Outlook.Application()
Dim objNS As Outlook._NameSpace = objOutlook.Session
Dim objFolder As Outlook.MAPIFolder =
objNS.GetDefaultFolder(Outlook.OlDefaultFolders.olPublicFoldersAllPublicFolders).Folders("Shared Documents")
Dim myItem = objFolder.Items.Add("IPM.Note.CustomFormName")
myItem.Display()
End Sub

Outlook VBA troubleshooting

I have the following block of VBA code, which should create a popup box with the first name for each contact in my default folder.
Sub DeleteaContact()
Dim myOutlook As Outlook.Application
Dim myInformation As NameSpace
Dim myContacts As Items
Dim myItems As ContactItem
Set myOutlook = CreateObject("Outlook.Application")
Set myInformation = myOutlook.GetNamespace("MAPI")
Set myContacts = myInformation.GetDefaultFolder(olFolderContacts).Items
For Each myItems In myContacts
MsgBox (myItems.FirstName)
Next
End Sub
For some reason I am getting a sporadic type mismatch error at the end of the loop.
Can anyone shed some light on this subject as to why?
Folders can store more than just the data type you'd expect. Change myItems to
Dim myItems As Object
and change the message box to
Debug.Print TypeName(myItems)
Then check the Immediate Window (Ctl+G) to see if any of the items are not ContactItem. If you determine you have something in there that's not a contact, you simply need to test for it. Keep myItems as Object, but use code like
If TypeName(myItems) = "ContactItem" Then
MsgBox myItems.FirstName
End If
Generally, I leave my variables typed as the specific item (e.g. ContactItem) while I'm writing the code and then convert them all to Object when I'm done. That way you get the benefit of Intellisense while you're coding.
Try changing:
MsgBox (myItems.FirstName)
to:
MsgBox myItems.FirstName
as VBA doesn't like unnecessary parentheses

When is a MailItem not a MailItem? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have written a message handler function in Outlook's Visual Basic (we're using Outlook 2003 and Exchange Server) to help me sort out incoming email.
It is working for me, except sometimes the rule fails and Outlook deactivates it.
Then I turn the rule back on and manually run it on my Inbox to catch up. The rule spontaneously fails and deactivates several times a day.
I would love to fix this once and for all.
This code showed me the different TypeNames that were in my Inbox:
Public Sub GetTypeNamesInbox()
Dim myOlItems As Outlook.Items
Set myOlItems = application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Items
Dim msg As Object
For Each msg In myOlItems
Debug.Print TypeName(msg)
'emails are typename MailItem
'Meeting responses are typename MeetingItem
'Delivery receipts are typename ReportItem
Next msg
End Sub
HTH
I use the following VBA code snippet in other Office Applications, where the Outlook Library is directly referenced.
' Outlook Variables
Dim objOutlook As Outlook.Application: Set objOutlook = New Outlook.Application
Dim objNameSpace As Outlook.NameSpace: Set objNameSpace = objOutlook.GetNamespace("MAPI")
Dim objFolder As MAPIFolder: Set objFolder = objNameSpace.PickFolder()
Dim objMailItem As Outlook.MailItem
Dim iCounter As Integer: iCounter = objFolder.Items.Count
Dim i As Integer
For i = iCounter To 1 Step -1
If TypeOf objFolder.Items(i) Is MailItem Then
Set objMailItem = objFolder.Items(i)
With objMailItem
etc.
have written a message handler function in Outlook's Visual Basic (we're using Outlook 2003 and Exchange Server) to help me sort out incoming email. It is working for me, except sometimes the rule fails and Outlook deactivates it. Then I turn the rule back on and manually run it on my Inbox to catch up. The rule spontaneously fails and deactivates several times a day. I would love to fix this once and for all.
Here is the code stripped of the functionality, but giving you an idea of how it looks:
Public WithEvents myOlItems As Outlook.Items
Public Sub Application_Startup()
' Reference the items in the Inbox. Because myOlItems is declared
' "WithEvents" the ItemAdd event will fire below.
' Set myOlItems = Outlook.Session.GetDefaultFolder(olFolderInbox).Items
Set myOlItems = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub myOlItems_ItemAdd(ByVal Item As Object)
On Error Resume Next
If TypeName(Item) = "MailItem" Then
MyMessageHandler Item
End If
End Sub
Public Sub MyMessageHandler(ByRef Item As MailItem)
Dim strSender As String
Dim strSubject As String
If TypeName(Item) <> "MailItem" Then
Exit Sub
End If
strSender = LCase(Item.SenderEmailAddress)
strSubject = Item.Subject
rem do stuff
rem do stuff
rem do stuff
End Sub
One error I get is "Type Mismatch" calling MyMessageHandler where VB complains that Item is not a MailItem. Okay, but TypeName(Item) returns "MailItem", so how come Item is not a MailItem?
Another one I get is where an email with an empty subject comes along. The line
strSubject = Item.Subject
gives me an error. I know Item.Subject should be blank, but why is that an error?
Thanks.
My memory is somewhat cloudy on this, but I believe that a MailItem is not a MailItem when it is something like a read receipt. (Unfortunately, the VBA code that demonstrated this was written at another job and isn't around now.)
I also had code written to process incoming messages, probably for the same reason you did (too many rules for Exchange, or rules too complex for the Rules Wizard), and seem to recall running into the same problem you have, that some items seemed to be from a different type even though I was catching them with something like what you wrote.
I'll see if I can produce a specific example if it will help.
There are many types of items that can be seen in the default Inbox.
In the called procedure, assign the incoming item to an Object type variable. Then use TypeOf or TypeName to determine if it is a MailItem. Only then should your code perform actions that apply to emails.
i.e.
Dim obj As Object
If TypeName(obj) = "MailItem" Then
' your code for mail items here
End If
Dim objInboxFolder As MAPIFolder
Dim oItem As MailItem
Set objInboxFolder = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
For Each Item In objInboxFolder.Items
If TypeName(Item) = "MailItem" Then
Set oItem = Item
next
why not use a simple error handler for the code? Seriously. You could write an error for each read of a property or object that seems to fail. Then have it Resume no matter what. No need for complex error handling. Think of a test that shows an empty subject. Since you don't know what value it will return, if any, and it seems to error on an empty or blank subject, you need to picture it as a simple test with a possible error. Run the test as an if statement (one in which you will get an error anyway), and have the program resume on error.
On Error Resume Next
If object.subject = Null 'produces an error when subject is null, otherwise allows a good read
strSubject = "" 'sets the subject grab string to a null or empty string as a string
Else
strSubject = object.subject 'Sets the subject grab string to the subject of the message\item
End If