Creating calendar entries in outlook from VB userform/excel

philfloyduk

Board Regular
Joined
Jan 6, 2011
Messages
82
I have a repair booking form in visual basic that feeds in to an excel sheet that I would like to automatically create calendar entries in outlook. Ideally, the next free hourly slot would be taken (our repairs are put on to the day then organised in the morning). The form has a textbox that the user enters the appointment date in via calendar control 12.0. The form currently populates all the information needed from the text boxes in to a cell, copies the information then prompts the user to paste it to the Calendar.

Many thanks in advance for any help


Phil.
 
...how straight forward is it to make a spreadsheet work on two computers and be used at the same time?
You'd have to set the workbook up as shared:-

http://office.microsoft.com/en-us/excel-help/administration-of-shared-workbooks-HA001013057.aspx

Will both computers be using the same Outlook Calendar? I assume 'yes'.

The only problem I can foresee is if two people hit the button at the same time and both computers receive notification that a particular slot is free and then both computers create appointments for that slot.

If that's possible and undesirable, then after creating an appointment in what was supposed to be a free slot, the program would have to check whether there were suddenly two appointments in it and resolve that by deleting the one it had created and looking for the next free slot again.

Meanwhile presumably the second computer would be taking the same action, so the two machines would contend for the slot until one was successful in taking sole control over it.
 
Upvote 0

Excel Facts

Which Excel functions can ignore hidden rows?
The SUBTOTAL and AGGREGATE functions ignore hidden rows. AGGREGATE can also exclude error cells and more.
Fantastic. I'll look at this tomorrow or Monday depending on how much work the misses let's me get away with doing when I should be relaxing and let you know.

Thanks,

Phil
 
Upvote 0
You're my hero! It takes roughly 5-6 seconds, which is how long the last code took to find an appointment at 9:00.

Much appreciated :biggrin:
 
Upvote 0
After posting this I realised it wasn't putting the slot in the correct place. I worked out the problem, and now it takes 37 seconds. I can't work out if it's better to make the user select the slot or wait the time for it to find it's own.

In case I decide to go with the user selecting it, how would I get the code to select the time slot from one that was selected in the form from a combobox? I tried to do that on friday and by using:

.Start = appdateTextBox.Value + slotcombobox.value

it won't work. Is it because I need to format the value of slotcombobox, if so how would I format ot correct value?

Thanks


Phil
 
Upvote 0
Textboxes are only ever text, even if they look like dates or times. If you want to store them in a date type variable, you have to convert them to dates using the DATEVALUE function which converts a string which looks like a date into an actual Excel date. TIMEVALUE does the same for times.

So if appdateTextBox holds a date and slotcombobox holds a time:-
Code:
.Start = DATEVALUE(appdateTextBox.Value) + TIMEVALUE(slotcombobox.value)

If you're going the other way - putting date/time values from your worksheet into a userform, you need to use FORMAT:-
Code:
appdateTextBox.Value = Format([I]somedate[/I],"dd/mm/yyyy")
slotcombobox.value = Format([I]sometime[/I],"hh:nn:ss")

For dates, "mm" gives you "02" for February, "mmm" gives you "Feb", "mmmm" gives you "February".
 
Upvote 0
Hi again. Sorry to be a pain..... but I'm struggling to get this code to work.

If i set the appointment code to;

.Start = DateValue(appdateTextBox.Value)

then it creates the appointment without a problem, but if i use:

.Start = DateValue(appdateTextBox.Value) + TimeValue(slotTextBox.Value)

it will just create the appointment on today's date. Is there something I'm missing? Below is the function code I have on my form:

Public Function CreateAppointment2()

Dim oApp As Outlook.Application
Dim oNameSpace As Namespace
Dim oItem As AppointmentItem
Dim iLastRow As Long
Dim irow As Long

On Error Resume Next
Set oApp = GetObject("Outlook.Application")
If Err <> 0 Then
Set oApp = CreateObject("Outlook.Application")
End If

Set oNameSpace = oApp.GetNamespace("MAPI")

Set oItem = oApp.CreateItem(olAppointmentItem)
With oItem
.Subject = "Slot booked"
.Start = DateValue(appdateTextBox.Value) + TimeValue(slotTextBox.Value)
.Duration = 60
.AllDayEvent = False
.Importance = olImportanceNormal
.Location = "Workshop"
.ReminderSet = False
.Save
End With

