Outlook 2010 Select Calendar - vba

I have some users who would like to have multiple calendars selected when they switch to calendar folder in theirs Outlook.
So I took a sample code from:
http://www.slipstick.com/developer/code-samples/select-multiple-calendars-outlook/
Modified it a little and gave to my users. Problem is that it is not working on one of these Outlooks and I cannot find out why.
Below is my code and the exact problem is that this macro cannot "select/enable" the calendar I want - but if I try to debug the code and put MsgBox for testing - looks like the code is in right place. Procmon is not showing any "access denied" or other kind of errors.
Could You help me to investigate this ?
Sub SelectCalendars()
Dim objPane As Outlook.NavigationPane
Dim objModule As Outlook.CalendarModule
Dim objGroupA, objGroupB As Outlook.NavigationGroup
Dim objNavFolder As Outlook.NavigationFolder
Dim objCalendar As Folder
Dim objFolder As Folder
Dim i As Integer
Dim test As Outlook.NavigationFolder
Set Application.ActiveExplorer.CurrentFolder = Session.GetDefaultFolder(olFolderCalendar)
DoEvents
Set objCalendar = Session.GetDefaultFolder(olFolderCalendar)
Set objPane = Application.ActiveExplorer.NavigationPane
Set objModule = objPane.Modules.GetNavigationModule(olModuleCalendar)
With objModule.NavigationGroups
Set objGroupA = .Item(1)
End With
' First calendar group
Set objNavFolder = objGroupA.NavigationFolders.Item(1)
MsgBox objNavFolder.DisplayName
MsgBox objNavFolder.IsSelected
objNavFolder.IsSelected = False
' Second calendar group
Set objNavFolder = objGroupA.NavigationFolders.Item(2)
MsgBox objNavFolder.DisplayName
MsgBox objNavFolder.IsSelected
objNavFolder.IsSelected = False
Set objPane = Nothing
Set objModule = Nothing
Set objGroup = Nothing
Set objNavFolder = Nothing
Set objCalendar = Nothing
Set objFolder = Nothing
End Sub

First of all, I'd suggest using the Debug.Print statements instead of Message boxes.
The IsSelected property of the NavigationFolder class allows to set a boolean variable that indicates whether the NavigationFolder object is selected for display. Try to set this property to true (instead of false).

Related

How to copy selected text from the email subject or body, put it into a link and open it in a browser

I am using Outlook for Office 365 (desktop).
I am trying to copy selected text from the email subject or body, and put it into a predefined web address and open it in the default browser.
Steps:
Open or select a received message
Select a word from the subject or body
Run the macro
The default browser should open the link: https://www.dictionary.com/browse/*selected word*
The code below only opens the link when the selected word is in the body of the email.
Sub OPEN_DICT()
Dim msg As Outlook.MailItem
Dim insp As Outlook.Inspector
Dim vURL1
Dim vURL2
Dim fullVID
Dim fullVURL
If Application.ActiveInspector Is Nothing Then
If Application.ActiveExplorer.Selection.Count = 1 Then
If Application.ActiveExplorer.Selection.Item(1).Class = olMail Then
Set msg = Application.ActiveExplorer.Selection.Item(1)
End If
Else
'to many items selected
MsgBox "Please select one item"
End If
Else
Set insp = Application.ActiveInspector
If insp.CurrentItem.Class = olMail Then
Set msg = insp.CurrentItem
End If
End If
If msg Is Nothing Then
MsgBox "could not determine an item. Try again!"
Else
If msg.GetInspector.EditorType = olEditorWord Then
Set hed = msg.GetInspector.WordEditor
Set appWord = hed.Application
Set Rng = appWord.Selection
With Rng
.Copy
End With
End If
End If
If IsNumeric(Rng) Then
fullVID = Rng
vURL1 = "https://www.dictionary.com/browse/"
vURL2 = fullVID
fullVURL = vURL1 & vURL2
Else
fullVID = Rng
vURL1 = "https://www.dictionary.com/browse/"
vURL2 = fullVID
fullVURL = vURL1 & vURL2
End If
Dim build
Set build = CreateObject("Shell.Application")
build.ShellExecute "Chrome.exe", fullVURL, "", "", 1
ExitNewItem:
Exit Sub
Set appWord = Nothing
Set insp = Nothing
Set Rng = Nothing
Set hed = Nothing
Set msg = Nothing
End Sub
How can the selected text from the Subject of the email also be opened in the link?
Also, instead of opening the link in Chrome, it should open in the default browser.
Outlook Object Model does not expose anything that would let you access selected (or any other) text from any of its controls except for the message body editor (which is exposed as Word.Document object).
Your best bet would be finding the Subject editor using low-level Windows API (FindWindow etc.) or Automation or Accessibility API to do that. See, for example, How to get selected text of currently focused window? or How to get selected text of any application into a windows form application

