Exporting Outlook Tasks to Excel


In an earlier post I showed a number of ways to export Outlook messages to Excel. Mitesh saw that post and asked if it’d be possible to adapt it to export Outlook tasks instead of messages. The answer of course is “yes”. In fact you could adapt the code from the original post to export any of Outlook’s basic item types (i.e. appointments, contacts, messages, notes, tasks). All Mitesh needs to do is change the list of item properties the code will export. Where an email has properties called “Subject”, “ReceivedTime”, and “SenderEmailAddress” (to name a few), a task has “Subject”, “StartDate”, and “DueDate”. In order to change the script to handle a different item type you need to know what properties an Outlook item of that type has. Microsoft has pages on its site that list the complete set of a task item’s properties for Outlook 2007, Outlook 2010, and Outlook 2013. For this example I’ve chosen a subset of task properties. You can add, delete, and/or rearrange them to suit your needs.

Some properties (e.g. DelegationState, Ownership) are enumerations. An enumeration stores a numeric value that equates to something. For example, a 0 in DelegationState means the task is not delegated while a 2 means that the task has been delegated and the person it is delegated to has accepted it. Rather than exporting the numeric value stored in an enumerated property, I wrote functions that returns a more meaningful value in plain English. I only wrote those functions for enumerated fields I used in this example. There are other enumerated fields that would benefit from a similar conversion if you include them in your export. Once again, you can refer to Microsoft’s documentation to see which properties are enumerated and to get the available values and what they stand for.


Adding the code to Outlook.

  1. Start Outlook
  2. Press ALT+F11 to open the Visual Basic Editor
  3. If not already expanded, expand Microsoft Office Outlook Objects
  4. If not already expanded, expand Modules
  5. Select an existing module (e.g. Module1) by double-clicking on it or create a new module by right-clicking Modules and selecting Insert > Module.
  6. Copy the code from the code snippet box and paste it into the right-hand pane of Outlook’s VB Editor window
  7. Click the diskette icon on the toolbar to save the changes
  8. Close the VB Editor
Sub ExportTasksToExcel()
    Const SCRIPT_NAME = "Export Tasks to Excel"
    Dim olkTsk As Object, _
        excApp As Object, _
        excWkb As Object, _
        excWks As Object, _
        lngRow As Long, _
        lngCnt As Long, _
        strFilename As String
    strFilename = InputBox("Enter a filename (including path) to save the exported tasks to.", SCRIPT_NAME)
    If strFilename = "" Then
        MsgBox "The filename is blank.  Export aborted.", vbInformation + vbOKOnly, SCRIPT_NAME
    Else
        Set excApp = CreateObject("Excel.Application")
        Set excWkb = excApp.Workbooks.Add()
        Set excWks = excWkb.ActiveSheet
        'Write Excel Column Headers
        With excWks
            .Cells(1, 1) = "Subject"
            .Cells(1, 2) = "Created On"
            .Cells(1, 3) = "Start Date"
            .Cells(1, 4) = "Due Date"
            .Cells(1, 5) = "Date Complete"
            .Cells(1, 6) = "% Complete"
            .Cells(1, 7) = "Delegation State"
            .Cells(1, 8) = "Delegator"
            .Cells(1, 9) = "Owner"
            .Cells(1, 10) = "Ownership"
            .Cells(1, 11) = "Role"
            .Cells(1, 12) = "Response State"
        End With
        lngRow = 2
        'Write tasks to spreadsheet
        For Each olkTsk In Application.ActiveExplorer.CurrentFolder.Items
            'Add a row for each task item property you want to export.  Rearrange the rows as desired.  Remember to edit the column number you want each property to appear in.
            excWks.Cells(lngRow, 1) = olkTsk.Subject
            excWks.Cells(lngRow, 2) = olkTsk.CreationTime
            excWks.Cells(lngRow, 3) = olkTsk.StartDate
            excWks.Cells(lngRow, 4) = olkTsk.DueDate
            excWks.Cells(lngRow, 5) = olkTsk.DateCompleted
            excWks.Cells(lngRow, 6) = olkTsk.PercentComplete
            excWks.Cells(lngRow, 7) = GetDelegationState(olkTsk.DelegationState)
            excWks.Cells(lngRow, 8) = olkTsk.Delegator
            excWks.Cells(lngRow, 9) = olkTsk.Owner
            excWks.Cells(lngRow, 10) = GetOwnership(olkTsk.Ownership)
            excWks.Cells(lngRow, 11) = olkTsk.Role
            excWks.Cells(lngRow, 12) = GetResponseState(olkTsk.ResponseState)
            lngRow = lngRow + 1
            lngCnt = lngCnt + 1
        Next
        Set olkTsk = Nothing
        excWkb.SaveAs strFilename
        excWkb.Close
        MsgBox "Process complete.  A total of " & lngCnt & " tasks were exported.", vbInformation + vbOKOnly, SCRIPT_NAME
    End If
    Set excWks = Nothing
    Set excWkb = Nothing
    Set excApp = Nothing
