Link to home
Start Free TrialLog in
Avatar of damoncf1234
damoncf1234

asked on

Modify existing VBScript that works in Office 2007 to work in both Office 2007 and 2010

Hello,

We have a vbscript that was created a few years ago (and modified a few times since then - thanks BlueDevilFan).  It works fine in Office 2007, but it has issues in Office 2010.  The script basically collects ‘appointments’ from several calendars located in Exchange public folders (for a specific date), then puts the results in an Excel spreadsheet (and sorts the items by start time).  

It works fine when we run it from a workstation with Office 2007 (running on XP workstations), but when we run it from a workstation with Office 2010  (and Win7 – but I think the issue is with Office 2010, not Win7), it doesn’t ‘restrict’ the items it collects to the date we specify – it appears to collect a week’s worth of appointments…  I’ve done some testing with various appointment/meeting times, lengths, etc., and it seems to have something to do with how the items are ‘restricted’ to the date we specify.  

It doesn’t seem to be an issue with connecting to the public folders, and finding the calendars, because it finds the appropriate meetings, but it finds/provides meetings for the entire week (or at least several days-worth, rather than the one day we specify).  And the same script still works fine in XP…  So I’m thinking it’s an issue with how the items are ‘collected’ or ‘restricted’ to the specific date – some change between Office/Outlook 2007 and 2010.  

We’d like to modify the existing script so that it will work in both Office 2007 and 2010.  

BlueDevilFan was very helpful in the past (and will probably be very familiar with how this works), if he’s available for comments.  For more background, the original question is located here:
https://www.experts-exchange.com/questions/26454432/convert-outlook-vba-to-vbs.html

Below is the existing VBScript (I changed the network locations, room names, and removed some of the additional calendar names).  

Thanks

Const olPublicFoldersAllPublicFolders = 18
On Error Resume Next
Dim olkApp, olkSes, olkFolder, olkItems, olkAppt, excApp, excWkb, excSht, excRng, lngRow, arrTitle, datDate

'Launch Outlook'
Set olkApp = CreateObject("Outlook.Application")
Set olkSes = olkApp.GetNamespace("MAPI")
olkSes.Logon "Outlook"

'Launch Excel and open the spreadsheet'
Set excApp = CreateObject("Excel.Application")
excApp.Visible = True
'version 2
Set excWkb = excApp.Workbooks.Open("\\somenetworkshare\MeetingsMaster.xltx")
Set excSht = excWkb.Worksheets(1)
    'Range("A2:U4450").SpecialCells(xlCellTypeConstants).ClearContents
    'If bolClearWorksheet Then
    Set excRng = excSht.Range("A1").CurrentRegion
    lngRow = excRng.Rows.count
    'excApp.Rows(2 & ":" & lngRow).Delete
    lngRow = 3

'Set date for schedule
datDate = InputBox("Enter the date you want to create a video schedule for:", "Export Calendars to Excel", Date)
excSht.Cells(1,1) = FormatDateHeader(datDate)

'Connect to and process the shared calendar - One'
Set olkFolder = olkSes.GetDefaultFolder(olPublicFoldersAllPublicFolders).Folders("Conference Rooms").Folders("Conference Room - One")
Set olkItems = olkFolder.Items.Restrict("[Start] >= '" & OutlookDateFormat(datDate & " 0:01am") & "' AND [Start] < '" & OutlookDateFormat(datDate & " 11:59pm") & "'")
olkItems.Sort "[Start]"
olkItems.IncludeRecurrences = True
For Each olkAppt In olkItems
    arrTitle = Split(olkAppt.Subject, " - ")
    excSht.Cells(lngRow, 1) = FormatHoursAndMinutes(olkAppt.Start) & "-" & FormatHoursAndMinutes(olkAppt.End)
    excSht.Cells(lngRow, 2) = "One"
    'excSht.Cells(lngRow, 3) = Replace((Trim(arrTitle(0))), "(One)", "", 1, -1, vbTextCompare)
    excSht.Cells(lngRow, 3) = Replace(Replace((Trim(arrTitle(0))), "(One)", "", 1, -1, vbTextCompare), "(TWO)", "", 1, -1, vbTextCompare)
    excSht.Cells(lngRow, 4) = Trim(arrTitle(2))
    excSht.Cells(lngRow, 5) = Trim(arrTitle(3))
    lngRow = lngRow + 1
Next

'Connect to and process the shared calendar - Two'
Set olkFolder = olkSes.GetDefaultFolder(olPublicFoldersAllPublicFolders).Folders("Conference Rooms").Folders("Conference Room-Two")
Set olkItems = olkFolder.Items.Restrict("[Start] >= '" & OutlookDateFormat(datDate & " 0:01am") & "' AND [Start] < '" & OutlookDateFormat(datDate & " 11:59pm") & "'")
olkItems.Sort "[Start]"
olkItems.IncludeRecurrences = True
For Each olkAppt In olkItems
    arrTitle = Split(olkAppt.Subject, " - ")
    excSht.Cells(lngRow, 1) = FormatHoursAndMinutes(olkAppt.Start) & "-" & FormatHoursAndMinutes(olkAppt.End)
    excSht.Cells(lngRow, 2) = "Two"
    excSht.Cells(lngRow, 3) = Replace((Trim(arrTitle(0))), "(Two)", "", 1, -1, vbTextCompare)
    'excSht.Cells(lngRow, 3) = Replace(Replace((Trim(arrTitle(0))), "(Exec)", "", vbTextCompare), "(TWO)", "")
    excSht.Cells(lngRow, 4) = Trim(arrTitle(2))
    excSht.Cells(lngRow, 5) = Trim(arrTitle(3))
    lngRow = lngRow + 1
Next

'Connect to and process the shared calendar - Some Office'
Set olkFolder = olkSes.GetDefaultFolder(olPublicFoldersAllPublicFolders).Folders("Conference Rooms").Folders("Some Office")
Set olkItems = olkFolder.Items.Restrict("[Start] >= '" & OutlookDateFormat(datDate & " 0:01am") & "' AND [Start] < '" & OutlookDateFormat(datDate & " 11:59pm") & "'")
olkItems.Sort "[Start]"
olkItems.IncludeRecurrences = True
For Each olkAppt In olkItems
    arrTitle = Split(olkAppt.Subject, " - ")
    excSht.Cells(lngRow, 1) = FormatHoursAndMinutes(olkAppt.Start) & "-" & FormatHoursAndMinutes(olkAppt.End)
    excSht.Cells(lngRow, 2) = "Some Office"
    excSht.Cells(lngRow, 3) = Replace((Trim(arrTitle(0))), "(Some Office)", "")
    excSht.Cells(lngRow, 4) = Trim(arrTitle(2))
    excSht.Cells(lngRow, 5) = Trim(arrTitle(3))
    lngRow = lngRow + 1
Next

'excSht.Range("A:E").Sort Key1:=excSht.Range("A:A"), Order1:=1
' works minus header row - excSht.Range("A:E").Sort excSht.Range("A:A"), 1
excSht.Range("A3:G107").Sort excSht.Range("A:A"), 1
' (with 1 header row) excSht.Range("A:E").Sort excSht.Range("A:A"), 1,,,,,,1 

'Save the spreadsheet and exit Excel'
Set excRng = Nothing
Set excSht = Nothing
'excWkb.Save
Set excWkb = Nothing
'excApp.Quit
Set excApp = Nothing

'Clean-up the Outlook objects'
Set olkFolder = Nothing
Set olkItems = Nothing
Set olkAppt = Nothing
olkSes.Logoff
Set olkSes = Nothing
Set olkApp = Nothing

'Prompting user to save file
msgbox ("Video Schedule has been created.  Please save the spreadsheet to the following location:    \\somenetworkshare\shared documents\video schedules\VIDEO SCHEDULES\2013  ")

Function OutlookDateFormat(varDate)
    Dim intHour, strAMPM
    intHour = Hour(varDate)
    If intHour > 12 Then
        intHour = intHour - 12
        strAMPM = "PM"
    Else
        strAMPM = "AM"
    End If
    OutlookDateFormat = Month(varDate) & "/" & Day(varDate) & "/" & Year(varDate) & " " & intHour & ":" & Minute(varDate) & " " & strAMPM
End Function

Function StrZero(varNumber, intLength)
    ' Purpose: Pad a number with zeroes to the given length and return it as a string.'
    ' Written: 4/24/2009'
    ' Author:  BlueDevilFan'
    ' Outlook: All versions'
    Dim intItemLength
    If IsNumeric(varNumber) Then
        intItemLength = Len(CStr(Int(varNumber)))
        If intItemLength < intLength Then
            StrZero = String(intLength - intItemLength, "0") & varNumber
        Else
            StrZero = varNumber
        End If
    Else
        StrZero = CStr(varNumber)
    End If
End Function

Function FormatHoursAndMinutes(varDate)
    FormatHoursAndMinutes = StrZero(Hour(varDate),2) & StrZero(Minute(varDate),2)
