I loop through information in an Excel sheet to create appointments in Outlook. It was working when I sent it to my default folder.
I made changes to upload the data to a specific folder (shared by coworkers).
Since then, as I F8 through my code, it saves the appointment for the row being looped through. However, when I go to the next row, the new appointment replaces the old instead of both being saved.
Sub ExportToOutlook
Dim OL as Outlook.Application, Appoint as Outlook.AppointmentItem, ES as Worksheet, _
r as Long, i as Long, WB as ThisWorkook, oFolder as Object, o NameSpace as Namespace
Set WB = ThisWorkbook
Set ES = WB.Sheets("Export Sheet")
r = ES.Cells(Rows.count,1).End(xlUp).Row
Set OL = New Outlook.Application
Set oNameSpace = OL.GetNamespace("MAPI")
Set oFolder = oNameSpace.GetFolderFromID("Insert the ID").Items.Add(olAppointmentItem)
For i = 2 to r
With oFolder
.Subject = ES.Cells(i,1).Value
.Start = ES.Cells(i,2).Value
.End = ES.Cells(i,3).Value
.Location = ES.Cells(i,4).Value
.AllDayEvent = ES.Cells(i,5).Value
.Categories = ES.Cells(i,6).Value & " Category"
.Save
End With
Next i
Set OL = Nothing
End Sub
You seem to be reupdating the same folder at each row iteration. Try the following:
Sub ExportToOutlook
Dim OL as Outlook.Application, Appoint as Outlook.AppointmentItem, ES as Worksheet, _
r as Long, i as Long, WB as ThisWorkook, oFolder as Object, o NameSpace as Namespace
Set WB = ThisWorkbook
Set ES = WB.Sheets("Export Sheet")
r = ES.Cells(Rows.count,1).End(xlUp).Row
Set OL = New Outlook.Application
Set oNameSpace = OL.GetNamespace("MAPI")
Set oFolder = oNameSpace.GetFolderFromID("Insert the ID")
For i = 2 to r
Dim appt as MailItem
Set appt = oFolder.Items.Add(olAppointmentItem)
With appt
.Subject = ES.Cells(i,1).Value
.Start = ES.Cells(i,2).Value
.End = ES.Cells(i,3).Value
.Location = ES.Cells(i,4).Value
.AllDayEvent = ES.Cells(i,5).Value
.Categories = ES.Cells(i,6).Value & " Category"
.Save
End With
Next i
Set OL = Nothing
End Sub
Dim appt as Outlook.AppointmentItem was the fix for me!
Sub ExportToOutlook2()
Dim OL As Outlook.Application, ES As Worksheet, _
r As Long, i As Long, WB As ThisWorkbook, oFolder As Object, oNameSpace As Namespace
Set WB = ThisWorkbook
Set ES = WB.Sheets("Export Sheet")
r = ES.Cells(Rows.count, 1).End(xlUp).Row
Set OL = New Outlook.Application
Set oNameSpace = OL.GetNamespace("MAPI")
Set oFolder = oNameSpace.GetFolderFromID("00000000579E67EAD9C2C94591E62A3CF21135F801001241364BFDA9AF49A3D3384A976997C50036FCD700060000")
For i = 2 To r
Dim appt As Outlook.AppointmentItem
Set appt = oFolder.Items.Add(olAppointmentItem)
With appt
.Subject = ES.Cells(i, 1).Value
.Start = ES.Cells(i, 2).Value
.End = ES.Cells(i, 3).Value
.Location = ES.Cells(i, 4).Value
.AllDayEvent = ES.Cells(i, 5).Value
.Categories = ES.Cells(i, 6).Value
.Save
End With
Next i
Set OL = Nothing
End Sub
Related
I'd like to create an Outlook calendar meeting request each time a workbook is saved.
The meeting requests need to be added to a shared mailbox so that all users that have access see the meeting invite.
So far it adds an entry to my personal calendar.
Private Sub Workbook_AfterSave(ByVal Success As Boolean)
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("2021") 'define your sheet!
Dim olApp As Object 'create outlook application
Set olApp = CreateObject("Outlook.Application")
Dim olNS As Object 'get namespace
Set olNS = olApp.GetNamespace("MAPI")
'define constants if using late binding
Const olFolderCalendar As Long = 9
Const olAppointmentItem As Long = 1
Dim olRecItems As Object 'get all appointments
Set olRecItems = olNS.GetDefaultFolder(olFolderCalendar)
Dim strFilter As String 'filter for appointments
Dim olFilterRecItems As Object 'filtered appointments
Dim iRow As Long
iRow = 3
Do Until Trim$(ws.Cells(iRow, 3).Value) = vbNullString
'filter appointments for subject
strFilter = "[Subject] = '" & Trim$(ws.Cells(iRow, 4).Value) & "'"
Set olFilterRecItems = olRecItems.Items.Restrict(strFilter)
If olFilterRecItems.Count = 0 Then 'if subject does not exist
With olApp.CreateItem(olAppointmentItem)
.Subject = ws.Cells(iRow, 4).Value
.Start = ws.Cells(iRow, 3).Value
.AllDayEvent = True
.BusyStatus = 5
.ReminderSet = True
.Save
End With
ws.Cells(iRow, 3).Interior.ColorIndex = 50
End If
iRow = iRow + 1
Loop
End Sub
Update:
I managed to get this. The problem now is that it'll only create the calendar entry for the last line.
Private Sub Workbook_AfterSave(ByVal Success As Boolean)
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("2020") 'define your sheet!
Dim olApp As Object 'create outlook application
Set olApp = CreateObject("Outlook.Application")
Dim olNS As Object 'get namespace
Set olNS = olApp.GetNamespace("MAPI")
Dim olAppItem As Outlook.AppointmentItem
Dim myRequiredAttendee As Outlook.Recipient
'define constants if using late binding
Const olFolderCalendar As Long = 9
Const olAppointmentItem As Long = 1
Dim olRecItems As Object 'get all appointments
Set olRecItems = olNS.GetDefaultFolder(olFolderCalendar)
Set olAppItem = olRecItems.Items.Add(olAppointmentItem)
Dim strFilter As String 'filter for appointments
Dim olFilterRecItems As Object 'filtered appointments
Dim iRow As Long
iRow = 3
Do Until Trim$(ws.Cells(iRow, 3).Value) = vbNullString
'filter appointments for subject
strFilter = "[Subject] = '" & Trim$(ws.Cells(iRow, 4).Value) & "'"
Set olFilterRecItems = olRecItems.Items.Restrict(strFilter)
If olFilterRecItems.Count = 0 Then 'if subject does not exist
With olAppItem
Set myRequiredAttendee = .Recipients.Add("email address")
myRequiredAttendee.Type = olRequired
.MeetingStatus = olMeeting
.ReminderMinutesBeforeStart = 30
.Subject = ws.Cells(iRow, 4).Value
.Start = ws.Cells(iRow, 3).Value
.AllDayEvent = True
.BusyStatus = 5
.ReminderSet = True
.Send
End With
ws.Cells(iRow, 3).Interior.ColorIndex = 50
End If
iRow = iRow + 1
Loop
End Sub
Instead of the following code:
Dim olRecItems As Object 'get all appointments
Set olRecItems = olNS.GetDefaultFolder(olFolderCalendar)
You need to use the NameSpace.GetSharedDefaultFolder method which returns a Folder object that represents the specified default folder for the specified user. This method is used in a delegation scenario, where one user has delegated access to another user for one or more of their default folders (for example, their shared Calendar folder). For example:
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("Eugene Astafiev")
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
I'm trying to pull in data that is set up like a table from my email. Does anyone know how I can loop through the email contents to check for tables, and if there is to export the data to columns in Excel? Right now the code I have just returns the subject, sender and time sent.
Sub GetMCInboxLeads()
Dim ol As Outlook.Application
Dim ns As Outlook.Namespace
Dim fol As Outlook.Folder
Dim i As Object
Dim mi As Outlook.MailItem
Dim n As Long
Dim rh As Double
Dim objOwner As Outlook.Recipient
Set ol = New Outlook.Application
Set ns = ol.GetNamespace("MAPI")
Set fol = ns.GetDefaultFolder(olFolderInbox)
Set objOwner = ns.CreateRecipient("xx#xxx.com")
objOwner.Resolve
If objOwner.Resolved Then
Set fol = ns.GetSharedDefaultFolder(objOwner, olFolderInbox)
End If
Worksheets.Add
rh = Range("A1").RowHeight
'i = 1
For Each i In fol.Items
If i.Class = olMail Then
n = n + 1
Set mi = i
'Debug.Print mi.Subject, mi.SenderName, mi.ReceivedTime
Cells(n, 1).Value = mi.SenderName
Cells(n, 2).Value = mi.Subject
Cells(n, 3).Value = mi.ReceivedTime
Cells(n, 4).Value = mi.Body
End If
Next i
Range("A1").CurrentRegion.EntireColumn.AutoFit
Range("A1").CurrentRegion.EntireRow.RowHeight = rh
I have the following code set up to create appointments in Outlook from data on my Excel spreadsheet. What I would like to do id make the appointment in a shared calendar rather than my own default one.
The calendar I want to add it to is the DTS Streetworks one as shown here - https://ibb.co/tKXKSPX, but I have no idea how to go about it.
Sub CoringAdd()
Dim OL As Outlook.Application, ES As Worksheet, _
r As Long, i As Long, wb As ThisWorkbook
Set wb = ThisWorkbook
Set ES = wb.Sheets("Coring")
Set OL = New Outlook.Application
r = ES.Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To r
With ES.Cells(i, 10)
If .Value = "No" And ES.Cells(i, 7) <> "Yes" Then
ES.Cells(i, 7) = "Yes"
With OL.CreateItem(olAppointmentItem)
.Subject = "Send reminder email - LBRuT " + ES.Cells(i, 2).Value
.Start = ES.Cells(i, 6) + 1 + ES.Cells(i, 8).Value
.ReminderSet = True
.ReminderMinutesBeforeStart = 60
.Body = "£" & ES.Cells(i, 5).Value
.Save
End With
End If
End With
Next i
Set OL = Nothing
Set wb = Nothing
Set ES = Nothing
End Sub
UPDATE:
Latest code below, still goes to default calendar.
Sub ResolveName()
Dim OL As Outlook.Application, ES As Worksheet, _
r As Long, i As Long, wb As ThisWorkbook
Set wb = ThisWorkbook
Set ES = wb.Sheets("Licences")
Set OL = New Outlook.Application
Dim myOlApp As Outlook.Application
Dim myNamespace As Outlook.Namespace
Dim myRecipient As Outlook.Recipient
Dim CalendarFolder As Outlook.MAPIFolder
Set myOlApp = CreateObject("Outlook.Application")
Set myNamespace = myOlApp.GetNamespace("MAPI")
Set myRecipient = myNamespace.CreateRecipient("DTS Streetworks")
myRecipient.Resolve
r = Cells(Rows.Count, 1).End(xlUp).Row
For i = 5 To r
With Cells(i, 5)
If myRecipient.Resolved And .Value = "Mobile Plant" And Cells(i, 6) <> "" Then
With OL.CreateItem(olAppointmentItem)
.Subject = "Test " + ES.Cells(i, 4).Value
.Start = ES.Cells(i, 14) + ES.Cells(i, 15).Value
.ReminderSet = True
.ReminderMinutesBeforeStart = 60
.Body = ES.Cells(i, 5).Value
.Save
End With
End If
End With
Next i
End Sub
Sub ShowCalendar(myNamespace, myRecipient)
Dim CalendarFolder As Outlook.MAPIFolder
Set CalendarFolder = myNamespace.GetSharedDefaultFolder(myRecipient, olFolderCalendar)
CalendarFolder.Display
End Sub
You can get the shared calendar by using the NameSpace.GetSharedDefaultFolder method which returns a Folder object that represents the specified default folder for the specified user. For example:
Sub ResolveName()
Dim myOlApp As Outlook.Application
Dim myNamespace As Outlook.NameSpace
Dim myRecipient As Outlook.Recipient
Dim CalendarFolder As Outlook.MAPIFolder
Set myOlApp = CreateObject("Outlook.Application")
Set myNamespace = myOlApp.GetNamespace("MAPI")
Set myRecipient = myNamespace.CreateRecipient("Eugene Astafiev")
myRecipient.Resolve
If myRecipient.Resolved Then
Call ShowCalendar(myNamespace, myRecipient)
End If
End Sub
Sub ShowCalendar(myNamespace, myRecipient)
Dim CalendarFolder As Outlook.MAPIFolder
Set CalendarFolder = myNamespace.GetSharedDefaultFolder(myRecipient, olFolderCalendar)
CalendarFolder.Display
End Sub
When you get a shared calendar folder you may use the Items.Add method which creates a new Outlook item in the Items collection for the folder. You just need to pass an item type you need to create, for example, olAppointmentItem.
Set myItem = mySharedCalendarFolder.Items.Add olAppointmentItem
So, your code should look like this:
Set wb = ThisWorkbook
Set ES = wb.Sheets("Licences")
Dim myOlApp As Outlook.Application
Dim myNamespace As Outlook.Namespace
Dim myRecipient As Outlook.Recipient
Dim CalendarFolder As Outlook.MAPIFolder
Dim olAppItem as Outlook.AppointmentItem
Set myOlApp = CreateObject("Outlook.Application")
Set myNamespace = myOlApp.GetNamespace("MAPI")
Set myRecipient = myNamespace.CreateRecipient("DTS Streetworks")
myRecipient.Resolve
If myRecipient.Resolved Then
Set CalendarFolder = myNamespace.GetSharedDefaultFolder(myRecipient, olFolderCalendar)
r = Cells(Rows.Count, 1).End(xlUp).Row
For i = 5 To r
With Cells(i, 5)
If .Value = "Mobile Plant" And Cells(i, 6) <> "" Then
Set olAppItem = CalendarFolder.Items.Add olAppointmentItem
With olAppItem
.Subject = "Test " + ES.Cells(i, 4).Value
.Start = ES.Cells(i, 14) + ES.Cells(i, 15).Value
.ReminderSet = True
.ReminderMinutesBeforeStart = 60
.Body = ES.Cells(i, 5).Value
.Save
End With
End If
End With
Next i
End Sub
I currently have a code set up to add an appointment to Outlook if a cell in Excel contains the word "No". What I would like to be able to do is delete an existing appointment if the same cell is changed to "N/A". I've tried to adapt some code I found elsewhere for this but can't get it to work, currently it's displaying "Compile error: next without for"
Sub DeleteCalendarItems()
Dim r As Long, i As Long, wb As Workbook
Dim ws As Worksheet
Dim objOutlook As Outlook.Application
Dim objNamespace As Outlook.Namespace
Dim objFolder As Outlook.MAPIFolder
Dim objAppointment As Outlook.AppointmentItem
Dim strSubject As String
Set objOutlook = Outlook.Application
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderCalendar)
Set oItems = objFolder.Items
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Section 74")
r = ws.Cells(Rows.Count, 1).End(xlUp).Row 'Rows.Count should also have a reference to a wb & ws
For i = 2 To r
If ws.Cells(i, 9) = "N/A" Then
ws.Cells(i, 13) = "Yes"
Set objAppointment = oItems.Item(i)
With objAppointment
If .Subject = strSubject Then
objAppointment.Delete
End If
End With
End If
Next i
End Sub
A With, If and For statement (and more) should always be closed
Sub DeleteCalendarItems()
Dim wb As Workbook
Dim ws As Worksheet
Dim objOutlook As Outlook.Application
Dim objNamespace As Outlook.Namespace
Dim objFolder As Outlook.MAPIFolder
Dim objAppointment As Outlook.AppointmentItem
Dim strSubject As String
Set objOutlook = Outlook.Application
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderCalendar)
Set oItems = objFolder.Items
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Section 74")
r = ES.Cells(Rows.Count, 1).End(xlUp).Row 'Rows.Count should also have a reference to a wb & ws
For i = 2 To r
If ES.Cells(i, 9).Value = "N/A" Then
Set objAppointment = oItems.Item(i)
With objAppointment
If .Subject = strSubject Then
objAppointment.Delete
End If
End With
End If
Next i
End Sub
I've managed to work it out (somehow) - I needed to add a nested For loop
Sub DeleteNASec74()
Dim i As Long, j As Long
Dim wb As Workbook
Dim ws As Worksheet
Dim objOutlook As Outlook.Application
Dim objNamespace As Outlook.Namespace
Dim objFolder As Outlook.MAPIFolder
Dim objAppointment As Outlook.AppointmentItem
Set objOutlook = Outlook.Application
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderCalendar)
Set oItems = objFolder.Items
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Section 74")
r = ws.Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To r
For j = oItems.Count To 1 Step -1
If ws.Cells(i, 9).Value = "N/A" Then
ws.Cells(i, 13) = "Yes"
Set objAppointment = oItems.Item(j)
With objAppointment
If .Subject = "Send reminder email - " + ws.Cells(i, 2).Value Then
objAppointment.Delete
End If
End With
End If
Next j
Next i
End Sub
I am trying to use the code below to update my Outlook calendar from an Excel sheet.
The code functions fine, but I need to save to a sub calendar rather than my default one.
I've tried a few work around's I found online,but none of them seem to work. For example Slapstick and also at the bottom of this page Ozgrid
Any help would be much appreciated.
Option Explicit
Sub AddToOutlook()
Dim OL As Outlook.Application
Dim olAppt As Outlook.AppointmentItem
Dim NS As Outlook.Namespace
Dim colItems As Outlook.Items
Dim olApptSearch As Outlook.AppointmentItem
Dim r As Long, sBody As String, sSubject As String, sLocation As String
Dim dStartTime As Date, dEndTime As Date, dReminder As String, dCatagory As Double
Dim sSearch As String, bOLOpen As Boolean
On Error Resume Next
Set OL = GetObject(, "Outlook.Application")
bOLOpen = True
If OL Is Nothing Then
Set OL = CreateObject("Outlook.Application")
bOLOpen = False
End If
Set NS = OL.GetNamespace("MAPI")
Set colItems = NS.GetDefaultFolder(olFolderCalendar).Items
For r = 2 To 394
If Len(Sheet1.Cells(r, 1).Value + Sheet1.Cells(r, 5).Value) = 0 Then
GoTo NextRow
sBody = Sheet1.Cells(r, 7).Value
sSubject = Sheet1.Cells(r, 3).Value
dStartTime = Sheet1.Cells(r, 1).Value + Sheet1.Cells(r, 2).Value
dEndTime = Sheet1.Cells(r, 1).Value + Sheet1.Cells(r, 5).Value
sLocation = Sheet1.Cells(r, 6).Value
dReminder = Sheet1.Cells(r, 4).Value
sSearch = "[Subject] = " & sQuote(sSubject)
Set olApptSearch = colItems.Find(sSearch)
If olApptSearch Is Nothing Then
Set olAppt = OL.CreateItem(olAppointmentItem)
olAppt.Body = sBody
olAppt.Subject = sSubject
olAppt.Start = dStartTime
olAppt.End = dEndTime
olAppt.Location = sLocation
olAppt.Catagory = dCatagory
olAppt.Close olSave
End If
NextRow:
Next r
If bOLOpen = False Then OL.Quit
End Sub
Function sQuote(sTextToQuote)
sQuote = Chr(34) & sTextToQuote & Chr(34)
End Function
To get access to a subfolder in your default calendar folder you can use:
Set colItems = NS.GetDefaultFolder(olFolderCalendar).Folders("TypeNameOfCalendarHere").Items
If it is on the same level as teh default folder you can use:
Set colItems = NS.GetDefaultFolder(olFolderCalendar).Parent.Folders("SharedCal").Items
Good resource here and here.
As described in the Ozgrid link, move the appointment created in the default calendar to the sub calendar.
You can reference a calendar with the entry ID.
Set oFolder = oNameSpace.GetFolderFromID("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
You can reference a sub Calendar of the default folder:
Set oFolder = NS.GetDefaultFolder(olFolderCalendar).folders("Name of sub calendar")
Once created in the default calendar move it to the non-default calendar
Set olApt = oApp.CreateItem(olAppointmentItem)
With olApt
' ..
.Save
.Move oFolder
End With
You may add to a non-default calendar.
Set subCalendar = NS.GetDefaultFolder(olFolderCalendar).folders("Name of sub calendar")
Set olAppt = subCalendar.items.Add
With olAppt
'...
.Save
End With