Set oApp = Nothing
Set oNameSpace = Nothing
Set oItem = Nothing
CreateAppointment = True

End Function

I'm formatting the textbox using:

Private Sub appslotTextBox_Change()
If Len(appslotTextBox.Text) = 2 Then
appslotTextBox.Text = appslotTextBox.Text & ":"
appslotTextBox.SelStart = Len(appslotTextBox.Text)
End If
End Sub

Private Sub appslotTextBox_AfterUpdate()
appslotTextBox.Value = Format(appslotTextBox.Value, "hh:nn:ss")
End Sub

I'm using a command button to run the code.

Any ideas?

Phil
 
Upvote 0
It'll be in the data but I can't see it.

Just before the .Start command, insert these commands:-
Code:
Debug.Print appdateTextBox.Value; " "; DateValue(appdateTextBox.Value)
Debug.Print slotTextBox.Value; " ";  TimeValue(slotTextBox.Value)

These will print to the Immediate wondow (press Ctrl-G to open it).

BTW, is your form textbox called slotTextBox or appslotTextBox?

You may need to step through the code using the F8 key watching the values of your variables as they change to detect any unexpected values. Try to follow whether they're date/time values or formatted strings at each stage.

I'm sending you a private message.
 
Upvote 0
I was able to get the code posted below working in an existing spreadsheet however I'm hoping I can get some assistance with modifying it a bit.
It appears to make the assumption that all appointments will be 30 minutes long. For example if I have an existing appointment on my calendar at 8:00 lasting for 1 hour, the program tells me the next available "slot" is 8:30, when in reality it isn't until 9:00. I'm wondering how I can modify the code to recognize the actual next available free "slot".

Thank you in advance for any assistance.



I found the problem: the code reads the entire calendar for each appointment slot it checks, so checking the 9am slot takes twice as long as checking the 8.30am slot, checking the 9.30am slot takes three times as long, etc.

The new code looks like this: BookNextFreeSlot is a sample of the code you need to produce to check for the next free slot on a given day, and if one exists between opening time and closing time, book it with the specified duration:-
Code:
[FONT=Fixedsys]Option Explicit[/FONT]
 
[FONT=Fixedsys]Sub BookNextFreeSlot()[/FONT]
 
[FONT=Fixedsys]  Dim dtDateToCheck As Date
  Dim dtTimeToCheck As Date
  Dim iDuration As Integer
  Dim dtLastAppointment As Date
  
  Dim dtNextFreeSlot As Date
  
  dtDateToCheck = DateValue("[COLOR=red][B]26-Feb-2011[/B][/COLOR]")
  dtTimeToCheck = TimeValue("[COLOR=darkorange][B]08:30:00[/B][/COLOR]")
  iDuration = [/FONT][FONT=Fixedsys][COLOR=magenta][B]30
[/B][/COLOR]  dtLastAppointment = TimeValue("[COLOR=blue][B]17:30:00[/B][/COLOR]")
  
  dtNextFreeSlot = FindNextFreeSlot(dtDateToCheck + dtTimeToCheck, iDuration)
    
  If dtNextFreeSlot > dtDateToCheck + dtLastAppointment + TimeSerial(0, 0, 1) Then
    MsgBox "No free slots today!", vbOKOnly + vbExclamation
  Else
    If CreateAppointment(dtNextFreeSlot, iDuration) Then
      MsgBox "Appointment for " & Format(dtNextFreeSlot, "hh:nn") _
           & " on " & Format(dtNextFreeSlot, "d-mmm-yyyy") & " created", _
           vbOKOnly + vbInformation
    Else
      MsgBox "Problem creating appointment for " & Format(dtNextFreeSlot, "hh:nn") _
           & " on " & Format(dtNextFreeSlot, "d-mmm-yyyy"), vbOKOnly + vbExclamation
    End If
  End If[/FONT]
 
[FONT=Fixedsys]End Sub[/FONT]

FindNextFreeSlot is the procedure which returns the next free slot. It only reads the calendar once, storing the existing appointments for the specified day in an array, and then checks for free slots in the (very small and very fast) array.
Code:
[FONT=Fixedsys]Option Explicit[/FONT]
 
[FONT=Fixedsys]Public Function FindNextFreeSlot(ByVal argCheckDateTime As Date, ByVal argDuration As Integer) As Date[/FONT]
 