Outlook Subfolder Expansion

I've code to expand folders in Outlook. It works for the first level folders, but won't expand the subfolders (in this case the xx Progressions folder).
The code doesn't bug out: the subfolder simply does not expand.
Private Sub ExpandFolders()
Dim objCurrentFolder As Outlook.Folder
Dim objStore As Outlook.Store
Dim objFileFolders As Outlook.Folders
Dim objFolder As Outlook.Folder
Dim objView As Outlook.View
'Expand xx Notifications
Set objStore = Outlook.Application.Session.Stores("xxNotification")
Set objFileFolders = objStore.GetRootFolder.Folders
Set Application.ActiveExplorer.CurrentFolder = objFileFolders("Inbox") 'Works fine
'Expand xx Delivery Support
Set objStore = Outlook.Application.Session.Stores("xxDeliverySupport")
Set objFileFolders = objStore.GetRootFolder.Folders
Set Application.ActiveExplorer.CurrentFolder = objFileFolders("Inbox")
Set Application.ActiveExplorer.CurrentFolder = objFileFolders("Inbox").Folders("xx Progressions") 'Does not expand
'User inbox
Set objStore = Outlook.Application.Session.Stores("xx.xx#xx.com")
Set objFileFolders = objStore.GetRootFolder.Folders
Set Application.ActiveExplorer.CurrentFolder = objFileFolders("Inbox") 'Works fine
End Sub
You trick a folder into expanding by selecting a folder under it.
Step through the code to see the expansion is "delayed" by one folder.
Option Explicit
Private Sub ExpandFolders()
Dim objStore As store
Dim objFileFolders As folders
Dim objCurrentFolder As Folder
Set objStore = Session.Stores("xxDeliverySupport")
Set objFileFolders = objStore.GetRootFolder.folders
' expand "xxDeliverySupport" by selecting Inbox
Set ActiveExplorer.CurrentFolder = objFileFolders("Inbox")
Set objCurrentFolder = ActiveExplorer.CurrentFolder
' expand "Inbox" by selecting "xx Progressions"
Set ActiveExplorer.CurrentFolder = objCurrentFolder.folders("xx Progressions")
Set objCurrentFolder = ActiveExplorer.CurrentFolder
' expand "xx Progressions" by selecting folder one level below
Set ActiveExplorer.CurrentFolder = objCurrentFolder.folders(1)
End Sub

How to identify emails where sender is also a recipient?

