Retrieve user's Outlook status

1.4k views Asked by At

I found VBScript code to retrieve a user's Outlook status and display in a list box. I need it to be C# and there are no conversion tools online:

Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")

Set objRecipient = objNameSpace.CreateRecipient("kenmyer")
strFreeBusyData = objRecipient.FreeBusy(#11/11/2014#, 60)

dtmStartDate = #11/11/2014#

For i = 1 to Len(strFreeBusyData) Step 24 
    Wscript.Echo dtmStartDate
    strDay = Mid(strFreeBusyData, i, 24)

    For x = 1 to 12
        If x = 1 Then
            strTime = "12 AM: "
        Else
            strTime = x - 1 & " AM: "
        End If 

        intFreeBusy = Mid(strDay, x, 1)
        If intFreeBusy = 1 Then
            strFreeBusy = "Busy"
        Else
            strFreeBusy = "Free"
        End If

        Wscript.Echo strTime & strFreeBusy
    Next

    For x = 13 to 24
        If x = 13 Then
            strTime = "12 PM: "
        Else
            strTime = x - 13 & " PM: "
        End If 

        intFreeBusy = Mid(strDay, x, 1)
        If intFreeBusy = 1 Then
            strFreeBusy = "Busy"
        Else
            strFreeBusy = "Free"
        End If

        Wscript.Echo strTime & strFreeBusy
    Next

    Wscript.Echo
    dtmStartDate = dtmStartDate + 1

    If dtmStartDate > #11/12/2014# Then
        Exit For
    End If
Next

The end result would look like this in my C# application under the appointments list box:

11/11/2014
8 AM: Free
9 AM: Free
10 AM: Free
11 AM: Free
12 PM: Free
1 PM: Free
2 PM: Free
3 PM: Free
4 PM: Free
5 PM: Busy
6 PM: Free

What I have so far:

private void userschedule()
{
    Outlook.Application oApp = new Outlook.Application();

    Microsoft.Office.Interop.Outlook.NameSpace ns = oApp.Application.Session;

    Outlook.Recipient recipient = ns.CreateRecipient(username.Text);

    DateTime datetime = DateTime.Now;

    string freeBusy = recipient.AddressEntry.GetFreeBusy(datetime, 60, true);

    string status = freeBusy.Substring(0, 1);

    textBox1.Text = status;
}

How can I convert this to C#? The other set of code is similar:

For i = 1 to Len(strFreeBusyData) Step 24 
    Wscript.Echo dtmStartDate
    strDay = Mid(strFreeBusyData, i, 24)

    For x = 1 to 12
        If x = 1 Then
            strTime = "12 AM: "
        Else
            strTime = x - 1 & " AM: "
        End If 

        intFreeBusy = Mid(strDay, x, 1)
        If intFreeBusy = 1 Then
            strFreeBusy = "Busy"
        Else
            strFreeBusy = "Free"
        End If

        Wscript.Echo strTime & strFreeBusy
    Next

Newly Edited Code ( Final Answer to my Question)

private void userstatus()
{
    {
        {
            Outlook.Application oApp = new Outlook.Application();
            Microsoft.Office.Interop.Outlook.NameSpace ns = oApp.Application.Session;
            Outlook.Recipient recipient = ns.CreateRecipient(username.Text);
            DateTime datetime = DateTime.Now; // gets current date and time
            DateTime startDate = DateTime.Today; //gets todays date
            startDate.AddHours(8); //Skip to 8 am
            string freeBusy = recipient.AddressEntry.GetFreeBusy(startDate, 60, true);
            textBox1.Text = freeBusy;

            foreach (char c in freeBusy) //iteration process
            {
                if (startDate.Hour == 0) //start at 12 AM
                    Contacts.Items.Add(startDate.ToString("dd/MM/yyyy"));
                if (8 <= startDate.Hour && startDate.Hour <= 18) // 8AM to 6PM inclusive
                {
                    listBox1.Items.Add(
                        String.Format(
                            "{0}: {1}",
                            startDate.ToString("hh tt"),
                            c == '0' ? "Free" : "Busy"));
                }
                startDate = startDate.AddHours(1);
                if (startDate.Date > DateTime.Today)
                    break; // stop once we get to tomorrow.
            }
        }
    }
    private void button5_Click(object sender, EventArgs e)
    {
        userstatus();
    }

The freeBusy string looks like this for the user I am getting the free/busy status for.

I got the below by doing this:

string freeBusy = recipient.AddressEntry.GetFreeBusy(datetime, 60, true);
textBox1.Text = freeBusy;

000000002200000000000000000000002200000000000000333333333333333333333333000000000000000000000000000000000000000000000000000000002000001100000000000000002000001000000000000000002000000000000000000000002022200000000000000000002000001000000000000000000000000000000000000000000000000000000000333333333333333333333333000000002001101000000000000000002000000000000000000000002000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000002000001100000000000000002000000000000000000000002000000000000000000000002020000000000000000000002000001000000000000000000000000000000000000000000000000000000000000000002000001100000000000000002000000000000000000000002000000000000000000000002000000000000000

1

There are 1 answers

25
juharr On BEST ANSWER

The following for loop and logic in VBScript

For i = 1 to Len(strFreeBusyData) Step 24 
    Wscript.Echo dtmStartDate
    strDay = Mid(strFreeBusyData, i, 24)
    ...
Next

would be equivalent to the following in C#

for(int i = 0; i < strFreeBusyData.Length; i+= 24)
{
    Console.WriteLine(dtmStartDate);
    var strDay = strFreeBusyData.Substring(i, 24);
    ...   
}

One big difference between VBScript and C# is that VBScript tends to be 1 - based when dealing with strings, whereas C# is 0 based. Specifically the Mid function's first parameter wants an index into the string that is 1-based (1 would mean start at the first character) whereas string.Substrings first parameter should be 0-based (0 would mean start at the first character).

EDIT

After sleeping on it a better way of dealing with this in C# would be the following.

DateTime startDate = DateTime.Today;
string freeBusy = recipient.AddressEntry.GetFreeBusy(datetime, 60, true);
foreach(char c in freeBusy)
{
    if(startDate.Hour == 0)
        Console.WriteLine(startDate.ToString("dd/MM/yyyy"));
    Console.WriteLine(
        "{0}: {1}",
        startDate.ToString("hh tt"),
        c == '1' ? "Busy" : "Free");
    startDate = startDate.AddHours(1);
}

This will get a DateTime that has today's date, but a time of 12 am. Then as you iterate over each character in the freeBusy string you will output the startDate formatted as dd/MM/yyyy when the hour is 0 or 12 am. Then you write out the hour in 12 hour time (hh) and the AM/PM designator (tt) and the word Busy if the character is "1" or Free otherwise. Then increment the startDate by one hour. This avoids the unnecessary inner for loops that the VBScript code has.

EDIT

Based on your updated code you should change this

listBox1.Items.Add("{0}: {1}") ;
listBox1.Items.Add(startDate.ToString("hh tt") + " " + (c == '1' ? "Busy" : "Free"));
listBox1.Items.Add(c == '1' ? "Busy" : "Free");
startDate.AddHours(1);

to this

listBox1.Items.Add(
    string.Format(
        "{0}: {1}", 
        startDate.ToString("hh tt"),
        c == '1' ? "Busy" : "Free");
startDate = startDate.AddHours(1);

The "{0}: {1}" is for formatting and Console.WriteLine has an overload that takes a format string. The date wasn't changing because DateTime is immuteable and you have to capture the return value of AddHours, that was my bad.

Edit

Here's code that will only show items for today and only between 8am and 6pm

foreach (char c in freeBusy) //iteration process
{
    if (startDate.Hour == 0 ) //start at 12 AM
        Contacts.Items.Add(startDate.ToString("dd/MM/yyyy"));
    if(8 <= startDate.Hour && startDate.Hour <= 18) // 8AM to 6PM inclusive
    {
        listBox1.Items.Add(
            String.Format(
            "{0}: {1}", 
            startDate.ToString("hh tt"),
            c == '1' ? "Busy" : "Free"));
    }

    startDate = startDate.AddHours(1);
    if(startDate.Date > DateTime.Today)
        break; // stop once we get to tomorrow.
}

You can optimize this to break after you hit 6PM if you want. It could also be shortened to the following

DateTime startDate = DateTime.Today; //gets todays date
string freeBusy = recipient.AddressEntry.GetFreeBusy(datetime, 60, true);
Contacts.Items.Add(startDate.ToString("dd/MM/yyyy")); 
startDate = startDate.AddHours(8); //Skip to 8 am
foreach (char c in freeBusy.Skip(8).Take(11)) // skip to 8AM and only go to 6PM
{
    listBox1.Items.Add(
        String.Format(
            "{0}: {1}", 
            startDate.ToString("hh tt"),
            c == '0' ? "Free" : "Busy"));

    startDate = startDate.AddHours(1);
}

EDIT

Changed

c == '1' ? "Busy" : "Free"

to

c == '0' ? "Free" : "Busy"