End Sub

Function GetDelegationState(intState As Integer) As String
    Select Case intState
        Case 0
            GetDelegationState = "Not delegated"
        Case 1
            GetDelegationState = "Unknown"
        Case 2
            GetDelegationState = "Accepted"
        Case 3
            GetDelegationState = "Declined"
    End Select
End Function

Function GetOwnership(intState As Integer) As String
    Select Case intState
        Case 0
            GetOwnership = "New Task"
        Case 1
            GetOwnership = "Delegated Task"
        Case 2
            GetOwnership = "Own Task"
    End Select
End Function

Function GetResponseState(intState As Integer) As String
    Select Case intState
        Case 0
            GetResponseState = "Simple"
        Case 1
            GetResponseState = "Reassigned"
        Case 2
            GetResponseState = "Accepted"
        Case 3
            GetResponseState = "Declined"
    End Select
End Function

Using the Code.

  1. With Outlook open select a folder that contains tasks.
  2. Run the macro ExportTasksToExcel.
  3. When prompted, enter a file name to save the export to. You can cancel the export by leaving the file name blank.
  4. The macro will display a dialog-box when it’s finished. The dialog-box includes a count of the number of tasks exported.

Notes.

  • This code can easily be modified to export a different set of fields. To do that, change the headings written to the spreadsheet (lines 19-30) and the message fields (lines 36-47).
  • If you don’t want the macro to prompt for a file name each time, then you can change line 10 to strFilename = “Path_and_File_Name”
About these ads

