2017-04-12 43 views
0

我希望你能幫助我減輕我的代碼的運行時間:減少處理時間字符串分解

Dim position As Long 
Dim CellRow As Long 
CellRow = 2 

For position = InStr(Inbox.Items(MostRecentVersionIndex).body, "Name") To Len(Inbox.Items(MostRecentVersionIndex).body) 
      ThisWorkbook.Sheets(1).Range("A" & CellRow) = Mid(Inbox.Items(MostRecentVersionIndex).body, InStr(position, Inbox.Items(MostRecentVersionIndex).body, "SCA"), InStr(InStr(position, Inbox.Items(MostRecentVersionIndex).body, "SCA") + 1, Inbox.Items(MostRecentVersionIndex).body, "SCA") - InStr(position, Inbox.Items(MostRecentVersionIndex).body, "SCA")) 
      CellRow = CellRow + 1 
      position = InStr(InStr(position, Inbox.Items(MostRecentVersionIndex).body, "SCA") + 1, Inbox.Items(MostRecentVersionIndex).body, "SCA") - 1 
     Next position 
  1. 代碼的第一部分是找到Outlook中的特定電子郵件,然後我保存它的索引在MostRecentVersionIndex。 (未在上面顯示)
  2. 此電子郵件在其正文中有大量記錄(約50萬字符),而我的代碼的第二部分(如上所示)則是將每條記錄放入A列的新行中第1頁。我知道每條記錄都以「SCA」開頭,這就是爲什麼我將它用作拆分參數的原因。

問題:需要(不出所料)大約10分鐘來運行整個事情。

有關如何減少此問題的任何想法?

編輯:這裏是FYI整個代碼(用溶液更新後):

Sub MailFinder() 
'1)Finding the most recent mail from Mr. Spoke 
    Dim Inbox As folder 
    Dim i As Integer 
    Dim MostRecentVersionIndex As Integer 
    MostRecentVersionIndex = -1 
    Dim TimeReceived As Date 
    Dim Content As String 
    Set Inbox = Session.GetDefaultFolder(olFolderInbox) 

    For i = 1 To Inbox.Items.Count 

      If TypeName(Inbox.Items(i)) <> "ReportItem" Then ' to avoid errors because we can't access information from this type of file 
       If Left(Inbox.Items(i).Subject, 24) = "Mr. Spoke Subject" Then 'And Inbox.Items(i).SenderName = "Mr.Spoke" Then 
         'MsgBox Len(Inbox.Items(i).body) '584512 
         If Inbox.Items(i).ReceivedTime > TimeReceived Then 
          TimeReceived = Inbox.Items(i).ReceivedTime 
          MostRecentVersionIndex = i 
         End If 
         'ThisWorkbook.Sheets("Sheet2").Range("A1") = Inbox.Items(i).body ' only get 32000 characters 

       End If 
      End If 
    Next i 

'2)Retrieving its information and storing each line in a new row from column A 
    Dim position As Long 
    Dim CellRow As Long 
    Dim RightMail As MailItem 
    Set RightMail = Inbox.Items(MostRecentVersionIndex) 
    Dim body As String 
    body = RightMail.body 
    CellRow = 2 
    If MostRecentVersionIndex <> -1 Then 
     ThisWorkbook.Sheets("SpokeSubject").Range("A1") = Left(body, InStr(body, "Name") + 3) 

     For position = InStr(body, "Name") To Len(body) 
      On Error GoTo Fin 
      ThisWorkbook.Sheets("SpokeSubject").Range("A" & CellRow) = Mid(body, InStr(position, body, "SCA"), InStr(InStr(position, body, "SCA") + 1, body, "SCA") - InStr(position, body, "SCA")) 
      CellRow = CellRow + 1 
      position = InStr(InStr(position, body, "SCA") + 1, body, "SCA") - 1 
     Next position '209333 
     'Inbox.Items(i).body.Copy ' doesn't work 
     'ThisWorkbook.Sheets("Sheet2").Range("A1").PasteSpecial 
     'ThisWorkbook.Sheets("Sheet2").Range("A1") = Inbox.Items(MostRecentVersionIndex).body ' all in one cell... 
Fin: 
    End If 
    Call Formatter 
End Sub 
+1

您是否嘗試過使用幾個變量來減少每次運行時通過循環多次解析這些引用的時間量?例如,爲有問題的郵件項目設置一個變量,或者更好的是,將正文文本放入一個字符串變量並循環。 –

+0

你能發佈完整的代碼嗎? – 0m3r

+0

@ 0m3r:好的我將編輯帖子。這隻會爲那些可能感興趣的人帶來價值,因爲它與我的問題無關 – Seb

回答

1

這是採取極端的多個點表示法。先閱讀該項目,然後閱讀它的正文,然後才能遍歷字符。

您需要認識到,每次您返回Items集合時,Outlook都會滾動到索引MostRecentVersionIndex,打開消息,然後讀取其巨大的Body屬性。你做這5到6次沒有理由。

set Item = Inbox.Items(MostRecentVersionIndex) 
body = item.Body 
For position = InStr(body, "Name") To Len(body) 
      ThisWorkbook.Sheets(1).Range("A" & CellRow) = Mid(body, InStr(position, body, "SCA"), InStr(InStr(position, body, "SCA") + 1, body, "SCA") - InStr(position, body, "SCA")) 
      CellRow = CellRow + 1 
      position = InStr(InStr(position, body, "SCA") + 1, body, "SCA") - 1 
     Next position 
+0

我很困惑,我認爲我們可以存儲字符的限制,但顯然它可以工作。 另外,我認爲爲了提高代碼的性能,我們應該使用最少的變量。 如果我沒有創建'item'變量,而是將整個事物存儲在'body'中,那麼性能會真的不同嗎? – Seb

+0

在32位字符串限制爲4Gb。儘量減少最佳情況下的變量數量不會產生任何效果(編譯器仍然需要創建隱式變量來保存中間結果),並且在最壞的情況下(如您的情況)會顯着降低性能。 –