Estrazione da Outlook



  • Estrazione da Outlook
    di Luca (utente non iscritto) data: 12/07/2016 09:17:43

    buongiorno,
    avere un'estrazione di Outlook su foglio di Excel ?

    avrei bisogno di esportare su folgio excel le mail di una determinata cartalla di Outlook suddividendo le informazioni i 4 colonne

    Indirizzo e-mail del Mittente
    Data e ora della ricezione
    Oggetto
    Testo della mail

    sinceramente so da che parte iniziare



  • di Vecchio Frac data: 12/07/2016 09:35:42

    cit. "sinceramente so da che parte iniziare"
    ---> E' già qualcosa. Allora posta un po' di codice :)





  • di Luca (utente non iscritto) data: 12/07/2016 09:40:50

    preso in pieno!!!
    volevo scrivere NON so da dove iniziare



  • di Vecchio Frac data: 12/07/2016 10:10:42

    Puoi lavorare sia da Outlook che da Excel. Questa è la prima scelta da fare.
    In entrambi i casi devi creare un riferimento all'altra applicazione creandoti gli oggetti che ti servono "come se fossi" dentro l'applicazione.
    Poi li piloti nel modo che useresti se fossi nell'applicazione di riferimento.





  • di Vecchio Frac data: 12/07/2016 10:48:02

    Ho già scritto un codice funzionante. Compresi i commenti, sono solo 50 righe di codice.
    Prima di vederlo insieme, fai uno sforzo e cerca di proporre qualcosa (anche se è sbagliato).




  • r
    di Luca (utente non iscritto) data: 12/07/2016 11:13:50

    Hai già scritto 50 righe di codice ??
    Io per scrive 50 righe funzionanti ci metterò almeno 2/3 ore!!

    Vabbè, ci proverò quando ho un attimo di calma...

    grazie




  • di Vecchio Frac data: 12/07/2016 11:17:34

    Non devi scrivere codice fin da subito.
    Devi scrivere uno scheletro delle operazioni che poi tradurrai in VBA.
    Questo si chiama appunto "stendere pseudocodice" e aiuta a organizzare i passaggi successivi.
    Devi immaginare di essere tu l'applicativo che esegue codice passo-passo: quali operazioni devi fare, in sequenza, per arrivare allo scopo?




  • r
    di Luca (utente non iscritto) data: 12/07/2016 11:57:03

    per cominciare, questo il testo del flusso:

    Con un nuovo folgio excel aperto
    Lanciare la macro
    Estrarre le e-mails contenute nella cartella "Presenze - TAG" (sottocartella di posta in arrivo)

    Popolare il file in excel con :
    colonna A: da (indirizzo e-mail del mittente)
    colonna B: ricevuto (data e ora della ricezione)
    colonna C: oggetto (ovviamente l'oggetto della mail)
    colonna D: corpo (il testo della mail)




  • di Vecchio Frac data: 12/07/2016 13:17:44

    Benissimo. Hai realizzato il macroprocesso dell'intero compito.
    Adesso devi analizzare il macroflusso e produrre dei microflussi (scritti in italiano come hai appena fatto) più o meno dettagliati a seconda del grado di complessità che vuoi raggiungere.
    Quando hai ottenuto un flusso di operazioni che copra gli eventi descrivibili, puoi "passare all'azione" :)

    Cioè, per come hai fatto tu, poichè sei partito col dire "Con nuovo foglio Excel aperto", assumo che scriverai codice in Excel che piloterà Outlook (e non viceversa, cosa parimenti fattibile). Quindi:
    - il codice da Excel provvede a collegarsi ad Outlook
    - deve leggere le email della sottocartella "Presenze - TAG"
    - per ogni mail che trova in tale sottocartella, ne recupera gli elementi che mi interessano (mittente, data e ora, oggetto, ecc.)
    - inserisce questi elementi nel foglio1, in righe sequenziali
    - se l'elemento è già stato inserito, lo salta (è il caso delle esecuzioni successive, per cui i dati nuovi vengono accodati a quelli esistenti)

    Ora non resta che sviluppare (se si vuole) quanto sopra i passaggi più dettagliati, altrimenti si può cominciare a stendere il codice. Mi fermo e attendo un tuo riscontro ... dimmi che hai capito :)





  • r
    di Luca (utente non iscritto) data: 12/07/2016 13:45:26

    Ho capito la metologia di lavoro, riassunto in 3 punti:
    - Marco analisi
    - Flow chart
    - Programma

    lo scoglio da superare è il linguaggio VBA (ho detto niente)




  • di Vecchio Frac data: 12/07/2016 14:14:04

    Sì ma vedi che alla fine il problema è ampiamente superabile perchè una volta che hai chiaro cosa devi fare, sai cosa devi chiedere e sarà più facile per gli altri aiutarti.

    Per esempio:
    - Se devo eseguire un codice che ritorna un valore mi serve una Function. Se voglio solo eseguire un compito che nasce e finisce senza darmi dei valori di ritorno da elaborare ulteriormente in altri punti del codice, basta una Subroutine.

    Sub retrieve_outlook_mailes()
    
    ...
    End Sub


    - "il codice da Excel provvede a collegarsi ad Outlook"
    Sono in Excel. Mi serve aprire Outlook perchè riceva comandi come se io fossi in Outlook. Mi serve quindi un meccanismo che crei in memoria un'istanza di Outlook e acceda ai suoi metodi e proprietà. Questo meccanismo deve "creare un oggetto" dell'applicazione Outlook e assegnarlo a una variabile in memoria:


    'crea un riferimento all'applicazione Outlook
    Set olApp = CreateObject("Outlook.Application")


    - "il codice legge la cartella di Outlook da dove pescare le mail"
    Facciamo riferimento alla cartella che abbiamo deciso di interrogare. La cartella predefinita in Outlook è il FolderInbox che ha come codice il valore 6 (è un valore deciso da Outlook). Le sottocartelle (proprio come in Gestione risorse) si trovano nell'insieme Folders e ogni sottocartella è indicizzabile anche con il suo nome. Anche qui assegniamo a una variabile di nome arbitrario (myfolder) il contenuto della sottocartella desiderata.


    'crea un riferimento alla cartella Posta in arrivo e a una sottocartella specifica
    Set myfolder = olApp.GetNamespace("MAPI").GetDefaultFolder(6).Folders("Presenze - TAG") ' 6 = olFolderInbox






  • di Vecchio Frac data: 12/07/2016 14:18:01

    Ora che hai capito il meccanismo, allego il codice intero per tuo studio.
    I dati che recupero sono molti di più di quelli che hai chiesto tu, ma è solo un esempio che puoi accomodare.
    Copia e incolla questo codice in un modulo di un foglio vuoto, inserisci in riga 1 le intestazioni:
    ENTRY ID, CARTELLA, MITTENTE, DATA, OGGETTO, CORPO, ALLEGATI
    quindi avvia la macro.
    A seconda di quante email ci son può metterci un po' di tempo, ma funziona anche se sembra inchiodato, dagli tempo e dopo un po' arriverà il messaggio di conclusione.
     
    Option Explicit
    
    Sub retrieve_outlook_mailes()
    Dim olApp As Object, myfolder As Object
    Dim oEmail As Object
    Dim exists As Range, ri As Long, cnt As Long
        
        'crea un riferimento all'applicazione Outlook
        Set olApp = CreateObject("Outlook.Application")
        
        'crea un riferimento alla cartella Posta in arrivo
        'per leggere il contenuto di una sottocartella rispetto a Posta in arrivo:
        Set myfolder = olApp.GetNamespace("MAPI").GetDefaultFolder(6).Folders("Presenze - TAG")        ' 6 = olFolderInbox
        
        'contatore per accodare a dati esistenti sul foglio
        ri = [COUNTA(A:A)]
        If ri = 0 Then ri = 2 Else ri = ri + 1      'tappo di sicurezza necessario per il caso della prima esecuzione
        
        Application.ScreenUpdating = False          'non visualizza l'elaborazione in diretta, velocizza così l'esecuzione
        
        'scansione delle mail dalla cartella Outlook specirficata all'inizio
        'recupera i diversi dati e li infila cella per cella nel foglio
        'la riga 1 del foglio contiene la riga di intestazione delle colonne
        'ENTRY ID, CARTELLA, MITTENTE, DATA, OGGETTO, CORPO, ALLEGATI
    
        For Each oEmail In myfolder.items
            With oEmail
                Set exists = Range("A:A").Find(.EntryID)    'cerca l'ID univoco della mail (generato da Outlook) per evitare di ricopiare doppioni
                If exists Is Nothing Then
                    Cells(ri, "A") = .EntryID         'entryID
                    Cells(ri, "B") = .Parent          'cartella outlook
                    Cells(ri, "C") = .SenderName      'mittente
                    Cells(ri, "D") = .ReceivedTime    'data dell'email
                    Cells(ri, "E") = .Subject         'oggetto
                    Cells(ri, "F") = .Body            'corpo del messaggio
                    Cells(ri, "G") = .Attachments.Count        'numero di allegati
                    Rows(ri).WrapText = False
                    ri = ri + 1
                    cnt = cnt + 1
                End If
            End With
        Next
        
        Set myfolder = Nothing
        Set olApp = Nothing
        Application.ScreenUpdating = True
        
        MsgBox "Finito. Ho importato " & cnt & " elementi."
    End Sub






  • di alfrimpa data: 12/07/2016 14:18:44

    Ciao Luca e Vecchio Frac

    Ho trovato il codice che vedete sotto sul forum OzGrid.

    Magari può essere utile anche a scopo didattico; io non posso provarlo perché non ho Outlook funzionante.

    Ovviamente va attivata la Microsoft Outlook Object Library.

    Alfredo
     
    Public Sub ListOutlookFolders()
         
        Dim olApp As Outlook.Application
        Dim olNamespace As Outlook.Namespace
        Dim olFolder As Outlook.MAPIFolder
        Dim rngOutput As Range
        Dim lngCol As Long
        Dim olItem As Outlook.MailItem
         
        Set rngOutput = ActiveSheet.Range("A1")
         
        Set olApp = New Outlook.Application
        Set olNamespace = olApp.GetNamespace("MAPI")
         
        For Each olFolder In olNamespace.Folders
            rngOutput = olFolder.Name
            rngOutput.Offset(0, 1) = olFolder.Description
            Set rngOutput = rngOutput.Offset(1)
            For Each olItem In olFolder.Items
                Set rngOutput = rngOutput.Offset(1)
                With rngOutput
                    .Offset(0, 1) = olItem.SenderName ' Sender
                    .Offset(0, 2) = olItem.Subject ' Subject
                    .Offset(0, 3) = olItem.ReceivedTime ' Received
                    .Offset(0, 4) = olItem.ReceivedByName ' Recepient
                    .Offset(0, 5) = olItem.UnRead ' Unread?
                    .Offset(0, 6) = olItem.ReplyRecipientNames '
                    .Offset(0, 7) = olItem.SentOn
                End With
            Next
             
            Set rngOutput = ListFolders(olFolder, 1, rngOutput)
        Next
         
        Set olFolder = Nothing
        Set olNamespace = Nothing
        Set olApp = Nothing
         
    End Sub
    Function ListFolders(MyFolder As Outlook.MAPIFolder, Level As Integer, Output As Range) As Range
         '
         '
         '
        Dim olFolder As Outlook.MAPIFolder
        Dim olItem As Outlook.MailItem
        Dim lngCol As Long
         
        For Each olFolder In MyFolder.Folders
            lngCol = ((Level - 1) * 8) + 1
            Output.Offset(0, lngCol) = olFolder.Name
            Set Output = Output.Offset(1)
            If olFolder.DefaultItemType = olMailItem Then
                For Each olItem In olFolder.Items
                    With Output
                        .Offset(0, lngCol + 1) = olItem.SenderName ' Sender
                        .Offset(0, lngCol + 2) = olItem.Subject ' Subject
                        .Offset(0, lngCol + 3) = olItem.ReceivedTime ' Received
                        .Offset(0, lngCol + 4) = olItem.ReceivedByName ' Recepient
                        .Offset(0, lngCol + 5) = olItem.UnRead ' Unread?
                        .Offset(0, lngCol + 6) = olItem.ReplyRecipientNames '
                        .Offset(0, lngCol + 7) = olItem.SentOn
                         
                    End With
                    Set Output = Output.Offset(1)
                Next
            End If
            If olFolder.Folders.Count > 0 Then
                Set Output = ListFolders(olFolder, Level + 1, Output)
            End If
        Next
        Set ListFolders = Output.Offset(1)
         
    End Function
    
    






  • di alfrimpa data: 12/07/2016 14:20:09

    Oops VF non volevo creare confusione.

    Se lo ritenete posso anche cancellare il post.

    Alfredo





  • di Vecchio Frac data: 12/07/2016 14:38:37

    Figurati Alfredo, nessuna confusione, il codice è simile al mio, fa anche qualcosa in più, il concetto è che le cose si possono fare sempre in modi diversi :)

    *Non* cancellare il tuo post. A Luca andrà benissimo studiarsi u po' di tecniche nuove ;)





  • di alfrimpa data: 12/07/2016 15:27:56

    Certo che ce ne è da studiare

    Alfredo




  • Grazie
    di Luca (utente non iscritto) data: 12/07/2016 15:38:38

    Ragazzi grazie 1000!
    in questo momento sono risucito a provare solo il codice di @Vecchio Frac, e funziona benissimo (per chiarire, io non avevo dubbi)

    Per favore non cancellate nulla, voglio studiare ed analizzare ogni riga di codice (appena trovo un attimo di tempo)

    grazie ancora sia ad @Vecchio Frac che a @alfrimpa, preparatissimi e gentilissimi!

    a presto,
    Luca



  • di Vecchio Frac data: 12/07/2016 15:56:44

    cit. Alfri "Certo che ce ne è da studiare"
    ---> Lo so, volevo far arrivare gradualmente Luca ai tanti concetti sottostanti, ma mi rendo conto che spesso come utenti non abbiamo il tempo o la voglia di ricevere lezioni non richieste e quindi è meglio fornire un codice buttato giù alla buona ma funzionante e riservarci l'analisi a momenti di maggior calma (ad avercene ^_^)