I'm trying to export sender email address and recipient email addresses (to and cc) to Excel. I adapted code I found online. It does most of what I need but there are two problems:
It only works with a single recipient. If there are two or more recipients, it provides names (e.g. Jo Bloggs) instead of email addresses.
It only includes people in the 'To' field, not those in the 'CC' field.
I think the bit that needs fixing is:
'trying to get recipient email address
Dim olEU2 As Outlook.ExchangeUser
Dim oEDL2 As Outlook.ExchangeDistributionList
Dim recip2 As Outlook.Recipient
Set recip2 = Application.Session.CreateRecipient(strColE)
Select Case recip2.AddressEntry.AddressEntryUserType
Case OlAddressEntryUserType.olExchangeUserAddressEntry
Set olEU2 = recip.AddressEntry.GetExchangeUser
If Not (olEU2 Is Nothing) Then
strColE = olEU2.PrimarySmtpAddress
End If
Case OlAddressEntryUserType.olOutlookContactAddressEntry
Set olEU2 = recip.AddressEntry.GetExchangeUser
If Not (olEU2 Is Nothing) Then
strColE = olEU2.PrimarySmtpAddress
End If
Case OlAddressEntryUserType.olExchangeDistributionListAddressEntry
Set oEDL2 = recip.AddressEntry.GetExchangeDistributionList
If Not (oEDL2 Is Nothing) Then
strColE = olEU2.PrimarySmtpAddress
End If
End Select
Full code:
Option Explicit
Sub CopyToExcel()
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim rCount As Long
Dim bXStarted As Boolean
Dim enviro As String
Dim strPath As String
Dim objOL As Outlook.Application
Dim objFolder As Outlook.MAPIFolder
Dim objItems As Outlook.Items
Dim obj As Object
Dim olItem 'As Outlook.MailItem
Dim strColA, strColB, strColC, strColD, strColE, strColF As String
' Get Excel set up
enviro = CStr(Environ("USERPROFILE"))
'the path of the workbook
strPath = enviro & "\Documents\Book1.xlsx"
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
Application.StatusBar = "Please wait while Excel source is opened ... "
Set xlApp = CreateObject("Excel.Application")
bXStarted = True
End If
On Error GoTo 0
On Error Resume Next
' Open the workbook to input the data
' Create workbook if doesn't exist
Set xlWB = xlApp.Workbooks.Open(strPath)
If Err <> 0 Then
Set xlWB = xlApp.Workbooks.Add
xlWB.SaveAs FileName:=strPath
End If
On Error GoTo 0
Set xlSheet = xlWB.Sheets("Sheet1")
On Error Resume Next
' add the headers if not present
If xlSheet.Range("A1") = "" Then
xlSheet.Range("A1") = "Sender Name"
xlSheet.Range("B1") = "Sender Email"
xlSheet.Range("C1") = "Subject"
xlSheet.Range("D1") = "Body"
xlSheet.Range("E1") = "Sent To"
xlSheet.Range("F1") = "Date"
End If
'Find the next empty line of the worksheet
rCount = xlSheet.Range("B" & xlSheet.Rows.Count).End(-4162).Row
'needed for Exchange 2016. Remove if causing blank lines.
rCount = rCount + 1
' get the values from outlook
Set objOL = Outlook.Application
Set objFolder = objOL.ActiveExplorer.CurrentFolder
Set objItems = objFolder.Items
For Each obj In objItems
Set olItem = obj
'collect the fields
strColA = olItem.SenderName
strColB = olItem.SenderEmailAddress
strColC = olItem.Subject
strColD = olItem.Body
strColE = olItem.To
strColF = olItem.ReceivedTime
' Get the Exchange address
' if not using Exchange, this block can be removed
Dim olEU As Outlook.ExchangeUser
Dim oEDL As Outlook.ExchangeDistributionList
Dim recip As Outlook.Recipient
Set recip = Application.Session.CreateRecipient(strColB)
If InStr(1, strColB, "/") > 0 Then
' if exchange, get smtp address
Select Case recip.AddressEntry.AddressEntryUserType
Case OlAddressEntryUserType.olExchangeUserAddressEntry
Set olEU = recip.AddressEntry.GetExchangeUser
If Not (olEU Is Nothing) Then
strColB = olEU.PrimarySmtpAddress
End If
Case OlAddressEntryUserType.olOutlookContactAddressEntry
Set olEU = recip.AddressEntry.GetExchangeUser
If Not (olEU Is Nothing) Then
strColB = olEU.PrimarySmtpAddress
End If
Case OlAddressEntryUserType.olExchangeDistributionListAddressEntry
Set oEDL = recip.AddressEntry.GetExchangeDistributionList
If Not (oEDL Is Nothing) Then
strColB = olEU.PrimarySmtpAddress
End If
End Select
End If
' End Exchange section
'trying to get recipient email address
Dim olEU2 As Outlook.ExchangeUser
Dim oEDL2 As Outlook.ExchangeDistributionList
Dim recip2 As Outlook.Recipient
Set recip2 = Application.Session.CreateRecipient(strColE)
Select Case recip2.AddressEntry.AddressEntryUserType
Case OlAddressEntryUserType.olExchangeUserAddressEntry
Set olEU2 = recip.AddressEntry.GetExchangeUser
If Not (olEU2 Is Nothing) Then
strColE = olEU2.PrimarySmtpAddress
End If
Case OlAddressEntryUserType.olOutlookContactAddressEntry
Set olEU2 = recip.AddressEntry.GetExchangeUser
If Not (olEU2 Is Nothing) Then
strColE = olEU2.PrimarySmtpAddress
End If
Case OlAddressEntryUserType.olExchangeDistributionListAddressEntry
Set oEDL2 = recip.AddressEntry.GetExchangeDistributionList
If Not (oEDL2 Is Nothing) Then
strColE = olEU2.PrimarySmtpAddress
End If
End Select
'write them in the excel sheet
xlSheet.Range("A" & rCount) = strColA
xlSheet.Range("B" & rCount) = strColB
xlSheet.Range("c" & rCount) = strColC
xlSheet.Range("d" & rCount) = strColD
xlSheet.Range("e" & rCount) = strColE
xlSheet.Range("f" & rCount) = strColF
'Next row
rCount = rCount + 1
xlWB.Save
Next
' don't wrap lines
xlSheet.Rows.WrapText = False
xlWB.Save
xlWB.Close 1
If bXStarted Then
xlApp.Quit
End If
Set olItem = Nothing
Set obj = Nothing
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
End Sub
Iterating through all items in the folder is not really a good idea. I'd recommend starting from the Find/FindNext or Restrict methods instead. Please note that there are some item properties that you can’t use for the filter. You can read more about the properties not allowed in the filter string and string formats used for the search criterion on MSDN.
The following example uses the Restrict method to get all Inbox items of Business category and moves them to the Business folder. To run this example, create or make sure a subfolder called 'Business' exists under Inbox:
Sub MoveItems()
Dim myNamespace As Outlook.NameSpace
Dim myFolder As Outlook.Folder
Dim myItems As Outlook.Items
Dim myRestrictItems As Outlook.Items
Dim myItem As Outlook.MailItem
Set myNamespace = Application.GetNamespace("MAPI")
Set myFolder = _
myNamespace.GetDefaultFolder(olFolderInbox)
Set myItems = myFolder.Items
Set myRestrictItems = myItems.Restrict("[Categories] = 'Business'")
For i = myRestrictItems.Count To 1 Step -1
myRestrictItems(i).Move myFolder.Folders("Business")
Next
End Sub
Also, you may find the AdvancedSearch method of the Application class helpful. The key benefits of using the AdvancedSearch method in Outlook are:
The search is performed in another thread. You don’t need to run another thread manually since the AdvancedSearch method runs it automatically in the background.
Possibility to search for any item types: mail, appointment, calendar, notes etc. in any location, i.e. beyond the scope of a certain folder. The Restrict and Find/FindNext methods can be applied to a particular Items collection (see the Items property of the Folder class in Outlook).
Full support for DASL queries (custom properties can be used for searching too). You can read more about this in the Filtering article in MSDN. To improve the search performance, Instant Search keywords can be used if Instant Search is enabled for the store (see the IsInstantSearchEnabled property of the Store class).
You can stop the search process at any moment using the Stop method of the Search class.
Please remember that you can set a suitable filter (View | View Settings |filter) on a folder and study the filter string on the SQL tab of the Filter dialog. Then you can construct any required filter string in the code.
If woudl be nice to use Items.Find/FindNext or Items.Restrict, but I cannot think of a query that would let you do what you want. If it is a one time thing, you have no choice but to loop through all items in a folder and for each item loop through all recipients and compare each recipient's entry id (Recipient.EntryID) with the sender entry id (MailItem.Sender.EntryId).

