Opening many shared calendars fails

R

Rasmus Wätjen

Hi.
We are experiencing that when a user opens more than about 70 calendars.
Outlook fails with the message like "Unable to display the folder. The
information
store could not be opened".

Actually we found the problem because we have an app which reads all
calendars (using the COM interface to Outlook) and it fails when it reaches
about 70. So we reproduced the problem by manually doing the same thing. For
some reason the COM interface adds the calendar folders in the "People's
Calendars" list in the left side of Outlook.

This is Outlook 2003 SP2.
Has anybody else seen this, or know a fix for it?

Best regards,
Rasmus
 
R

Rasmus Wätjen

The calendar information is needed in a telephone switchboard application. -
The user has a list of all coworkers where their daily schedule is shown.

The calendars are read similar to this:
outlook = GetActiveOleObject('outlook.application');
namespace = outlook.GetNameSpace('MAPI');
while more contacts do
contact = namespace.CreateRecipient(otherusersalias);
calendarfolder = namespace.GetSharedDefaultFolder(contact,
olFolderCalendar);
calendaritems = calendarfolder.Items;
calendaritems.Sort('[Start]');
calendaritems.IncludeRecurrences = true;
restriction = '[Start] <= midnighttoday and [End] >= midnightyesterday';

while more items do
// read calendar times
done;
calendarfolder = Unassigned;
done;

I'm assuming that the final Unassigned assignment will close the folders,
and remove references?

Is there something missing, or should it be done differently?

Thank you.

Best regards,
Rasmus
 
D

Dmitry Streblechenko

You need to release *all* the variables that point to the objects from that
mailbox (calendaritems, calendarfolder).
Move the code that opens and process a particular mailbox to a separate
sub - this way all local variables will be automatically released when the
sub exits.
If you are using .Net, GC.Collect would also be a good idea.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
Rasmus Wätjen said:
The calendar information is needed in a telephone switchboard
application. - The user has a list of all coworkers where their daily
schedule is shown.

The calendars are read similar to this:
outlook = GetActiveOleObject('outlook.application');
namespace = outlook.GetNameSpace('MAPI');
while more contacts do
contact = namespace.CreateRecipient(otherusersalias);
calendarfolder = namespace.GetSharedDefaultFolder(contact,
olFolderCalendar);
calendaritems = calendarfolder.Items;
calendaritems.Sort('[Start]');
calendaritems.IncludeRecurrences = true;
restriction = '[Start] <= midnighttoday and [End] >= midnightyesterday';

while more items do
// read calendar times
done;
calendarfolder = Unassigned;
done;

I'm assuming that the final Unassigned assignment will close the folders,
and remove references?

Is there something missing, or should it be done differently?

Thank you.

Best regards,
Rasmus



Dmitry Streblechenko said:
Why do you need to *simultaneously* open that many folders?

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
 
R

Rasmus Wätjen

I am using Delphi, so no garbage collection.
I am pretty sure that all variables are now set to Unassigned after every
calendar read, but the problem prevails.

Is there a way to remove a calendar from the "People's calendars" list in
Outlook?
I wonder why the other peoples calendar's are added to that list, when our
program reads the calendars using the object model. But maybe if the program
could remove the entries from that list after Outlook has added them, we
would be able to work around the problem.

Rasmus

Dmitry Streblechenko said:
You need to release *all* the variables that point to the objects from
that mailbox (calendaritems, calendarfolder).
Move the code that opens and process a particular mailbox to a separate
sub - this way all local variables will be automatically released when the
sub exits.
If you are using .Net, GC.Collect would also be a good idea.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
Rasmus Wätjen said:
The calendar information is needed in a telephone switchboard
application. - The user has a list of all coworkers where their daily
schedule is shown.

The calendars are read similar to this:
outlook = GetActiveOleObject('outlook.application');
namespace = outlook.GetNameSpace('MAPI');
while more contacts do
contact = namespace.CreateRecipient(otherusersalias);
calendarfolder = namespace.GetSharedDefaultFolder(contact,
olFolderCalendar);
calendaritems = calendarfolder.Items;
calendaritems.Sort('[Start]');
calendaritems.IncludeRecurrences = true;
restriction = '[Start] <= midnighttoday and [End] >= midnightyesterday';

