Ho una collezione che uso per avere una mappa String -> MailItem
. Riempio la mappa e quando trovo una chiave duplicata voglio leggere l'elemento nella raccolta.Perché non riesco a ottenere un oggetto da una Collezione e memorizzarlo in una variabile?
Sembra così facile, ma ho impiegato più di un'ora a cercare di capire perché non è possibile assegnare un elemento Raccolta a una variabile locale. (Vedi PROBLEM
nel codice di seguito)
oMailOther = cMails.Item(cMailKey)
"Oggetto variabile o variabile del blocco non set"
Set oMailOther = cMails.Item(cMailKey)
"Oggetto richiesto"
L'altra cMails(cMailKey)
forma dà lo stesso errore. Spostare la Dim in giro non fa alcuna differenza. cMails
deve essere disponibile perché è stato utilizzato in precedenza nel metodo. Nota la riga Debug.Print
appena prima di questa istruzione, che funziona. Cosa mi manca?
Option Explicit
Option Compare Text
Public cMails As Collection
Public Sub GetOutlookAttachments()
Set cMails = New Collection
Dim oStore As Store
For Each oStore In Session.Stores
If oStore.DisplayName = "Outlook Data File" Then
ProcessFolder oStore.GetRootFolder()
End If
Next
End Sub
Private Sub ProcessFolder(oFolder As Folder)
Debug.Print oFolder.FolderPath
ProcessItems oFolder.Items
Dim oSubFolder As Folder
For Each oSubFolder In oFolder.Folders
ProcessFolder oSubFolder ' recurse
Next
End Sub
Private Sub ProcessItems(oItems As Items)
Dim oItem As Object
For Each oItem In oItems
DoEvents
If TypeOf oItem Is MailItem Then
Dim oMail As MailItem
Set oMail = oItem
Dim cMailKey As String
cMailKey = oMail.ConversationID & "-" & oMail.ConversationIndex
If Not Contains(cMails, cMailKey) Then
cMails.Add oMail.Subject, cMailKey
Else
Debug.Print cMails.Item(cMailKey)
Dim oMailOther As MailItem
PROBLEM oMailOther = cMails.Item(cMailKey)
Debug.Print cMailKey & ": " & oMailOther.Subject
End If
ElseIf TypeOf oItem Is MeetingItem Then
' ignore
Else
Debug.Print "oItem Is a " & TypeName(oItem)
End If
Next oItem
End Sub
Public Function Contains(col As Collection, key As Variant) As Boolean
Dim obj As Variant
On Error GoTo err
Contains = True
obj = col(key)
Exit Function
err:
Contains = False
End Function
Ho anche cercato di replicare simili Add
e Item
chiamate altrove e funziona.
Public Sub Test()
Set cMails = New Collection
Dim cMailKey As String
cMailKey = "hello"
cMails.Add Session.Stores.Item(1), cMailKey
Debug.Print cMails(cMailKey)
Dim oStore As Store
Set oStore = cMails(cMailKey)
Debug.Print oStore.DisplayName
End Sub
Provare a utilizzare 'CreateObject (" Scripting.Dictionary ")' invece di 'Collection'. Il dizionario ha il metodo nativo '.Exists()', quindi non è necessario 'Function Contains()'. – omegastripes
@omegastripes Lo so, ma quella parte funziona bene, altrimenti non arriverebbe alla riga 'PROBLEM'. Non voglio ulteriori dipendenze. – TWiStErRob
Non sono sicuro che considererei 'Scripting.Dictionary 'una dipendenza problematica - richiederebbe che * non * sia disponibile sul computer di destinazione. – Comintern