Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

salvare mail outlook sul disco fisso in una cartella

278 views
Skip to first unread message

mario rossi

unread,
Nov 2, 2022, 11:36:56 AM11/2/22
to
Buongiorno a tutti,

Con questo codice invio una mail da access con outlook, è possibile salvare copia del messaggio in un determinato percorso dando un determinato nome alla mail in una cartella del PC?

Dim OutlookApp As Outlook.Application
Dim MItem As Object
Dim Recipient As String
Dim Msg As String, fname As String

On Error Resume Next

Set OutlookApp = New Outlook.Application
Set MItem = OutlookApp.CreateItem(olMailItem)
With MItem
.To = destinatario
.Subject = Nz(oggetto, "")
.Body = Nz(Testo, "")
.Attachments.Add Nz(allegato, "")
.Activate
.display
.Activate
'.Send
End With

Set OutlookApp = Nothing

BFS

unread,
Nov 2, 2022, 12:15:56 PM11/2/22
to
a naso proverei

.SaveAs ("c:\tuacartella\tuaMail.eml")


BFS

BFS

unread,
Nov 2, 2022, 12:17:31 PM11/2/22
to

mario rossi

unread,
Nov 2, 2022, 12:22:53 PM11/2/22
to
ok grazie ho trovato anche un vecchio post del 2019
https://groups.google.com/g/it.comp.appl.access/c/YiJAQ_N_mxY/m/F611oWkaBwAJ

il mio problema è però il seguente, apro in anteprima il messaggio creato da vba, l'operatore può modificare tale messaggio scrivendo ulteriore testo e aggiungendo allegati e/o immagini all'interno del corpo della mail, infine clicca il tasto "invia"

è in questo momento che ho necessità di salvare il messaggio non prima di aprire l'anteprima altrimenti non ci sarebbero le modifiche dell''operatore

fattibile?












mario rossi

unread,
Nov 2, 2022, 12:56:17 PM11/2/22
to
ci sono quasi, dopo la sub "inviaMail" che apre in anteprima il messaggio per consentire all'operatore di modificare la mail eseguo una sub di nome "SaveLastSentItem"
il problema è che viene eseguita subito dopo la sub "inviaMail" quindi salva l'ultimo messaggio inviato in outlook che non è quello che l'operatore ha aperto in anteprima

è possibile mettere in attesa access e ritornare al codice dopo che l'operatore ha inviato la mail?

*** codice ****

Public Sub SaveLastSentItem(pathf As String, nomef As String)

Dim myItems As Object
Dim savePath As String

Set myItems = CreateObject("Outlook.Application").CreateItem(oMailItem)
Set Mail = myItems

Dim oApp As Outlook.Application
Dim myNameSpace As Outlook.NameSpace
Dim myFolder As Outlook.Folder
Dim myNewFolder As Outlook.Folder
Dim myItem As Outlook.MailItem
Dim myCopiedItem As Outlook.MailItem


Set oApp = New Outlook.Application

Set myNameSpace = oApp.GetNamespace("MAPI")

Set myFolder = myNameSpace.GetDefaultFolder(olFolderSentMail)

Set myItems = myFolder.Items

myItems.Sort ("[SentOn]")

Set myItem = myItems.GetLast


savePath = pathf '## Modify as needed
savePath = savePath & nomef


myItem.SaveAs savePath, OlSaveAsType.olMSG

End Sub







BFS

unread,
Nov 2, 2022, 1:03:07 PM11/2/22
to
è nel link che hai inserito la soluzione
RobertoA afferma che prima salva il messaggio per ottenere il suo id
una volta che hai l'id, anche se il messaggio viene modificato e poi
inviato l'id rimane quello.

quindi ti basta andartelo a recuperare e ri-salvarlo nella cartella che
vuoi.

magari posta il codice a cosa fatta che può tornare utile a tutti
BFS



mario rossi

unread,
Nov 2, 2022, 2:19:23 PM11/2/22
to
ho provato la riga Debug.print objOutlookMsg.EntryID
ma è vuoto objOutlookMsg.EntryID

ho pensato di procedere così, quando l'operatore chiude la schermata per tornare al menù principale si suppone che le mail siano state inviate
non saprei come impedire di uscire da quella form prima che le mail vengano effettivamente inviate (è possibile?)

cliccando quindi il pulsante "salva e torna al menù" vado a salvare l'ultimo messaggio inviato in outlook con getlast del mio esempio messaggi precedenti se ne ha inviato solo uno e se ha inviato più mail con un ciclo for eseguo
N volte getprevious salvando ogni volta i messaggi con:

myItem.SaveAs savePath, OlSaveAsType.olMSG

spero di essere riuscito a spiegarmi

BFS

unread,
Nov 3, 2022, 2:45:03 AM11/3/22
to
ti sbagli
ho appena provato

se aggiungi


.Save
Debug.Print .EntryID


il debug nel mio caso mi restituisce

0000000003C0152B8C360E40B1F52A54992DA66E24012000

che è l'id della mail che posso usare per andarmela a recuperare in ogni
momento

ciao
BFS

mario rossi

unread,
Nov 3, 2022, 10:43:59 AM11/3/22
to
ok EntryID era vuoto perchè prima non facevo .save
ma ora ti chiedo, in che modo salvo esattamente quel messaggio avente ID=EntryID?

grazie.

BFS

unread,
Nov 3, 2022, 11:01:54 AM11/3/22
to
non ti piace googolare vedo

fonte della funzione Outlook_OpenEmail
https://www.devhut.net/vba-retrieve-an-outlook-message-item/


sul tuo codice

'hai la mail in anteprima e la modifichi come vuoi
.Display (True)
'appena la invii il codice va avanti e ti salva e genera l'id della mail
modificata
.Save
Debug.Print .EntryID

'la funzione del link ti recupera la mail a video:
Outlook_OpenEmail .EntryID


quindi, nel tuo caso che non ti serve rivederla a video ma semplicemente
salvarla in altra cartella ti basta modificarla cosi

Set oNameSpace = oOutlook.GetNamespace("MAPI")
'Find the item, if not found it generates a -2147221233 error
Set oOutlookMsg = oNameSpace.GetItemFromID(sEntryId)
'Open/Display the item to the user
oOutlookMsg.saveas "metti qui tuo percorso"...



BFS





mario rossi

unread,
Nov 3, 2022, 12:47:50 PM11/3/22
to
la mail l'ho inviata ed è in posta inviata
l'ho salvata in una tabella temporanea nel campo di nome IDmail di tipo testo

Set myItem = myNameSpace.GetItemFromID(Rs!IDMail)

mi da errore: Errore di run-time '-2147221233(8004010f)':
Operazione non riuscita. impossibile trovare un offetto.

Qualche aiuto?




BFS

unread,
Nov 3, 2022, 1:09:09 PM11/3/22
to
devi modificare la funzione del link!

a cui passerai il tuo rs|!idmail
questa:

Function Outlook_OpenEmail(ByVal sEntryId As String)
'REF:
https://docs.microsoft.com/en-us/office/vba/api/outlook.namespace.getitemfromid
' #Const EarlyBind = 1 'Use Early Binding
#Const EarlyBind = 0 'Use Late Binding
#If EarlyBind Then
Dim oOutlook As Outlook.Application
Dim oOutlookMsg As Outlook.MailItem
#Else
Dim oOutlook As Object
Dim oOutlookMsg As Object
#End If

On Error Resume Next
Set oOutlook = GetObject(, "Outlook.Application") 'Bind to
existing instance of Outlook
If Err.Number <> 0 Then 'Could not get instance, so create a
new one
Err.Clear
Set oOutlook = CreateObject("Outlook.Application")
End If
On Error GoTo Error_Handler

Set oNameSpace = oOutlook.GetNamespace("MAPI")
'Find the item, if not found it generates a -2147221233 error
Set oOutlookMsg = oNameSpace.GetItemFromID(sEntryId)
'Open/Display the item to the user

'versione originale tii mostra la mail a video <<<<<<<<<<<<<<
' oOutlookMsg.Display

'tu invce vuoi salvarla quindi DEVI MODIFICARLA QUI...<<<<<<<<<
oOutlookMsg.SaveAs percorso etc etc

Error_Handler_Exit:
On Error Resume Next
If Not oOutlookMsg Is Nothing Then Set oOutlookMsg = Nothing
If Not oOutlook Is Nothing Then Set oOutlook = Nothing
Exit Function