while more items do
// read calendar times
done;
calendarfolder = Unassigned;
done;

I'm assuming that the final Unassigned assignment will close the folders,
and remove references?

Is there something missing, or should it be done differently?

Thank you.

Best regards,
Rasmus



Dmitry Streblechenko said:
Why do you need to *simultaneously* open that many folders?

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
in message Hi.
We are experiencing that when a user opens more than about 70
calendars.
Outlook fails with the message like "Unable to display the folder. The
information
store could not be opened".

Actually we found the problem because we have an app which reads all
calendars (using the COM interface to Outlook) and it fails when it
reaches
about 70. So we reproduced the problem by manually doing the same
thing. For
some reason the COM interface adds the calendar folders in the
"People's
Calendars" list in the left side of Outlook.

This is Outlook 2003 SP2.
Has anybody else seen this, or know a fix for it?

Best regards,
Rasmus
 
D

Dmitry Streblechenko

Delphi releases all interface type variables when they go out of scope, i.e.
when the method where they are declared exits or, in case of the class
variables, the class is destroyed.
Are you using multiple dot notation?
Again, do try my suggestion and see if it helps.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
Rasmus Wätjen said:
I am using Delphi, so no garbage collection.
I am pretty sure that all variables are now set to Unassigned after every
calendar read, but the problem prevails.

Is there a way to remove a calendar from the "People's calendars" list in
Outlook?
I wonder why the other peoples calendar's are added to that list, when our
program reads the calendars using the object model. But maybe if the
program could remove the entries from that list after Outlook has added
them, we would be able to work around the problem.

Rasmus

Dmitry Streblechenko said:
You need to release *all* the variables that point to the objects from
that mailbox (calendaritems, calendarfolder).
Move the code that opens and process a particular mailbox to a separate
sub - this way all local variables will be automatically released when
the sub exits.
If you are using .Net, GC.Collect would also be a good idea.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
Rasmus Wätjen said:
The calendar information is needed in a telephone switchboard
application. - The user has a list of all coworkers where their daily
schedule is shown.

The calendars are read similar to this:
outlook = GetActiveOleObject('outlook.application');
namespace = outlook.GetNameSpace('MAPI');
while more contacts do
contact = namespace.CreateRecipient(otherusersalias);
calendarfolder = namespace.GetSharedDefaultFolder(contact,
olFolderCalendar);
calendaritems = calendarfolder.Items;
calendaritems.Sort('[Start]');
calendaritems.IncludeRecurrences = true;
restriction = '[Start] <= midnighttoday and [End] >=
midnightyesterday';

while more items do
// read calendar times
done;
calendarfolder = Unassigned;
done;

I'm assuming that the final Unassigned assignment will close the
folders, and remove references?

Is there something missing, or should it be done differently?

Thank you.

Best regards,
Rasmus



Why do you need to *simultaneously* open that many folders?

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
"Rasmus Wätjen" <[email protected]>
wrote in message Hi.
We are experiencing that when a user opens more than about 70
calendars.
Outlook fails with the message like "Unable to display the folder. The
information
store could not be opened".

Actually we found the problem because we have an app which reads all
calendars (using the COM interface to Outlook) and it fails when it
reaches
about 70. So we reproduced the problem by manually doing the same
thing. For
some reason the COM interface adds the calendar folders in the
"People's
Calendars" list in the left side of Outlook.

This is Outlook 2003 SP2.
Has anybody else seen this, or know a fix for it?

Best regards,
Rasmus
 
R

Rasmus Wätjen

I am not sure what you mean by multiple dot notation.

I have rewritten the code, so that a function is called for each calendar to
be read, but unfortunately the problem is still there.
That function calls other functions for each part of the read: Resolve the
other user, open the folder, get the items collection, etc.
All variants are set to Unassigned after use, the only ones reused for
reading several calendars are the Outlook.Application OLE object, and the
namespace reference. These are set to Unassigned in the event of an error.

Rasmus