End Function

Function FormatDateHeader(datValue)
    FormatDateHeader = WeekdayName(Weekday(datValue)) & vbLf & StrZero(Day(datValue), 2) & UCase(MonthName(Month(datValue), True)) & Year(datValue)
End Function

Open in new window

SOLUTION
Avatar of Zack Barresse
Zack Barresse
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi, damoncf1234.

Apologies for taking so long to post to your question.

This post is NOT FOR POINTS.  I'm only commenting because I had promised to take a look at the question prior to Zack's post.

Zack (@firefytr) is correct that my original code is implementing the Restrict backwards.  As he points out, the sequence should be

1.  Get the folder's Items object.
2.  Sort the items
3.  Set IncludeRecurrences to True
4.  Restrict the items with your filter
5.  Read the filtered items

For example

Set olkItems = olkFolder.Items
olkItems.Sort "[Start]"
olkItems.IncludeRecurrences = True
Set olkFiltered = olkItems.Restrict("[Start] >= '" & OutlookDateFormat(datDate & " 0:01am") & "' AND [Start] < '" & OutlookDateFormat(datDate & " 11:59pm") & "'")

Open in new window


I don't know why I have them out of order in the original code.  That might account for the problem you're having.  My recommendation is to try Zack's code.  If it fixes the problem, then you should go with it.  If it doesn't , then I'll need to run some tests to see if I can duplicate the problem.
Avatar of damoncf1234
damoncf1234

ASKER

Zack & BlueDevilFan,

Thank you both for your responses.  I'll try your suggestion (having the sort run first) from work tomorrow or Wednesday (the script is on a network I can't access from home).  I'll post back with results.  Hopefully it resolves the issue.  
Thanks again for the responses.  
-Chris
Zack / BlueDevilFan,

Thanks for the response…  I tried your new script (updated the file name/location, conference room names, prefixes, etc.), and it opened Excel, but didn’t do anything beyond that (and showed the popup that the schedule had been created).  

I tried your other suggestion of moving things around in our existing script – sort, recurrences, restrict.  That seems to have helped with the (never-ending results that we were getting with Office 2010).  Now, we get the same results whether it’s run on a machine with Office 2007 or 2010 – but for some reason, we’re getting a few ‘extra’ meetings – that aren’t from the date selected.  

For example, I ran it today, and in one room, there are 10 meetings, but the updated script will show 14 meetings (one from the 23rd, one from the 28th, one from the 29th, and one from the 30th), in addition to the 10 meetings actually occurring today.  

Just for kicks, I tried modifying the ‘restrict’ line to narrow-down the start date/time to just a few hours today, and it seems to ignore the start time.  

I did a few searches today, and found the following items that might explain what’s happening with the restrict method:
http://www.outlookcode.com/codedetail.aspx?id=1206
http://support.microsoft.com/default.aspx?scid=kb;EN-US;292451

Is there an issue with the way the restrict method is used?

Do you know of any reasons why the script would 'include' a few meetings 'from the future' / outside of the specified date within the results?
 
Set olkItems = olkFolder.Items.Restrict("[Start] >= '" & OutlookDateFormat(datDate & " 0:01am") & "' AND [Start] < '" & OutlookDateFormat(datDate & " 11:59pm") & "'")

Open in new window


Thanks,
Chris
Hello Chris,

Perhaps it is an improper filter being applied. You only have [Start] defined. So you're restricting the items to where the start date is in the specified range. Should you in fact be filtering for the [End] as well?

Zack
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Zack,

Thanks for the reply.   Possibly...  The existing script that worked with Office 2007 worked with just the Start field applied.  

I just added the [End] times, and it didn't make a difference (still 14 meetings appeared for today, when there are only 10 scheduled).  

I just took off the .Restrict from olkFolder.Items.Restrict(strDayFilter)
So it's now just olkFolder.Items, and it pulls up all future meetings in that room (doesn't restrict to today)...  

I put the .Restrict back on there, and it seems to restrict the results to today (but for some reason it adds those 'extra' four entries - which are from 28/29/30January, for some reason).  It seems like it's 'working', but a few random entries get included from different dates.  

Do you have an idea why it'd be adding these additional entries?  

Thanks,
Chris
Chris,

I'm honestly not sure why it'd be adding the additional dates. I can't see anything on the Restrict method which would be getting those values. You should try BlueDevilFan's latest suggestion and let us know if it works for you as well. If that does work I'd still recommend implementing some of the changes I made, which makes the code more robust.

Zack
Oh, wow...  I didn't even notice that BlueDevilFan posted that new script. I'll test it right now.  Thank you!
BlueDevilFan/Zack,

I just tried the version that BlueDevilFan posted at 3:30pm, and it worked great, and didn't pull up any 'extra' meetings!  

Great!  I compared this script to the original one, and it seems like
set olkItems = olkFolder.Items.Restrict(start date info)
was changed to
With olkItems
    .Sort "[Start]"
    .IncludeRecurrences = True
    Set OlkHite = .Restrict(start date info)

I just updated the original version of the script with those changes from your updated script, and it works great!  Thank you.  (The version running on our (closed) network has some other parts to it - it also changes background and text color based on meeting subjects and keywords, and some other items).  

I just ran it from Office 2007 and 2010 (XP and Win7), and it works great (with no extra meetings!).  

One item that came up was 'Object reference not set to an instance of an object' - when running it from an XP machine with Outlook 2007 closed (not really worried about it, but do you have an idea how to make that go away?).

Thank both of you again,

Chris

(How do you want to split the points up?)
You don't have to give me any points, Chris, they've never been my focus here. :)

For the Outlook 2007 error, is the machine up to date with all Windows and Office service packs? I'd suspect the Windows XP, and make sure it has the latest updates installed. Also, I'm assuming no add-ins are involved. Are you saying you receive that error yet it continues to run, and do so successfully?

Zack
Zack,

Are you sure about the points?  You jumped in pretty quickly and offered some help...  

The XP machine I was testing on probably doesn't have the latest updates (it's on a closed network on blades that no one manages).  I'll try it on a 'regular XP workstation tomorrow'.  We're migrating from XP to Win7 soon, and that was one machine that I could VNC into from here.  

Yes, I'd get that error message on XP, but it would still open the spreadsheet and continue to run perfectly.  The error message doesn't appear on my Win7 machine.  It's no big deal - just wondering if you guys had any idea what was causing it.  

Thanks again,
Chris
It's a bit difficult to know which object it's referring to exactly. I'm assuming it would be in one of the three folder iterations you're looking through, and either that folder doesn't have any items to Restrict (thus found nothing) or the folder itself wasn't found - both theoretical guesses at this point, as there is almost no error handling in the code.

Do what you wish with the points, they're yours, just don't feel obligated to give me any. :)

Zack
Chris,

That's great.  A point split is definitely in order since it was Zack who first noticed that I had the commands out of order.

As to the error you're getting, what line is it occurring on?
Zack,

That 'empty folder' idea about the error message makes sense (there are actually 12 different folders - I just put 3 renamed ones on here) - and I'm sure a few of them were empty today.  

BlueDevilFan, I couldn't tell which line they were coming from - the error wasn't one of those line xx, character xx messages - it came up as soon as the outlook window was opened - before I put in the date or excel opened the spreadsheet.  

It was a small box that said that simple message, and sat in the background if you didn't hit ok before putting in a date.  

One thing I just thought about - I have 3 ema profiles on XP - I wonder if that's causing those messages...  I have outlook setup to prompt me for a profile on XP...  
I can get more details on that error message tomorrow.  

Thanks again,
Chris
Chris,

What version of Outlook is it on the XP box?
BlueDevilFan,

It's Outlook 2007 on the XP machine
And Outlook 2010 on the Win7 machine

Thanks,
Chris
It's tough to figure out what's causing the error when we don't know what line of code it is that's causing it.  I just looked back over the code and I did notice that there's an undefined constant.  I don't know if that's the problem (i.e. the interpreter thinks the constant is an object), but we should fix it anyway.  Please add

Const xlCellTypeConstants = 2

to the other constants defined at the top of the file.
BlueDevilFan,
Ok, I'll add that line to the top of the file (I'm out right now, but should be in later this afternoon to test that out).  
Thank you,
Chris
BlueDevilFan,

I just added that line to the top of the file - it still works without errors on Win7/Office2010, but on an XP machine, it comes up with the same error (it appears before I even get prompted for a date for the schedule (and before Excel Opens)...  

Thanks,
Chris
(The XP machines have Office 2007 on them)
Try changing this line

olkSes.Logon olkApp.DefaultProfileName

to

olkSes.Logon "Outlook"
I just changed the line, and it still comes up with that generic error message on Office 2007/XP.  

Since it doesn't come up when run from a Win7 machine running Office 2010, is it something that was changed from the original script (that apparently works in Office 2010 and Win7)?
The script shouldn't care whether it's on XP or Win7.  The problem is that we don't know what it is that's causing the error.  Without knowing that, all I can do is guess at what will make it go away.  I don't have an XP computer anymore, so I've no way to test it on that platform.  The best suggestion I have is to make a separate copy of the script (for debugging purposes), then add Msgbox commands to the file, once after each line of code from line 9 to line 27.  Something like this

'--> Turn error handling off
	On Error Resume Next
msgbox "Point A"

'--> Launch Outlook'
	Set olkApp = CreateObject("Outlook.Application")
msgbox "Point B"
	Set olkSes = olkApp.GetNamespace("MAPI")
msgbox "Point C"
	olkSes.Logon olkApp.DefaultProfileName
msgbox "Point D"

Open in new window


Once you have all the msgbox commands in, run the script.  The script will display dialog-box on screen after each command.  The last dialog-box you see before the error will tell us where the error is.  Using the above example, if the error message pops up after a dialog-box containing "Point C", then we know the error is on the next line below that command.  When we know what line it is that's causing the error, then we have a reasonable chance of figuring out what's causing it and how to fix it.
Hahaha...  We still have plenty of XP machines...  
Ok, I'll give that a shot to see what line causes the error.
I'll post back on Monday (since I can't access the other network otuside of work).

Thanks,
Chris
BlueDevilFan,

I just got in (haven't done the MsgBox commands yet), but one thing I noticed later on Friday is that if I have Outlook already open (before running the script), those error messages do not appear.  
The error messages only appear if Outlook is not running before the script is run...  

Thanks,
Chris
Chris,

The only reason I can think of that having Outlook open would make the errors go away is if the code is somehow failing to create an instance of Outlook.  Creating a new Outlook instance is exactly what lines 12-14 of the code are designed to do.
BlueDevilFan,

Yes -- what's even stranger is that I went back to our original script (from 2010 or so), and ran it without Outlook open on an XP machine, and the same generic error appeared (but the script still worked fine).  

Since users here have Outlook open 99% of the time, apparently no one has ever seen that error (and we're also migrating from XP to Win7)...  

I guess we can 'ignore' that error on XP if/when anyone sees it.  (No big deal).  The script still works great on XP and Win7, which was the original question for this post...  

We've also started using the updated script daily, and everyone likes it / hasn't complained... :)

Thank you and Zack again for the quick responses and assistance.  

You'd like to split the points equally between you two?  

Thanks,
Chris
That's so odd.

A split works for me.
Good to hear the update Chris. I'm a little baffled along with BDF though. The only other thing I would try is a rendition of the code I posted earlier, if you wanted to.

So you'd change this line...
Set olkApp = CreateObject("Outlook.Application")

Open in new window

... to this ...
    On Error Resume Next
    Set olkApp = GetObject(, "Outlook.Application")
    If olkApp Is Nothing Then
        Set olkApp = CreateObject("Outlook.Application")
    End If
    If olkApp Is Nothing Then
        MsgBox "Outlook not found"
        Exit Sub
    End If

Open in new window

I don't think you'll see any difference though. With Outlook open it uses the current instance, and if it's not open it will use the CreateObject() method to create one.

I suspect it would be the Logon code where the failure comes in. I'm assuming you have multiple profiles. If you do not, I'd think about commenting that line out as it's not needed for a single profile. In any case it should work just fine on Win XP though, I've done it a hundred times.

Regarding the points, it's your thread, your points to distribute, but I don't seek anything. BDF is the man of the hour here and I don't need points (certainly not the reason I'm here). Do as you see fit.

Have a great day!

Zack
Zack,

Yes, a few of us here have two Outlook profiles (although I tried changing the Outlook settings to 'not prompt' for the profile when opening, and it didn't seem to make a difference.  (That, and most people's individual profile is named "Outlook", but there's a second account we access from the other profile, which isn't named the same when people setup the secondary account.)

I'll try that modification in the morning and post back about the results.  

Thank you again,
Chris
If you have your Mail settings (in Control Panel) to "Always use this profile" for the selected profile, you shouldn't have to use the Logon method. If you have it prompting you, however, you must set which profile to logon to.

Zack
Zack/BlueDevilFan,

Sorry for the delay (federal government shutdown/got caught-up with other projects/etc.).  

The same generic error appears on XP - but we're about to upgrade our machines and switch to Win7 anyway, so I'm not going to worry about it -- it works fine on Win7/Office2010, and I haven't heard any complaints from anyone...  

Thank you again.  

Chris
Excellent responses by both Zack and BlueDevliFan - both were very responsive and helped with troubleshooting an issue that wasn't part of the original question - thank you again.
You're welcome, Chris!