Error_Handler:
If Err.Number = "287" Then
MsgBox "You clicked No to the Outlook security warning. " & _
"Rerun the procedure and click Yes to access e-mail " & _
"addresses to send your message. For more information, " & _
"see the document at http://www.microsoft.com/office" & _
"/previous/outlook/downloads/security.asp."
ElseIf Err.Number = -2147221233 Then
MsgBox "Outlook item not found.", vbInformation + vbOKOnly
Else
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: Outlook_OpenEmail" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
End If
Resume Error_Handler_Exit
End Function




mario rossi

unread,
Nov 3, 2022, 1:34:02 PM11/3/22
to
sapresti dirmi come modificare questo codice per fargli cercare il messaggio avente EntryID ricevuto come parametro ma nella cartella posta inviata
non so come fare.

mario rossi

unread,
Nov 3, 2022, 1:46:25 PM11/3/22
to
ho provato aggiungendo le seguenti righe ma nulla da fare
Set oNameSpace = oOutlook.GetNamespace("MAPI")
Set myFolder = oNameSpace.GetDefaultFolder(olFolderSentMail)
Set myItems = myFolder.Items
myItems.Sort ("[SentOn]")

da sempre errore "Outlook item not found."

mario rossi

unread,
Nov 4, 2022, 1:27:35 AM11/4/22
to
Help! Questa è la sub che sto provando, la eseguo e da errore alla riga
Set myItem = myNameSpace.GetItemFromID(EntryID, FolderID)

errore di run-time -2147221233 (8004010f)
Operazione non riuscita. Impossibile trovare un oggetto.

sia entryID che folderID sono correttamente valorizzati, il messaggio in posta inviata c'è
ma dall'errore sembra che non trova il messaggio, qualcuno può provarlo e scoprire se sul suo pc funziona? grazie.


***** code ****
Public Sub SalvaMail()
Dim myItems As Object
Dim savePath As String

Dim percorso As String
Dim nomefile As String
Dim FolderID As String

Dim oApp As Outlook.Application
Dim myNameSpace As Outlook.NameSpace
Dim myFolder As Outlook.Folder
Dim myNewFolder As Outlook.Folder
Dim myItem As Outlook.MailItem
Dim myCopiedItem As Outlook.MailItem
Dim omailitem
Dim mail
Dim i

Set myItems = CreateObject("Outlook.Application").CreateItem(omailitem)
Set mail = myItems


'imposto il nome del file
percorso = "c:\miacartella\"
nomefile = "messaggio.msg"

Set oApp = New Outlook.Application

Set myNameSpace = oApp.GetNamespace("MAPI")

Set myFolder = myNameSpace.GetDefaultFolder(olFolderSentMail)

'ottengo l'ID della cartella posta inviata
FolderID = myFolder.storeId

Set myItems = myFolder.Items

myItems.Sort ("[SentOn]")


Set myItem = myNameSpace.GetItemFromID(Rs!IDMail, FolderID)

savePath = percorso
savePath = savePath & nomefile

mario rossi

unread,
Nov 4, 2022, 1:34:14 AM11/4/22
to
Se commento la riga di codice
Set myItem = myNameSpace.GetItemFromID(Rs!IDMail, FolderID)

ed eseguo la riga di codice
Set myItem = myItems.GetLast

Salva l'ultimo messaggio inviato correttamente, lo utilizzerei così ma può accadere che l'operatore invia altre mail dopo aver inviato la mail che mi interessa salvare e quindi quella mail da salvare non è più l'ultima, devo usare quindi questa riga che non vuole saperne di funzionare, o meglio forse funziona ma non trova la mail e quindi da l'errore del mio messaggio precedente.

BFS

unread,
Nov 4, 2022, 2:40:33 AM11/4/22
to
non ho capito cosa ti schifa di questa funzione, pronta, chiara, funzionante

https://www.devhut.net/vba-retrieve-an-outlook-message-item/

per recuperare una mail dal suo id.
ti basta semplicemente sostituire il .display con .saveAs

non capisco perchè complicarsi la vita inutilmente

BFS

mario rossi

unread,
Nov 4, 2022, 1:38:20 PM11/4/22
to
Ok nel casino dello sviluppo credo di averla provata fra le tante prove fatte ma non pensavo che la soluzione fosse cosi semplice come scrivi, adesso la riprovo.
Grazie per aver rimarcato la cosa.

mario rossi

unread,
Nov 4, 2022, 1:57:37 PM11/4/22
to
Il giorno venerdì 4 novembre 2022 alle 07:40:33 UTC+1 BFS ha scritto:
Ecco perché avevo fatto altre prove, la riga di codice
Set oOutlookMsg = oNameSpace.GetItemFromID(sEntryId)
che riceve come parametro stringa il EntryID -->

00000000862F893433F6804EA5E48276F2CA4F9A070034AD76187591974DBF6C4F76951C873A010000000000000012C64DB6DB1A9D4588144FAB32E0F1DE0000000008CA0000

quel codice è stato assegnato al messaggio che mi interessa quando ho fatto .Save in fase di creazione della mail:
mi restituisce l'errore: Outlook Item Not found ovvero l'errore Err.Number = -2147221233

da quell'errore intuisco che tutto funziona ma access non trova il messaggio.
ma il messaggio posso garantire è presente in posta inviata e infatti se uso un altro esempio che preleva l'ultimo messaggio inviato con getlast funziona perfettamente
quello che ipotizzo è che il tuo esempio cerchi di default in una cartella diversa da "posta inviata" e per questo motivo non trova il messaggio?

fammi sapere se capisci il motivo.
Grazie.





mario rossi

unread,
Nov 4, 2022, 2:05:36 PM11/4/22
to
da questo articolo
https://learn.microsoft.com/it-it/office/vba/api/outlook.mailitem.entryid

cito:
The Entry ID changes when an item is moved into another store, for example, from your Inbox to a Microsoft Exchange Server public folder, or from one Personal Folders (.pst) file to another .pst file. Solutions should not depend on the EntryID property to be unique unless items will not be moved

traduzione:
L'ID voce cambia quando un elemento viene spostato in un altro archivio, ad esempio, dalla Posta in arrivo a una cartella pubblica di Microsoft Exchange Server o da un file delle cartelle personali (pst) a un altro file pst. Le soluzioni non devono dipendere dalla proprietà EntryID per essere univoca a meno che gli elementi non vengano spostati

Quando creo la mail e la salvo con .save ottengo un EntryID che salvo in una tabella temporanea
il mio dubbio è : da come si legge qui sopra quando un messaggio cambia posizione cambia anche entryID, quindi l'EntryID che cerco potrebbe essere diverso perchè una volta inviata la mail questa finisce (ipotizzo) dalla cartella "bozze" o "temp" alla cartella "inviata"? se cosi fosse come recuperare il nuovo EntryID che viene assegnato al messaggio quando va a finire in posta inviata?


mario rossi

unread,
Nov 4, 2022, 2:29:34 PM11/4/22
to
esiste un modo in outlook o con qualche utility di sapere il codice EntryID di un determinato messaggio? in questo modo potrei capire se il codice EntryId che cerco è diverso da quello che è assegnato al messaggio che cerco quando viene spostato in posta inviata.

grazie.

mario rossi

unread,
Nov 4, 2022, 10:57:57 PM11/4/22
to
Ho scoperto il problema, confermo che EntryID della stessa mail è diverso quando il messaggio viene creato e subito salvato con .Save e quando viene modificato e poi inviato e finisce in posta inviata di outlook
per recuperare il nuovo EntryID ho usato una Sub che applica delle restrizioni agli oggetti items le mail presenti in posta inviata a quel punto ho provato a passare il nuovo EntryID e il codice di BFS funziona perfettamente.

per maggiori info sul metodo restrict leggere questo articolo https://learn.microsoft.com/en-us/office/vba/api/outlook.items.restrict
secondo voi negli oggetti presenti in questo articolo c'è l'oggetto mail destinatario che magari ha un altro nome? io non la vedo.

il codice di ricerca è

Public Sub CercaEmail()
Dim oINS As NameSpace
Dim Folderinbox As MAPIFolder
Dim filtered_items As Items
Dim strFilter As String
Dim olMail As MailItem

Set oINS = GetNamespace("MAPI")
Set Folderinbox = oINS.GetDefaultFolder(olFolderSentMail)

strFilter = "@SQL= urn:schemas:httpmail:subject LIKE '%STRINGA DA CERCARE NEL SUBJECT%'"
Set filtered_items = Folderinbox.Items.Restrict(strFilter)

If filtered_items.Count = 0 Then
GoTo empty_objects
End If

For Each olMail In filtered_items

Debug.Print olMail.Subject
Debug.Print olMail.SenderEmailAddress
Debug.Print olMail.entryId
Debug.Print olMail.To

Next olMail

empty_objects:
Set Folderinbox = Nothing
Set oINS = Nothing
End Sub


mario rossi

