Delphi Folder.Items.Add是否始终添加到Items数组的前面?

Delphi Folder.Items.Add是否始终添加到Items数组的前面?,delphi,calendar,outlook,ole,Delphi,Calendar,Outlook,Ole,在我的(Delphi)代码中,我在Outlook中创建了一个新的日历约会: function TDataModuleSyncOutlook.ExportEventToOutlook(AOutlookEvent: TcxSchedulerEvent; var AOutlookEntryID: String): Boolean; var AAppointmentItem: OleVariant; begin Result := false; AAppointmentItem := FCa

在我的(Delphi)代码中,我在Outlook中创建了一个新的日历约会:

function TDataModuleSyncOutlook.ExportEventToOutlook(AOutlookEvent: TcxSchedulerEvent; var AOutlookEntryID: String): Boolean;
var
  AAppointmentItem: OleVariant;
begin
  Result := false;
  AAppointmentItem := FCalendarFolder.Items.Add(olAppointmentItem);
  ...
  AAppointmentItem.Save;  // This generates AAppointmentItem.EntryID 
  AOutlookEntryID := AAppointmentItem.EntryID;
  ...
我想维护一个EntryId列表,该列表指向FCalendarFolder.Items[]中的索引

运行代码时,我注意到新项目被添加到项目的前面,即它是FCalendarFolder.Items[1](项目基于1)

我的问题是:是否保证会出现这种情况?,即FCalendarFolder.Items.Add是否始终在FCalendarFolder.Items[1]中添加新约会?
因为如果不是,我如何将entryId与索引耦合?”

如果不能保证这一点,我如何保持交叉引用?我看没有别的办法:

  • 似乎没有.Index或.ItemIndex属性

  • EntryID明确不支持使用或按EntryID查找项

背景:
FCalendarFolder是通过GetDefaultFolder或GetSharedDefaultFolder检索的:
(代码基于)

const
olFolderCalendar=$00000009;//Outlook默认日历文件夹
olAppointmentItem=$00000001;
scxOutlookApp='outlook.application';
scxNameSpace='MAPI';
函数TDataModuleSyncOutlook.ConnectToOutlook(AUserSMTP:String=''):布尔值;
变量
名称空间,
lRecipient,
lVar:油变异体;
lLoginSMTP:字符串;
开始
结果:=假;
FWasCreated:=假;
尝试
FOutlookApp:=GetActiveOleObject(scxOutlookApp);//应用程序对象
结果:=真;
除了
尝试
FOutlookApp:=CreateOleObject(scxOutlookApp);
FWasCreated:=真;
结果:=真;
除了
在E上:异常do tsynclougler.LogError(E.Message);
终止
终止
如果结果是这样的话
开始
lNameSpace:=FOutlookApp.GetNamespace(scxNameSpace);
lVar:=FOutlookApp.Session;//当前会话的命名空间对象
如果不是VarIsClear(lVar),则lVar:=lVar.CurrentUser;//当前登录用户的收件人对象
如果不是VarIsClear(lVar),则lVar:=lVar.AddressEntry;//收件人的AddressEntry对象
如果不是VarIsClear(lVar),则lVar:=lVar.GetExchangeUser;//返回表示AddressEntry的ExchangeUser对象
如果不是VarIsClear(lVar),则lVar:=lVar.PrimarySmtpAddress;//表示ExchangeUser的SMTP地址的字符串
如果不是可变线性(lVar),则
lLoginSMTP:=FOutlookApp.Session.CurrentUser.AddressEntry.GetExchangeUser.PrimarySmtpAddress;
其他的
日志错误(…)
如果是小写(AUserSMTP)小写(lLoginSMTP),那么
开始//如果是其他用户,则打开共享日历
lRecipient:=lNameSpace.CreateRecipient(AUserSMTP);
尝试
FCalendarFolder:=lNameSpace.GetSharedDefaultFolder(lRecipient,olFolderCalendar);
除了
关于E:Exception-do
开始
结果:=假;
对数误差(…);
终止
终止
终止
else/。。。否则打开默认日历文件夹
开始
FCalendarFolder:=lNameSpace.GetDefaultFolder(olFolderCalendar);
...   

绝对不是。除非使用Items.sort对Items集合进行显式排序,否则根本没有顺序。如果您知道条目id,您可以使用Namespace.GetItemFromID重新打开该项。

旁注:如果导入Outlook typelib,您将得到一个更干净的代码,而不必使用那些
OleVariant
。@Free这会更清楚,是的。代码大部分是从其他代码中复制的,因此我们决定离开后期绑定,而不是重写所有内容以进行早期绑定。
const
  olFolderCalendar  = $00000009;  // Outlook default calendar folder
  olAppointmentItem = $00000001;
  scxOutlookApp     = 'outlook.application';
  scxNameSpace      = 'MAPI';

function TDataModuleSyncOutlook.ConnectToOutlook(AUserSMTP: String = ''): Boolean;
var
   lNameSpace,                   
   lRecipient,
   lVar      : OleVariant;
   lLoginSMTP: String;
begin
   Result      := false;
   FWasCreated := False;  
   try
      FOutlookApp := GetActiveOleObject(scxOutlookApp);         // Application object
      Result := True;
   except
      try
         FOutlookApp := CreateOleObject(scxOutlookApp);
         FWasCreated := True;
         Result := True;
      except
         on E:Exception do TSyncLogger.LogError(E.Message);
      end;
   end;
   if Result then         
   begin
      lNameSpace := FOutlookApp.GetNamespace(scxNameSpace);
      lVar := FOutlookApp.Session;                                   // NameSpace object for the current session
      if not VarIsClear(lVar) then lVar := lVar.CurrentUser;         // Recipient object for the currently logged-on user
      if not VarIsClear(lVar) then lVar := lVar.AddressEntry;        // AddressEntry object for the recipient
      if not VarIsClear(lVar) then lVar := lVar.GetExchangeUser;     // Returns an ExchangeUser object that represents the AddressEntry
      if not VarIsClear(lVar) then lVar := lVar.PrimarySmtpAddress;  // String representing the SMTP address for the ExchangeUser
      if not VarIsClear(lVar) then
         lLoginSMTP := FOutlookApp.Session.CurrentUser.AddressEntry.GetExchangeUser.PrimarySmtpAddress;
      else 
         LogError(...)
      if LowerCase(AUserSMTP) <> Lowercase(lLoginSMTP) then
      begin   // Open shared calendar if it's a different user
         lRecipient := lNameSpace.CreateRecipient(AUserSMTP);
         try
            FCalendarFolder := lNameSpace.GetSharedDefaultFolder(lRecipient, olFolderCalendar);
         except
            on E:Exception do
            begin
               Result := false;
               LogError(...);
            end;
         end;
      end
      else   // ... otherwise open default calendar folder 
      begin
         FCalendarFolder := lNameSpace.GetDefaultFolder(olFolderCalendar);
      ...