Dmitry Streblechenko said:
Delphi releases all interface type variables when they go out of scope,
i.e. when the method where they are declared exits or, in case of the
class variables, the class is destroyed.
Are you using multiple dot notation?
Again, do try my suggestion and see if it helps.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
Rasmus Wätjen said:
I am using Delphi, so no garbage collection.
I am pretty sure that all variables are now set to Unassigned after every
calendar read, but the problem prevails.

Is there a way to remove a calendar from the "People's calendars" list in
Outlook?
I wonder why the other peoples calendar's are added to that list, when
our program reads the calendars using the object model. But maybe if the
program could remove the entries from that list after Outlook has added
them, we would be able to work around the problem.

Rasmus

Dmitry Streblechenko said:
You need to release *all* the variables that point to the objects from
that mailbox (calendaritems, calendarfolder).
Move the code that opens and process a particular mailbox to a separate
sub - this way all local variables will be automatically released when
the sub exits.
If you are using .Net, GC.Collect would also be a good idea.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
in message The calendar information is needed in a telephone switchboard
application. - The user has a list of all coworkers where their daily
schedule is shown.

The calendars are read similar to this:
outlook = GetActiveOleObject('outlook.application');
namespace = outlook.GetNameSpace('MAPI');
while more contacts do
contact = namespace.CreateRecipient(otherusersalias);
calendarfolder = namespace.GetSharedDefaultFolder(contact,
olFolderCalendar);
calendaritems = calendarfolder.Items;
calendaritems.Sort('[Start]');
calendaritems.IncludeRecurrences = true;
restriction = '[Start] <= midnighttoday and [End] >=
midnightyesterday';

while more items do
// read calendar times
done;
calendarfolder = Unassigned;
done;

I'm assuming that the final Unassigned assignment will close the
folders, and remove references?

Is there something missing, or should it be done differently?

Thank you.

Best regards,
Rasmus



Why do you need to *simultaneously* open that many folders?

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
"Rasmus Wätjen" <[email protected]>
wrote in message Hi.
We are experiencing that when a user opens more than about 70
calendars.
Outlook fails with the message like "Unable to display the folder.
The information
store could not be opened".

Actually we found the problem because we have an app which reads all
calendars (using the COM interface to Outlook) and it fails when it
reaches
about 70. So we reproduced the problem by manually doing the same
thing. For
some reason the COM interface adds the calendar folders in the
"People's
Calendars" list in the left side of Outlook.

This is Outlook 2003 SP2.
Has anybody else seen this, or know a fix for it?

Best regards,
Rasmus
 
D

Dmitry Streblechenko

By multiple notation I mean something like
MAPIFolder.Items.Count
The compiler will store the result of the call to MAPIFolder.Items in an
implciit variable that you canot explicilty access and release.

What is your latest code?


--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
Rasmus Wätjen said:
I am not sure what you mean by multiple dot notation.

I have rewritten the code, so that a function is called for each calendar
to be read, but unfortunately the problem is still there.
That function calls other functions for each part of the read: Resolve the
other user, open the folder, get the items collection, etc.
All variants are set to Unassigned after use, the only ones reused for
reading several calendars are the Outlook.Application OLE object, and the
namespace reference. These are set to Unassigned in the event of an error.

Rasmus




Dmitry Streblechenko said:
Delphi releases all interface type variables when they go out of scope,
i.e. when the method where they are declared exits or, in case of the
class variables, the class is destroyed.
Are you using multiple dot notation?
Again, do try my suggestion and see if it helps.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
Rasmus Wätjen said:
I am using Delphi, so no garbage collection.
I am pretty sure that all variables are now set to Unassigned after
every calendar read, but the problem prevails.

Is there a way to remove a calendar from the "People's calendars" list
in Outlook?
I wonder why the other peoples calendar's are added to that list, when
our program reads the calendars using the object model. But maybe if the
program could remove the entries from that list after Outlook has added
them, we would be able to work around the problem.

Rasmus

You need to release *all* the variables that point to the objects from
that mailbox (calendaritems, calendarfolder).
Move the code that opens and process a particular mailbox to a separate
sub - this way all local variables will be automatically released when
the sub exits.
If you are using .Net, GC.Collect would also be a good idea.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
"Rasmus Wätjen" <[email protected]>
wrote in message The calendar information is needed in a telephone switchboard
application. - The user has a list of all coworkers where their daily
schedule is shown.