unread,
Nov 5, 2022, 1:04:40 PM11/5/22
to
La domanda però sorge spontanea se EntryID di uno stesso messaggio cambia a che serve la possibilità di salvarlo in una tabella se poi quello nella tabella non esiste più in outlook? mi è sfuggito qualcosa?



mario rossi

unread,
Nov 15, 2022, 2:43:15 AM11/15/22
to
Il giorno venerdì 4 novembre 2022 alle 07:40:33 UTC+1 BFS ha scritto:
ti confermo quanto da me sospettato ovvero che EntryID può cambiare e quindi non si capisce l'utilità di salvarlo in una tabella se poi non serve per ritrovare quel messaggio in outlook

questa è la risposta ufficiale del programmatore che ha pubblicato la sub che mi hai consigliato, puoi leggerla anche in fondo al tuo link

link https://www.devhut.net/vba-retrieve-an-outlook-message-item/

--- mia domanda
L’ho provata e mi restituisce “Outlook item not found.”
Il messaggio che cerco però è presente nella cartella outlook posta inviata
come parametro EntryID gli passo la stringa che identifica il messaggio che ho salvato in una tabella in fase di creazione del messaggio eseguendo .save

Quale potrebbe essere il motivo per cui non trova il messaggio? forse il codice EntryID assegnato in fase di creazione cambia quando il messaggio viene spostato in posta inviata?
se cosi fosse come potrei risalire al nuovo EntryID?
--- mia domanda

--- risposta
The EntryId can change if, for instance if the item is moved. It’s a real pain and something I’ve never understood the reason for. So sometimes it may be better to locate an item by
date/time, subject, sender, recipient(s), …
--- risposta

--- risposta tradotta
L'EntryId può cambiare se, ad esempio, se l'elemento viene spostato. È un vero dolore e qualcosa di cui non ho mai capito il motivo. Quindi a volte potrebbe essere meglio individuare
un articolo per data/ora, oggetto, mittente, destinatario/i,...
--- risposta tradotta

RobertoA

unread,
Nov 15, 2022, 2:49:23 AM11/15/22
to
Ma lo spostamento messaggio da una all'altra cartella, non potresti
farlo da codice?
Magari ti viene restituito il nuovo EntryID messaggio

BFS

unread,
Nov 15, 2022, 3:35:24 AM11/15/22
to
mi sfugge una cosa

il tuo post è "salvare mail outlook sul disco fisso in una cartella"

quindi una volta che hai l'id della mail e la salvi su cartella windows
che ti frega se poi l'id cambia perchè qualcuno sposta la mail in outlook?


Nella tabella ti memorizzi il percorso del file eml sul disco e non l'id
e te la recuperi con quello.
Ti metterebbe al riparo da cancellazioni involontarie dell'utente in
outlook e in più se salvata in share di rete di recuperarla da ogni
postazione

BFS






RobertoA

unread,
Nov 15, 2022, 4:33:36 AM11/15/22
to
Credo scriva di 'cartelle' dentro Outlook
Non del sistema operativo

mario rossi

unread,
Nov 15, 2022, 6:11:09 AM11/15/22
to
l'operatore clicca un pulsante in access che crea una mail outlook in anteprima che salvo con .save e ottengo EntryID
poi però l'operatore modifica a suo piacere la mail e infine clicca il pulsante invia di outlook che mette la mail in cartella "posta inviata" di outlook
nel mentre che la mail passa da bozze (credo) a "inviata" cambia EntryID e quindi quello salvato prima non serve a nulla.

Soltanto dopo che l'operatore ha inviato la mail devo salvarla in una cartella su disco c:\miacartella

al momento ho risolto mettendo un numero ordine univoco nell'oggetto e utilizzando i metodi restrict di vba per outlook come indicato in qualche post precedente di questa discussione.






BFS

unread,
Nov 15, 2022, 8:45:07 AM11/15/22
to
non vorrei dire una fesseria ma
se dopo il tuo
.display
metti
.saveAs "c:\miacartella"

il codice va interruzione tra display e saveAs

quindi nel momento in cui l'operatore clicca su invia si passa a .saveAs
quindi nella tua cartella hai gia l'ultima versione della mail.
a questo punto l'id non ti serve a nulla
memorizzati il percorso di dove hai salvato il file e stop

BFS

mario rossi

unread,
Nov 15, 2022, 9:42:15 AM11/15/22
to
interessante lo proverò.
0 new messages