Send Appointment VBA

So, I've been wrestling with this task for WAY too long now. I am trying to make a button that creates an appointment and sends it to someone. So far, I've been successful in creating the appointment with the variables I want, but I can't figure out how to send it to the right person. Or send it at all for that matter. I'm very new to Outlook applications within VBA, so be gentle with me, but here is my code so far:
Sub appt()
Dim OutApp As Object
Dim OutMail As Object
Dim duedate As String
Dim currentrow As String
Dim currentsheet As String
Dim owner As String
currentsheet = ActiveSheet.Name
currentrow = Range("C10:C" & Rows.Count).Cells.SpecialCells(xlCellTypeBlanks).Row
duedate = Range("C" & currentrow).Offset(0, 1)
owner = Range("C" & currentrow).Offset(0, 2)
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(1)
On Error Resume Next
With OutMail
.Recipients = Range("M3")
.Subject = "Next PDB Task for " & currentsheet
.Importance = True
.Start = "8:00 AM" & duedate
.End = "8:00 AM" & Format(Date + 5)
.ReminderMinutesBeforeStart = 10080
.Body = "Text and Stuff"
.Display
End With
Set OutMail = Nothing
Set OutApp = Nothing
Unload Emy
End Sub
So, this is definitely grabbing the information I want from the sheet it's run in, however it's not going anywhere. Do I need to use something other than .Recipients? Is it possible to forward this (with .Forward maybe?)? Any help would be greatly appreciated!!!
P.S. The email address I want to send the appointment to is in cell M3.
I didn't try the scripts, but it looks like they will do what you want.
Sub ResolveName()
Dim myNamespace As Outlook.NameSpace
Dim myRecipient As Outlook.Recipient
Dim CalendarFolder As Outlook.Folder
Set myNamespace = Application.GetNamespace("MAPI")
Set myRecipient = myNamespace.CreateRecipient("Dan Wilson")
myRecipient.Resolve
If myRecipient.Resolved Then
Call ShowCalendar(myNamespace, myRecipient)
End If
End Sub
Sub ShowCalendar(myNamespace, myRecipient)
Dim CalendarFolder As Outlook.Folder
Set CalendarFolder = _
myNamespace.GetSharedDefaultFolder _
(myRecipient, olFolderCalendar)
CalendarFolder.Display
End Sub
excel vba create appointment in someone elses calendar
Sub MultiCalendars()
Dim objPane As Outlook.NavigationPane
Dim objModule As Outlook.CalendarModule
Dim objGroup As Outlook.NavigationGroup
Dim objNavFolder As Outlook.NavigationFolder
Dim objFolder As Folder
Dim calItem As Object
Dim mtgAttendee As Outlook.Recipient
Dim i As Integer
Set Application.ActiveExplorer.CurrentFolder = Session.GetDefaultFolder(olFolderCalendar)
DoEvents
Set objPane = Application.ActiveExplorer.NavigationPane
Set objModule = objPane.Modules.GetNavigationModule(olModuleCalendar)
With objModule.NavigationGroups
Set objGroup = .GetDefaultNavigationGroup(olMyFoldersGroup)
' To use a different calendar group
' Set objGroup = .Item("Shared Calendars")
End With
For i = 1 To objGroup.NavigationFolders.Count
If (objGroup.NavigationFolders.Item(i).Folder.FullFolderPath = "\\Mailbox - Doe, John T\Calendar") Then
Set objNavFolder = objGroup.NavigationFolders.Item(i)
Set calItem = objNavFolder.Folder.Items.Add(olAppointmentItem)
calItem.MeetingStatus = olMeeting
calItem.Subject = "Test Meeting - Ignore"
calItem.Location = "TBD Location"
calItem.Start = #1/19/2015 1:30:00 PM#
calItem.Duration = 90
Set mtgAttendee = calItem.Recipients.Add("John Doe")
mtgAttendee.Type = olRequired
Set mtgAttendee = calItem.Recipients.Add("Jane Doe")
mtgAttendee.Type = olOptional
Set mtgAttendee = calItem.Recipients.Add("CR 101")
mtgAttendee.Type = olResource
calItem.Save
If (calItem.Recipients.ResolveAll) Then
calItem.Send
Else
calItem.Display
End If
End If
Next
Set objPane = Nothing
Set objModule = Nothing
Set objGroup = Nothing
Set objNavFolder = Nothing
Set objFolder = Nothing
Set calItem = Nothing
Set mtgAttendee = Nothing
End Sub
https://answers.microsoft.com/en-us/office/forum/office_2010-customize/excel-vba-create-an-appointment-in-someone-elses/4c2ec8d1-82f2-4b02-abb7-8c2de2fd7656?auth=1