The calendars are read similar to this:
outlook = GetActiveOleObject('outlook.application');
namespace = outlook.GetNameSpace('MAPI');
while more contacts do
contact = namespace.CreateRecipient(otherusersalias);
calendarfolder = namespace.GetSharedDefaultFolder(contact,
olFolderCalendar);
calendaritems = calendarfolder.Items;
calendaritems.Sort('[Start]');
calendaritems.IncludeRecurrences = true;
restriction = '[Start] <= midnighttoday and [End] >=
midnightyesterday';

while more items do
// read calendar times
done;
calendarfolder = Unassigned;
done;

I'm assuming that the final Unassigned assignment will close the
folders, and remove references?

Is there something missing, or should it be done differently?

Thank you.

Best regards,
Rasmus



Why do you need to *simultaneously* open that many folders?

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
"Rasmus Wätjen" <[email protected]>
wrote in message Hi.
We are experiencing that when a user opens more than about 70
calendars.
Outlook fails with the message like "Unable to display the folder.
The information
store could not be opened".

Actually we found the problem because we have an app which reads all
calendars (using the COM interface to Outlook) and it fails when it
reaches
about 70. So we reproduced the problem by manually doing the same
thing. For
some reason the COM interface adds the calendar folders in the
"People's
Calendars" list in the left side of Outlook.

This is Outlook 2003 SP2.
Has anybody else seen this, or know a fix for it?

Best regards,
Rasmus
 
R

Rasmus Wätjen

By multiple notation I mean something like
MAPIFolder.Items.Count
The compiler will store the result of the call to MAPIFolder.Items in an
implciit variable that you canot explicilty access and release.
Ok. I don't use that at all.
What is your latest code?
The code is paraphrased below. Exception handling etc. have been removed for
easier readability. On exceptions, all variants are set to Unassigned, and
the outlook connection (the OLE object and namespace references) are also
set to Unassigned;
The only global variant variables are FOutlook and FNamespace. The
appointment's EntryID is stored in a variant in my own data object, but I
can't see how that would leave references unreleased.

The code to read one calendar is:
function ImportFromCalendar(emailaddress: String) : TObjectList;
begin
if not connectedtooutlook then
ConnectToOutlook; // create ole object and get MAPI Namespace
reference

CalendarFolder := GetCalendarFolder(emailaddress);

items := GetCalendarItems(CalendarFolder);

Result := TObjectList.Create;
for i:= 0 to items.Count-1 do
begin
Appointment := items.item;
newapp := TCalendarAppointment.Create;
ExtractAppointmentInfo(Appointment, newapp);
Result.Add(newapp);
end;
Appointment := Unassigned;
items := Unassigned;
CalendarFolder := Unassigned;
end;

procedure ConnectToOutlook;
begin
try
FOutlook := GetActiveOleObject('outlook.application');
except
FOutlook := CreateOleObject('outlook.application');
end;

FNamespace := FOutlook.GetNamespace('MAPI');
end;

function GetCalendarFolder(emailaddress) : Variant;
var
otheruser : Variant;
begin
OtherUser := FNamespace.CreateRecipient(emailaddress);
Result := GetSharedDefaultFolder(OtherUser, olFolderCalendar);
end;

function GetCalendarItems(CalendarFolder): Variant;
var
sRestriction : String;
begintime, endtime : TDateTime;
begin
// begintime and endtime are assigned so they point to today and
tomorrow at midnight, because I am only interested in today's appointments
Result := CalendarFolder.Items;
Result.Sort('[Start]');
Result.IncludeRecurrences := True;