[FONT=Fixedsys]  Dim oApp As Outlook.Application
  Dim oNameSpace As Outlook.Namespace
  Dim oApptItem As Outlook.AppointmentItem
  Dim oFolder As Outlook.MAPIFolder
  Dim oMeetingoApptItem As Outlook.MeetingItem
  Dim oObject As Object
  
  Dim aStore() As Date
  Dim iPtr As Integer
  Dim bFound As Boolean
  
  On Error Resume Next
  ' check if Outlook is running
  Set oApp = GetObject("Outlook.Application")
  If Err <> 0 Then
    'if not running, start it
    Set oApp = CreateObject("Outlook.Application")
  End If
  
  Set oNameSpace = oApp.GetNamespace("MAPI")
  Set oFolder = oNameSpace.GetDefaultFolder(olFolderCalendar)
  
  ReDim aStore(0) As Date
  
  For Each oObject In oFolder.Items
    If oObject.Class = olAppointment Then
      Set oApptItem = oObject
      If Int(oApptItem.Start) = Int(argCheckDateTime) Then
        ReDim Preserve aStore(UBound(aStore) + 1) As Date
        aStore(UBound(aStore)) = oApptItem.Start
      End If
    End If
  Next oObject
  
  FindNextFreeSlot = argCheckDateTime
  Do
    iPtr = 1
    bFound = False
    For iPtr = 1 To UBound(aStore)
      If Format(aStore(iPtr), "dd/mm/yyyy hh:nn:ss") = Format(FindNextFreeSlot, "dd/mm/yyyy hh:nn:ss") Then
        bFound = True
        Exit For
      End If
    Next iPtr
    If bFound = False Then Exit Do
    FindNextFreeSlot = FindNextFreeSlot + TimeSerial(0, argDuration, 0)
    DoEvents
  Loop
  
  Set oApp = Nothing
  Set oNameSpace = Nothing
  Set oApptItem = Nothing
  Set oFolder = Nothing
  Set oObject = Nothing
   
End Function[/FONT]
And a slightly modified version of CreateAppointment:-
Code:
[FONT=Fixedsys]Option Explicit[/FONT]
 
[FONT=Fixedsys]Public Function CreateAppointment(ByVal argDateTime As Date, ByVal argDuration As Integer) As Long[/FONT]
 
[FONT=Fixedsys]  Dim oApp As Outlook.Application
  Dim oNameSpace As Namespace
  Dim oItem As AppointmentItem
  Dim iLastRow As Long
  Dim irow As Long
     
  On Error Resume Next
  Set oApp = GetObject("Outlook.Application")
  If Err <> 0 Then
    Set oApp = CreateObject("Outlook.Application")
  End If
  
  Set oNameSpace = oApp.GetNamespace("MAPI")
  
    Set oItem = oApp.CreateItem(olAppointmentItem)
    With oItem
      .Subject = "Slot booked"
      .Start = argDateTime
      .Duration = argDuration
      .AllDayEvent = False
      .Importance = olImportanceNormal
      .Location = "Workshop"
      .ReminderSet = False
      .Save
    End With
  
  Set oApp = Nothing
  Set oNameSpace = Nothing
  Set oItem = Nothing[/FONT]
[FONT=Fixedsys]  CreateAppointment = True
  
 End Function[/FONT]

Hopefully you can put this lot together! Please let me know if it's any faster than the previous version?
 
Last edited:
Upvote 0
hi, trying to use this code (thanks for putting it together by the way!). However, its not finding the next
available slot on my calender. Could i be missing something? ive set up a dummy 3 hour appointment for 17/12/2013 at 10:00
and the findnextfreeslot function is returning 17/12/2013 10:30 as the next free slot. I was expecting 13:00 hrs at the earliest.
Please advise.
 
Upvote 0
Wazimu13,
I don't remember too much about this - after I get something working I tend to purge it from my brain and move on to the next thing. However I do have the text from a message I sent to Ruddles after I got it working.

Here it is:
Praedico said:
It appears I spoke/wrote too soon. I was able to add code to the program to make it do what I wanted. If your interested - I changed argDuration in the FindNextFreeSlot module to the oApptItem.Duration which I added to the array, so instead of jumping ahead 30 minutes at a time it jumps ahead by the duration of the conflicting appointment.

I hope that helps you,
Praedico
 
Upvote 0

Forum statistics

Threads
1,224,597
Messages
6,179,808
Members
452,944
Latest member
2558216095

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top