Remove space before and after in Outlook

I'm attempting to write a macro for Outlook (never written a macro, or VBA for that matter) that will remove the space before and after the text that I have selected.
This is what I've cobbled together from examples that I've found:
Sub FixParagraphSpacing()
Dim objOL As Application
Dim objDoc As Object
Dim objSel As Object
Set objOL = Application
Set objDoc = objOL.ActiveInspector.WordEditor
Set objSel = objDoc.Windows(1).Selection
objSel.ParagraphFormat.SpaceBefore = 0
objSel.ParagraphFormat.SpaceAfter = 0
Set objOL = Nothing
Set objDoc = Nothing
Set objSel = Nothing
End Sub
The problem is that the code executes and almost nothing happens. The body of the email isn't affected, but I'm not able to remove the spacing before and after manually anymore because Outlook thinks it's already been done.
What am I missing here?
Update
Here is my updated code, based on #KevinPope's answer:
Sub FixParagraphSpacing()
Dim objOL As Application
Dim sel As Object
Set objOL = Application
Set sel = objOL.ActiveInspector().WordEditor.Application.Selection
For Each para In sel.Paragraphs
para.SpaceBefore = 0
para.SpaceAfter = 0
Next para
End Sub
Before I run the code, here's what I see under Line and Paragraph Spacing:
And here's what I see after I run the macro:
Unfortunately, other than this, no visible change is made in the body of the email.
Screenshot of text per request:
I too faced the same problem.
When running the macro, it does seem to update the values (space before/after to 0), but doesnt apply the settings to the selected text.
But then adding the SpaceBeforeAuto = False worked...
Sub FixParagraphSpacing()
Dim objOL As Application
Dim objDoc As Object
Dim objSel As Object
Set objOL = Application
Set objDoc = objOL.ActiveInspector.WordEditor
Set objSel = objDoc.Windows(1).Selection
objSel.ParagraphFormat.SpaceBefore = 0
objSel.ParagraphFormat.SpaceBeforeAuto = False
objSel.ParagraphFormat.SpaceAfter = 0
objSel.ParagraphFormat.SpaceAfterAuto = False
Set objOL = Nothing
Set objDoc = Nothing
Set objSel = Nothing
End Sub
Try using "Selection.WholeStory" before you set the paragraph formatting. It worked for me.
Something like this should sort out the line spacing before and after a selected Paragraph:
Sub Test()
Dim objOL As Application
Dim sel As Object
Set objOL = Application
Set sel = objOL.ActiveInspector().WordEditor.Application.Selection
sel.Paragraphs(1).SpaceBefore = 0
sel.Paragraphs(1).SpaceAfter = 0
End Sub
Let me know if this doesn't work and we can iterate on it.