// I am only interested in today's appointments,
sRestriction := '[Start] <= ''' + FormatDateTime(shortdateformat + ' ' +
shorttimeformat, endtime) + '''' +
' and [End] >= ''' + FormatDateTime(shortdateformat + ' '
+ shorttimeformat, begintime) + '''';

Result := Result.Restrict(sRestriction);
end;

function ExtractAppointmentInfo(Appointment: Variant; newitem :
TCalendarAppointment) : Boolean;
begin
newitem.Subject := Appointment.Subject;
newitem.Begintime := Appointment.Start;
newitem.Endtime := Appointment.End;
if appointment.sensitivity = 2 then
newitem.Subject := newitem.Subject + ' (Private)';
newitem.BusyStatus := Appointment.BusyStatus;
newitem.EntryID := Appointment.EntryID;
end;
 
D

Dmitry Streblechenko

Hmmmm... Looks good to me. I wonder if Outlook internally keeps all the
fodlers/items from the shared folders returned by GetSharedDefaultFolder
BTW, the Items collection in OOM is 1, not 0 based.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
Rasmus Wätjen said:
By multiple notation I mean something like
MAPIFolder.Items.Count
The compiler will store the result of the call to MAPIFolder.Items in an
implciit variable that you canot explicilty access and release.
Ok. I don't use that at all.
What is your latest code?
The code is paraphrased below. Exception handling etc. have been removed
for easier readability. On exceptions, all variants are set to Unassigned,
and the outlook connection (the OLE object and namespace references) are
also set to Unassigned;
The only global variant variables are FOutlook and FNamespace. The
appointment's EntryID is stored in a variant in my own data object, but I
can't see how that would leave references unreleased.

The code to read one calendar is:
function ImportFromCalendar(emailaddress: String) : TObjectList;
begin
if not connectedtooutlook then
ConnectToOutlook; // create ole object and get MAPI Namespace
reference

CalendarFolder := GetCalendarFolder(emailaddress);

items := GetCalendarItems(CalendarFolder);

Result := TObjectList.Create;
for i:= 0 to items.Count-1 do
begin
Appointment := items.item;
newapp := TCalendarAppointment.Create;
ExtractAppointmentInfo(Appointment, newapp);
Result.Add(newapp);
end;
Appointment := Unassigned;
items := Unassigned;
CalendarFolder := Unassigned;
end;

procedure ConnectToOutlook;
begin
try
FOutlook := GetActiveOleObject('outlook.application');
except
FOutlook := CreateOleObject('outlook.application');
end;

FNamespace := FOutlook.GetNamespace('MAPI');
end;

function GetCalendarFolder(emailaddress) : Variant;
var
otheruser : Variant;
begin
OtherUser := FNamespace.CreateRecipient(emailaddress);
Result := GetSharedDefaultFolder(OtherUser, olFolderCalendar);
end;

function GetCalendarItems(CalendarFolder): Variant;
var
sRestriction : String;
begintime, endtime : TDateTime;
begin
// begintime and endtime are assigned so they point to today and
tomorrow at midnight, because I am only interested in today's appointments
Result := CalendarFolder.Items;
Result.Sort('[Start]');
Result.IncludeRecurrences := True;

// I am only interested in today's appointments,
sRestriction := '[Start] <= ''' + FormatDateTime(shortdateformat + ' '
+ shorttimeformat, endtime) + '''' +
' and [End] >= ''' + FormatDateTime(shortdateformat + ' '
+ shorttimeformat, begintime) + '''';

Result := Result.Restrict(sRestriction);
end;

function ExtractAppointmentInfo(Appointment: Variant; newitem :
TCalendarAppointment) : Boolean;
begin
newitem.Subject := Appointment.Subject;
newitem.Begintime := Appointment.Start;
newitem.Endtime := Appointment.End;
if appointment.sensitivity = 2 then
newitem.Subject := newitem.Subject + ' (Private)';
newitem.BusyStatus := Appointment.BusyStatus;
newitem.EntryID := Appointment.EntryID;
end;
 
J

JimAnAmateur

Hi Rasmus

I am not able to help you with this problem of 70 calendars, but I am doing
a similar project, i.e. writing an application that reads all calendars for
use by a telephone switchboard.

Have you solved the problem of not getting any info about private
appointments that people may have in their calendars? I mean, not the details
of the private appointments, but that there exists a private appointment and
start and end time of the appointment.

I have been searching for days now, but have not yet found any solution.
Have you? I am using write in VBA in Excel.

Jim

Rasmus Wätjen skrev:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top