23 comments on “Exporting Outlook Tasks to Excel

  1. Hey- thanks for your code, it is working great on my end— One question – I want it to skip tasks that have been marked as completed. I know the easy fix would be to delete items when completed, but I need to go back to review completion time at a later date. I am guessing an If … Then statement based on the value of the complete field….

    • You’re welcome, Tim!

      That’s simple enough to do. Insert this line of code after line 34

      If Not olkTsk.Complete Then
      

      and this line after the current line 49

      End If
      

      With those two lines added in the script will now ignore any task that’s complete.

  2. Great work!
    This works perfect, BUT…
    I would also like to have all the data in the “message/textbox” for each task exported.
    My scripting skills are at a copt/paste level so I appreciate all help!

    Best regards,
    Per

    • Hi, Per.

      That’s simple enough. Add a line like this somewhere between lines 36 and 47 of the original code. Add a corresponding header somewhere between lines 19 and 30. Just copy one of the headers in that range and change the column title as desired.

      'On the next line replace X with a column number
      excWks.Cells(lngRow, X) = olkTsk.Body
      
  3. Hi David

    I have kept the names of the UDF and the property of the control are exactly the same. Are there any declarations that need to be done before hand? Kind regards

    • Mitesh,

      No, there are no declarations involved. Are you sure about the property name? The property name is whatever appears next to “Choose Field” on the “Value” tab of the control’s properties.

    • Hi David,

      Thats the name I have selected. It’s a list box for which I have entered possible values, which will allow the user to select a value (I have entered these in the possible value field section in the value tab)- I’m not sure if this has affected it

      Secondly, within the field chooser where you can choose fields from various, my UDF’s appear under the ‘User Defined Fields in this folder’

      Best Regards

      Mitesh

    • Mitesh,

      Do all the tasks your exporting use that same form? If not, then that would explain the error.

      Yep, that’s the right place.

    • Hi David

      Yes, the task uses that form, when you select ‘New Task’ from the group inbox it selects the form that I have created. Although there are 2 other task forms previously used, the current task from (the one for which I’d like to export data from) comes up as default

      Is there any other way of ensuring that i.e. in the VBA to look in the specfic task form

      Best Regards

      Mitesh

    • Hi, Mitesh.

      Yes, we can restrict the code to working against that one form type. Replace the subroutine ExportTasksToExcel with the version below. Please be sure to edit the name of you form as per the comment I included in the code. You’ll also need to add the code for exporting your custom form fields.

      Sub ExportTasksToExcel()
          Const SCRIPT_NAME = "Export Tasks to Excel"
          Dim olkTsk As Outlook.TaskItem, _
              excApp As Object, _
              excWkb As Object, _
              excWks As Object, _
              lngRow As Long, _
              strFilename As String
          strFilename = InputBox("Enter a filename (including path) to save the exported tasks to.", SCRIPT_NAME)
          If strFilename <> "" Then
              Set excApp = CreateObject("Excel.Application")
              Set excWkb = excApp.Workbooks.Add()
              Set excWks = excWkb.ActiveSheet
              'Write Excel Column Headers
              With excWks
                  .Cells(1, 1) = "Subject"
                  .Cells(1, 2) = "Created On"
                  .Cells(1, 3) = "Start Date"
                  .Cells(1, 4) = "Due Date"
                  .Cells(1, 5) = "Date Complete"
                  .Cells(1, 6) = "% Complete"
                  .Cells(1, 7) = "Delegation State"
                  .Cells(1, 8) = "Delegator"
                  .Cells(1, 9) = "Owner"
                  .Cells(1, 10) = "Ownership"
                  .Cells(1, 11) = "Role"
                  .Cells(1, 12) = "Response State"
              End With
              lngRow = 2
              'Write tasks to spreadsheet
              For Each olkTsk In Application.ActiveExplorer.CurrentFolder.Items
                  'On the next line replace YourFormName with the name of your form
                  If Item.MessageClass = "IPM.Task.YourFormName" Then
                      'Add a row for each task field you want to export
                      excWks.Cells(lngRow, 1) = olkTsk.Subject
                      excWks.Cells(lngRow, 2) = olkTsk.CreationTime
                      excWks.Cells(lngRow, 3) = olkTsk.StartDate
                      excWks.Cells(lngRow, 4) = olkTsk.DueDate
                      excWks.Cells(lngRow, 5) = olkTsk.DateCompleted
                      excWks.Cells(lngRow, 6) = olkTsk.PercentComplete
                      excWks.Cells(lngRow, 7) = GetDelegationState(olkTsk.DelegationState)
                      excWks.Cells(lngRow, 8) = olkTsk.Delegator
                      excWks.Cells(lngRow, 9) = olkTsk.Owner
                      excWks.Cells(lngRow, 10) = GetOwnership(olkTsk.Ownership)
                      excWks.Cells(lngRow, 11) = olkTsk.Role
                      excWks.Cells(lngRow, 12) = GetResponseState(olkTsk.ResponseState)
                      lngRow = lngRow + 1
                  End If
              Next
              Set olkTsk = Nothing
              excWkb.SaveAs strFilename
              excWkb.Close
          End If
          Set excWks = Nothing
          Set excWkb = Nothing
          Set excApp = Nothing
          MsgBox "Process complete.  A total of " & lngRow - 2 & " tasks were exported.", vbInformation + vbOKOnly, SCRIPT_NAME
      End Sub
      
  4. Thanks a lot that David

    Just one final query, I have a custom Task form made with user defined fields. Everytime I list the user defined field in the code, it doesn’t recongise the field.

    I’m assuming it needs to be delcared but I have no knowledge of the syntax

    Best Regards

    • You’re welcome, Mitesh.

      You can include user-defined fields by adding a line like this for each one.

      'On the next line replace X with a column number and UDF Name with the name of the user-defined field
      excWks.Cells(lngRow, X) = olkTsk.UserProperties.Item("UDF Name").Value
      
    • Hi David, VBA doesn’t seem to recongise the object

      I get an error:

      Run-time error ’91′
      Object Variable or With Block variable not set

    • Mitesh,

      My best guess is that the UDF Name is wrong. Did you use the name of the control on the form or the name of the property the control is bound to? You want the latter. Controls don’t store information, they only display it.

  5. Sorry to keep bombarding you with questions David, when exporting tasks, is it possible to only select upon criteria, for example, only export tasks which have the ‘red’ category?

    Many Thanks in advance

    • Mitesh,

      Yes, that’s possible. Assuming that the category name (e.g. “Red”) is unique (i.e. does not appear as a substring of another category name), then we accomplish this by enclosing lines 36-49 in an IF … END IF statement. Something like this

      If InStr(1, olkTsk.Categories, "Red") > 0 Then
          (lines 36-49)
      End If
      
  6. Hi David

    Is there any way for getting the code to point to a Shared inbox, I have tried selecting the shared inbox when running the code but it seems to only export my personal tasks rather than the inbox tasks

    Many Thanks

    • Mitesh,

      Yes, but it’d be simpler to go back to the original code and simply select the folder you want to export from instead of making that change in code. That said, you’ll need to add the following bit of code to what you already have.

      Function OpenOutlookFolder(strFolderPath As String) As Outlook.MAPIFolder
          ' Purpose: Opens an Outlook folder from a folder path.
          ' Written: 4/24/2009
          ' Author:  David Lee
          ' Outlook: All versions
          Dim arrFolders As Variant, _
              varFolder As Variant, _
              bolBeyondRoot As Boolean
          On Error Resume Next
          If strFolderPath = "" Then
              Set OpenOutlookFolder = Nothing
          Else
              Do While Left(strFolderPath, 1) = "\"
                  strFolderPath = Right(strFolderPath, Len(strFolderPath) - 1)
              Loop
              arrFolders = Split(strFolderPath, "\")
              For Each varFolder In arrFolders
                  Select Case bolBeyondRoot
                      Case False
                          Set OpenOutlookFolder = Outlook.Session.Folders(varFolder)
                          bolBeyondRoot = True
                      Case True
                          Set OpenOutlookFolder = OpenOutlookFolder.Folders(varFolder)
                  End Select
                  If Err.Number <> 0 Then
                      Set OpenOutlookFolder = Nothing
                      Exit For
                  End If
              Next
          End If
          On Error GoTo 0
      End Function
      

      Once you’ve added that code, then modify line 34 to this

      'On the next line enter the path to the shared task folder.  The path must point to a task folder, not an inbox.
      For Each olkTsk In OpenOutlookFolder("path to the shared task folder").Items
      

      In case you aren’t familiar with Outlook paths, here’s how they work. A folder path in Outlook is essentially the same as a folder path in the file system. The one difference being that Outlook folder paths do not include a drive letter. The path to a folder is a list of all the folders from the root to the target folder with each folder name separated from the preceding folder name by a backslash (i.e. \). Consider the following folder structure:

      Mailbox – Doe, John
      – Calendar
      – Inbox
      – Tasks
      Personal Folders
      + Marketing
      + Proposals
      + Reviews
      + Projects
      + Project 1
      + Project 2

      The path to “Inbox” is “Mailbox – Doe, John\Inbox”.
      The path to “Reviews” is “Personal Folders\Marketing\Reviews”.
      The path to “Project 1″ is “Personal Folders\Projects\Project 1″.

  7. Hi David

    Good Result! I found the error,

    Line 34 needs to be changed to the following

    For Each olkTsk In Session.GetDefaultFolder(olFolderTasks).Items

    Thanks a lot for your help

    Mitesh

    • Hi, Mitesh.

      Changing line #34 from

      For Each olkTsk In Application.ActiveExplorer.CurrentFolder.Items

      to
      For Each olkTsk In Session.GetDefaultFolder(olFolderTasks).Items

      restricts the code to operating against just the default task folder. Leaving the code as I posted it allows the code to work against any task folder. You just need to remember to select a task folder before running the code.

  8. Hi David

    Many Thanks for your invaluable support for taking the time out and posting this solution

    I am trying to execute the code but keep getting the folowing error message;

    Run Time Error ’438′:
    Object doesn’t support this property or Method

    These were basically Outlook items that it didn’t recongise, for example the following fine,
    1) Subject
    2) Creation Time

    The rest of the properties i.e. StartDate, DueDate, DateCompleted etc. were the properties that were causing the code to fail. I removed these from the code and it seemed to have worked, however when I opened up the exported Excel file, I found that my Email messages were copied over rather than the tasks

    I suspect that somewhere in the code, its pointing at Email items rather than Tasks?

    Many Thanks in Advance

    Mitesh

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s