Оптимизация кода для поиска писем в надстройке Outlook

1

У меня есть следующее решение для печати определенной электронной почты в файл Excel. Я выбираю, какие письма должны быть написаны через дату.

    [STAThread]
    public void Summary(DateTime startDate, DateTime finishDate, string fileSaveAdress)
    {
        try
        {
            Outlook.Application oApp = new Outlook.Application();
            Outlook.NameSpace oNs = oApp.GetNamespace("mapi");
            oNs.Logon(Missing.Value, Missing.Value, false, false);

            Excel.Application xlApp = new Excel.Application();
            Excel.Workbook xlWorkBook = xlApp.Workbooks.Add(Missing.Value);
            Excel.Worksheet xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

            Outlook.MAPIFolder pickedFolder = oApp.Session.PickFolder();
            Outlook.Items pickedFolderItems = pickedFolder.Items;

            int iX = 1;
            int iY = 1;
            int iAdjustColomn = 0;

            foreach (object obj in pickedFolderItems)
            {
                if (obj is Outlook.MailItem)
                {
                    Outlook.MailItem oMsg = (Outlook.MailItem)obj;
                    if (oMsg.ReceivedTime.ToUniversalTime() > startDate.ToUniversalTime() &&
                        oMsg.ReceivedTime.ToUniversalTime() < finishDate.ToUniversalTime())
                    {
                        xlWorkSheet.Cells[iY, iX] = oMsg.ReceivedTime.ToShortDateString() + " " +
                                                    oMsg.ReceivedTime.ToShortTimeString();
                        xlWorkSheet.Cells[iY, ++iX] = oMsg.Sender.Name;

                        for (int i = 1; i <= oMsg.Recipients.Count; i++)
                        {
                            xlWorkSheet.Cells[iY, ++iX] = oMsg.Recipients[i].Name;
                        }

                        xlWorkSheet.Cells[iY, ++iX] = oMsg.Subject;

                        Outlook.Attachments AttachmentArray = oMsg.Attachments;
                        if (AttachmentArray.Count != 0)
                        {
                            foreach (Outlook.Attachment attachment in AttachmentArray)
                            {
                                xlWorkSheet.Cells[iY, ++iX] = attachment.DisplayName;
                            }
                        }

                        iAdjustColomn += iX;

                        iY += 2;
                        iX = 1;
                    }
                }
            }

            for (int i = 1; i < iAdjustColomn; i++)
            {
                AutoFitColumn(xlWorkSheet, i);
            }

            xlWorkBook.SaveAs(fileSaveAdress, Excel.XlFileFormat.xlWorkbookNormal, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
                              Excel.XlSaveAsAccessMode.xlExclusive, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
            xlWorkBook.Close(true, Missing.Value, Missing.Value);
            xlApp.Quit();

            oNs.Logoff();
        }
        catch (Exception e)
        {
            ErrorReport er = new ErrorReport(e.Message);
            er.ShowDialog();
        }
    }

И главная проблема заключается в том, что она дает ошибку, которой недостаточно памяти для работы. Как его оптимизировать? Пожалуйста помоги!

Теги:
outlook

1 ответ

1
Лучший ответ

Я бы заменил вызовы foreach, которые используют объекты Outlook, для циклов с использованием счетчика. Использование foreach обычно является плохой практикой с данными Outlook.

Кроме того, более быстрый подход заключается в использовании объекта таблицы с Folder.GetTable, где вы можете установить минимальное количество столбцов/полей, которые будут извлекаться для вашей итерации, чтобы минимизировать использование памяти.

Пример из Microsoft (http://msdn.microsoft.com/en-us/library/bb176423%28v=office.12%29.aspx):

Sub RemoveAllAndAddColumns()
'Declarations
Dim Filter As String
Dim oRow As Outlook.Row
Dim oTable As Outlook.Table
Dim oFolder As Outlook.Folder

'Get a Folder object for the Inbox
Set oFolder = Application.Session.GetDefaultFolder(olFolderInbox)

'Define Filter to obtain items last modified after May 1, 2005
Filter = "[LastModificationTime] > '5/1/2005'"
'Restrict with Filter
Set oTable = oFolder.GetTable(Filter)

'Remove all columns in the default column set
oTable.Columns.RemoveAll
'Specify desired properties
With oTable.Columns
    .Add ("Subject")
    .Add ("LastModificationTime")
    'PR_ATTR_HIDDEN referenced by the MAPI proptag namespace
    .Add ("http://schemas.microsoft.com/mapi/proptag/0x10F4000B")
End With

'Enumerate the table using test for EndOfTable
Do Until (oTable.EndOfTable)
    Set oRow = oTable.GetNextRow()
    Debug.Print (oRow("Subject"))
    Debug.Print (oRow("LastModificationTime"))
    Debug.Print (oRow("http://schemas.microsoft.com/mapi/proptag/0x10F4000B"))
Loop
End Sub
  • 0
    Я действительно не уверен, что это решит проблему. Может быть, будет более полезно отфильтровать почту из любой другой общей коллекции, чем из самого Outlook. Я хочу сначала сделать копию.
  • 1
    Я не совсем уверен, где может произойти раздувание памяти, но вы всегда должны использовать для операторов, а не foreach с объектами Outlook. Кроме того, более быстрый подход заключается в использовании объекта Table с Folder.GetTable, где вы можете установить минимальное количество столбцов / полей, которые нужно извлечь для вашей итерации, чтобы минимизировать использование памяти.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню