I am having trouble getting this loop to work. Any advice?
Sub SaveEmailAttachmentsToFolder(OutlookFolderInInbox As String, _
ExtString As String, DestFolder As String)
Dim ns As NameSpace
Dim Inbox As MAPIFolder
Dim SubFolder As MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim MyDocPath As String
Dim i As Integer
Dim wsh As Object
Dim fs As Object
Dim InboxMsg As Object
On Error GoTo ThisMacro_err
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
Set SubFolder = Inbox.Folders(OutlookFolderInInbox)
'To fix my issue I may have to change the loop to repeat the same number of
times as attachments
' Check subfolder for messages and exit of none found
' strFilter = "[Unread] = True"
' Set inboxItems =
ns.GetDefaultFolder(olFolderInbox).Folders(OutlookFolderInInbox).Items.Restrict(strFilter)
If SubFolder.UnReadItemCount = 0 Then
MsgBox "There are no New messages in this folder : " &
OutlookFolderInInbox, _
vbInformation, "Nothing Found"
Set SubFolder = Nothing
Set Inbox = Nothing
Set ns = Nothing
Exit Sub
End If
'Create DestFolder if DestFolder = ""
If DestFolder = "" Then
Set wsh = CreateObject("WScript.Shell")
Set fs = CreateObject("Scripting.FileSystemObject")
MyDocPath = wsh.SpecialFolders.Item("mydocuments")
DestFolder = MyDocPath & "\" & Format(Now, "dd-mmm-yyyy hh-mm-ss")
If Not fs.FolderExists(DestFolder) Then
fs.CreateFolder DestFolder
End If
End If
If Right(DestFolder, 1) <> "\" Then
DestFolder = DestFolder & "\"
End If
' Check each message for attachments and extensions
strFilter = "[Unread] = True"
Set inboxItems =
ns.GetDefaultFolder(olFolderInbox).Folders(OutlookFolderInInbox).Items.Restrict(strFilter)
' For Each Item In inboxItems
For i = inboxItems.Count To 1 Step -1 'Iterates from the end backwards
Set InboxMsg = Inbox.Items(i)
'For Each Item In inboxItems
' For Each Atmt In inboxItems(I).Attachments
For Each Atmt In InboxMsg.Attachments
If LCase(Right(Atmt.FileName, Len(ExtString))) = LCase(ExtString)
Then
FileName = DestFolder & Format(Item.ReceivedTime, "yyyy-mmm-dd") & Atmt.FileName
Atmt.SaveAsFile FileName
End If
Item.UnRead = "False"
' inboxItems(I).UnRead = "False"
Next Atmt
' Item.UnRead = "false"
Next
' Show this message when Finished
If i = 0 Then
MsgBox "You can find the files here : " _
& DestFolder, vbInformation, "Finished!"
Else
MsgBox "No attached files in your mail.", vbInformation, "Finished!"
End If
' Clear memory
ThisMacro_exit:
Set SubFolder = Nothing
Set Inbox = Nothing
Set ns = Nothing
Set fs = Nothing
Set wsh = Nothing
Exit Sub
' Error information
ThisMacro_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: SaveEmailAttachmentsToFolder" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume ThisMacro_exit
End Sub
Here is Quick example, set filter for both UnRead & Items with Attachments
Option Explicit
Public Sub Example()
Dim olNs As Outlook.NameSpace
Dim Inbox As Outlook.MAPIFolder
Dim Items As Outlook.Items
Dim i As Long
Dim Filter As String
Set olNs = Application.GetNamespace("MAPI")
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
Filter = "#SQL=" & Chr(34) & "urn:schemas:httpmail:hasattachment" & _
Chr(34) & "=1 AND " & _
Chr(34) & "urn:schemas:httpmail:read" & _
Chr(34) & "=0"
Set Items = Inbox.Items.Restrict(Filter)
For i = Items.Count To 1 Step -1
Debug.Print Items(i) 'Immediate Window
Next
End Sub
I am trying to make the below output into a text file on my desktop. I am very new (as in today) and I found the below script online, I have gotten my head around what each but does however I am struggling to make it output as a text file. I am not sure where the commands should go (beginning middle or end?) to do this. I have found one command but I am getting errors left right and centre. Please help.
Sub CountItemsInMBX()
Dim outapp As Outlook.Application
Set outapp = CreateObject("Outlook.Application")
Dim olns As Outlook.NameSpace
Set olns = outapp.GetNamespace("MAPI")
Debug.Print GetSubFolderCount(olns.GetDefaultFolder(olFolderInbox).Parent)
End Sub
Function GetSubFolderCount(objParentFolder As MAPIFolder) As Long
Dim currentFolders As Folders
Dim fldCurrent As MAPIFolder
Set currentFolders = objParentFolder.Folders
If currentFolders.Count > 0 Then
Set fldCurrent = currentFolders.GetFirst
While Not fldCurrent Is Nothing
TempFolderCount = TempFolderCount + GetSubFolderCount(fldCurrent)
Set fldCurrent = currentFolders.GetNext
Wend
Debug.Print objParentFolder.Name & " - " & objParentFolder.Items.Count
GetSubFolderCount = TempFolderCount + objParentFolder.Items.Count
Else
Debug.Print objParentFolder.Name & " - " & objParentFolder.Items.Count
GetSubFolderCount = objParentFolder.Items.Count
End If
End Function
The following is your code, converted to call a function, passing it a string, that will write to a text file. Change the file path & name to suit your needs.
Personally, I don't like the call method because it is a waste to check if the file exists, etc. for every call. However, since your code had two subroutines that need to write text, I was too lazy to embed the proper code in your code. You could either leave as is (if seldom used), or combine together if desired.
Option Explicit
Sub CountItemsInMBX()
Dim outapp As Outlook.Application
Dim olns As Outlook.NameSpace
Set outapp = CreateObject("Outlook.Application")
Set olns = outapp.GetNamespace("MAPI")
'Debug.Print GetSubFolderCount(olns.GetDefaultFolder(olFolderInbox).Parent)
Write_To_MyLog GetSubFolderCount(olns.GetDefaultFolder(olFolderInbox).Parent)
End Sub
Function GetSubFolderCount(objParentFolder As MAPIFolder) As Long
Dim currentFolders As Folders
Dim fldCurrent As MAPIFolder
Dim TempFolderCount As Integer
Set currentFolders = objParentFolder.Folders
If currentFolders.Count > 0 Then
Set fldCurrent = currentFolders.GetFirst
While Not fldCurrent Is Nothing
TempFolderCount = TempFolderCount + GetSubFolderCount(fldCurrent)
Set fldCurrent = currentFolders.GetNext
Wend
'Debug.Print objParentFolder.Name & " - " & objParentFolder.Items.Count
Write_To_MyLog objParentFolder.Name & " - " & objParentFolder.Items.Count
GetSubFolderCount = TempFolderCount + objParentFolder.Items.Count
Else
'Debug.Print objParentFolder.Name & " - " & objParentFolder.Items.Count
Write_To_MyLog objParentFolder.Name & " - " & objParentFolder.Items.Count
GetSubFolderCount = objParentFolder.Items.Count
End If
End Function
Public Function Write_To_MyLog(sText As String)
Dim oFSO As FileSystemObject
Dim oFile As File
Dim oStream As TextStream
On Error GoTo Error_trap
Set oFSO = New FileSystemObject
If Not oFSO.FileExists("C:\Temp\Outlook_Folders.txt") Then
Set oStream = oFSO.CreateTextFile("C:\Temp\Outlook_Folders.txt")
oStream.WriteLine " "
Else
Set oFile = oFSO.GetFile("C:\Temp\Outlook_Folders.txt")
Set oStream = oFile.OpenAsTextStream(ForAppending, TristateMixed)
End If
oStream.WriteLine sText
oStream.Close
Set oStream = Nothing
Set oFile = Nothing
Set oFSO = Nothing
Early_Exit:
Exit Function
Error_trap:
Dim strError As String
strError = "In subroutine: Write_To_MyLog " & vbCrLf & _
Err.Number & vbCrLf & vbCrLf & Err.Description & vbCrLf & _
"At Line: " & Erl
Err.Source = "Module_Utilities: Write_To_MyLog at Line: " & Erl
MsgBox "Error: " & strError
'Write_To_Log strError ' This is a call to a function that saves the error info to a database table.
Resume Early_Exit
Resume Next
End Function
I have macro that searches for a subject and if found copy the email in another folder. My problem is that it copies the email 4 times instead of only once. If i have 10 emails in the original folder "Left Ones" then, after search and copy i will have 40 emails in the folder "TO BE REMOVED" . Any help is welcomed, thank you.
Sub Search_Inbox()
Dim myOlApp As New Outlook.Application
Dim objNamespace As Outlook.NameSpace
Dim objFolder As Outlook.MAPIFolder
Dim filteredItems As Outlook.Items
Dim itm As Object
Dim Found As Boolean
Dim strFilter As String
Dim subject_to_find As String
Dim myDestFolder As Outlook.Folder
subject_to_find = "something"
Set objNamespace = myOlApp.GetNamespace("MAPI")
Set objFolder = OpenOutlookFolder("\\Mailbox - ME\Inbox\Left Ones")
strFilter = "#SQL=" & Chr(34) & "urn:schemas:httpmail:subject" & Chr(34) & " like '%" & subject_to_find & "%'"
Set filteredItems = objFolder.Items.Restrict(strFilter)
If filteredItems.Count = 0 Then
Debug.Print "No emails found"
Found = False
Else
Found = True
For Each itm In filteredItems
If itm.Class = olMail Then
Debug.Print itm.Subject
Debug.Print itm.ReceivedTime
End If
Set myDestFolder = Session.Folders("Mailbox - ME").Folders("TO BE REMOVED")
For i = filteredItems.Count To 1 Step -1
Dim myCopiedItem As Object
Set myCopiedItem = filteredItems(i).Copy
myCopiedItem.Move myDestFolder
Next i
Next itm
End If
'If the subject isn't found:
If Not Found Then
'NoResults.Show
Else
Debug.Print "Found " & filteredItems.Count & " items."
End If
Set myOlApp = Nothing
End Sub
After
Else
Found = True
add the line
Debug.Print filteredItems.Count
This is to check the number of items found. This way, you can definitely see if VBA actually finds 40 emails (for whatever reason), or if it just copies it 4 times later on.
Also try Changing
Next i
to
i = i + 1
Edit:
Cut the
Next itm
and move it to the end of this block:
For Each itm In filteredItems
If itm.Class = olMail Then
Debug.Print itm.Subject
Debug.Print itm.ReceivedTime
End If
Next itm 'move it here
For future searchers here is the working code to find all the emails with a given subject in a subfolder - Inbox\Left Ones - and copy them in another subfolder - Inbox\TO BE REMOVED - ( note that it will leave out the undelivered notification ) :
Sub Search_Inbox_Subfolder_Left_Ones()
Dim objFolder As Outlook.MAPIFolder
Dim filteredItems As Outlook.Items
Dim itm As Object
Dim Found As Boolean
Dim strFilter As String
Dim subject_to_find As String
Dim myDestFolder As Outlook.Folder
Dim myCopiedItem As Object
subject_to_find = "something to find"
Set objFolder = OpenOutlookFolder("\\Mailbox - ME\Inbox\Left Ones")
strFilter = "#SQL=" & Chr(34) & "urn:schemas:httpmail:subject" & Chr(34) & " like '%" & subject_to_find & "%'"
Set filteredItems = objFolder.Items.Restrict(strFilter)
If filteredItems.Count = 0 Then
Debug.Print "No emails found"
Found = False
Else
Found = True
Set myDestFolder = Session.Folders("Mailbox - ME").Folders("TO BE REMOVED")
For i = filteredItems.Count To 1 Step -1
If filteredItems(i).Class = olMail Then
Set myCopiedItem = filteredItems(i).Copy
myCopiedItem.Move myDestFolder
End If
Next i
End If
'If the subject isn't found:
If Not Found Then
'NoResults.Show
Else
Debug.Print "Found " & filteredItems.Count & " items."
End If
Set myOlApp = Nothing
End Sub
Private Function OpenOutlookFolder(strFolderPath As String) As Outlook.MAPIFolder
Dim arrFolders As Variant, _
varFolder As Variant, _
bolBeyondRoot As Boolean
On Error Resume Next
If strFolderPath = "" Then
Set OpenOutlookFolder = Nothing
Else
Do While Left(strFolderPath, 1) = "\"
strFolderPath = Right(strFolderPath, Len(strFolderPath) - 1)
Loop
arrFolders = Split(strFolderPath, "\")
For Each varFolder In arrFolders
Select Case bolBeyondRoot
Case False
Set OpenOutlookFolder = Outlook.Session.Folders(varFolder)
bolBeyondRoot = True
Case True
Set OpenOutlookFolder = OpenOutlookFolder.Folders(varFolder)
End Select
If Err.Number <> 0 Then
Set OpenOutlookFolder = Nothing
Exit For
End If
Next
End If
On Error GoTo 0
End Function
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 7 years ago.
Improve this question
I am curious to know how to move emails from a specific subfolder to my hard drive. Basically, my inbox has about 20 subfolders. I want to be able to move all the emails from subfolder1 to my hard drive.
Is there a macro to specifically go to that folder and move all the emails onto my hard drive? Granted I do want to keep all the emails in .msg rather than being a .txt file.
I bielive you can develop a VBA macro or add-in to get the job done. See Getting Started with VBA in Outlook 2010 to get started.
The SaveAs method of the MailItem class saves the Microsoft Outlook item to the specified path and in the format of the specified file type. If the file type is not specified, the MSG format (.msg) is used. The file type to save can be one of the following OlSaveAsType constants: olHTML, olMSG, olRTF, olTemplate, olDoc, olTXT, olVCal, olVCard, olICal, or olMSGUnicode. For example:
Sub SaveAsMSG()
Dim myItem As Outlook.Inspector
Dim objItem As Object
Set myItem = Application.ActiveInspector
If Not TypeName(myItem) = "Nothing" Then
Set objItem = myItem.CurrentItem
strname = objItem.Subject
'Prompt the user for confirmation
Dim strPrompt As String
strPrompt = "Are you sure you want to save the item? " & _
"If a file with the same name already exists, " & _
"it will be overwritten with this copy of the file."
If MsgBox(strPrompt, vbYesNo + vbQuestion) = vbYes Then
objItem.SaveAs Environ("HOMEPATH") & "\My Documents\" & strname & ".msg", olMSG
End If
Else
MsgBox "There is no current active inspector."
End If
End Sub
This should allow you to select outlook folder and hard drive folder, All emails in that folder and all sub folders will be saved to your HD
Option Explicit
Sub SaveMsgToFolders()
Dim i, j, n As Long
Dim sSubject As String
Dim sName As String
Dim sFile As String
Dim sReceived As String
Dim sPath As String
Dim sFolder As String
Dim sFolderPath As String
Dim SaveFolder As String
Dim Prompt As String
Dim Title As String
Dim iNameSpace As NameSpace
Dim olApp As Outlook.Application
Dim SubFolder As MAPIFolder
Dim olmItem As MailItem
Dim FSO, ChosenFolder As Object
Dim Folders As New Collection
Dim EntryID As New Collection
Dim StoreID As New Collection
Set FSO = CreateObject("Scripting.FileSystemObject")
Set olApp = Outlook.Application
Set iNameSpace = olApp.GetNamespace("MAPI")
Set ChosenFolder = iNameSpace.PickFolder ' // Chose Outlook Folder
If ChosenFolder Is Nothing Then
GoTo ExitSub:
End If
Prompt = "Please enter the path to save all the emails to."
Title = "Folder Specification"
sPath = BrowseForFolder
If sPath = "" Then
GoTo ExitSub:
End If
If Not Right(sPath, 1) = "\" Then
sPath = sPath & "\"
End If
Call GetFolder(Folders, EntryID, StoreID, ChosenFolder)
For i = 1 To Folders.Count
sFolder = StripIllegalChar(Folders(i))
n = InStr(3, sFolder, "\") + 1
sFolder = Mid(sFolder, n, 256)
sFolderPath = sPath & sFolder & "\"
SaveFolder = Left(sFolderPath, Len(sFolderPath) - 1) & "\"
If Not FSO.FolderExists(sFolderPath) Then
FSO.CreateFolder (sFolderPath)
End If
Set SubFolder = olApp.Session.GetFolderFromID(EntryID(i), StoreID(i))
On Error Resume Next
For j = 1 To SubFolder.Items.Count
Set olmItem = SubFolder.Items(j)
sReceived = ArrangedDate(olmItem.ReceivedTime)
sSubject = olmItem.Subject
sName = StripIllegalChar(sSubject)
sFile = SaveFolder & sReceived & "_" & sName & ".msg"
sFile = Left(sFile, 256)
olmItem.SaveAs sFile, 3
Next j
On Error GoTo 0
Next i
ExitSub:
End Sub
Function StripIllegalChar(StrInput)
Dim RegX As Object
Set RegX = CreateObject("vbscript.regexp")
RegX.Pattern = "[\" & Chr(34) & "\!\#\#\$\%\^\&\*\(\)\=\+\|\[\]\{\}\`\'\;\:\<\>\?\/\,]"
RegX.IgnoreCase = True
RegX.Global = True
StripIllegalChar = RegX.Replace(StrInput, "")
ExitFunction:
Set RegX = Nothing
End Function
Function ArrangedDate(sDateInput)
Dim sFullDate As String
Dim sFullTime As String
Dim sAMPM As String
Dim sTime As String
Dim sYear As String
Dim sMonthDay As String
Dim sMonth As String
Dim sDay As String
Dim sDate As String
Dim sDateTime As String
Dim RegX As Object
Set RegX = CreateObject("vbscript.regexp")
If Not Left(sDateInput, 2) = "10" And _
Not Left(sDateInput, 2) = "11" And _
Not Left(sDateInput, 2) = "12" Then
sDateInput = "0" & sDateInput
End If
sFullDate = Left(sDateInput, 10)
If Right(sFullDate, 1) = " " Then
sFullDate = Left(sDateInput, 9)
End If
sFullTime = Replace(sDateInput, sFullDate & " ", "")
If Len(sFullTime) = 10 Then
sFullTime = "0" & sFullTime
End If
sAMPM = Right(sFullTime, 2)
sTime = sAMPM & "-" & Left(sFullTime, 8)
sYear = Right(sFullDate, 4)
sMonthDay = Replace(sFullDate, "/" & sYear, "")
sMonth = Left(sMonthDay, 2)
sDay = Right(sMonthDay, Len(sMonthDay) - 3)
If Len(sDay) = 1 Then
sDay = "0" & sDay
End If
sDate = sYear & "-" & sMonth & "-" & sDay
sDateTime = sDate & "_" & sTime
RegX.Pattern = "[\:\/\ ]"
RegX.IgnoreCase = True
RegX.Global = True
ArrangedDate = RegX.Replace(sDateTime, "-")
ExitFunction:
Set RegX = Nothing
End Function
Sub GetFolder(Folders As Collection, EntryID As Collection, StoreID As Collection, Fld As MAPIFolder)
Dim SubFolder As MAPIFolder
Folders.Add Fld.FolderPath
EntryID.Add Fld.EntryID
StoreID.Add Fld.StoreID
For Each SubFolder In Fld.Folders
GetFolder Folders, EntryID, StoreID, SubFolder
Next SubFolder
ExitSub:
Set SubFolder = Nothing
End Sub
Function BrowseForFolder(Optional OpenAt As String) As String
Dim ShellApp As Object
Set ShellApp = CreateObject("Shell.Application"). _
BrowseForFolder(0, "Please choose a folder", 0, OpenAt)
On Error Resume Next
BrowseForFolder = ShellApp.self.Path
On Error GoTo 0
Select Case Mid(BrowseForFolder, 2, 1)
Case Is = ":"
If Left(BrowseForFolder, 1) = ":" Then
BrowseForFolder = ""
End If
Case Is = "\"
If Not Left(BrowseForFolder, 1) = "\" Then
BrowseForFolder = ""
End If
Case Else
BrowseForFolder = ""
End Select
ExitFunction:
Set ShellApp = Nothing
End Function
I am looking to move emails from a folder to the deleted folder of the below mailbox. I get a "compile error: variable not defined" message, where have I gone wrong?
Sub MoveToFolder(folderName)
mailboxNameString = "Mailbox - David Beach"
Dim olApp As New Outlook.Application
Dim olNameSpace As Outlook.NameSpace
Dim olCurrExplorer As Outlook.Explorer
Dim olCurrSelection As Outlook.Selection
Dim olDestFolder As Outlook.MAPIFolder
Dim olCurrMailItem As MailItem
Dim m As Integer
Set olNameSpace = olApp.GetNamespace("MAPI")
Set olCurrExplorer = olApp.ActiveExplorer
Set olCurrSelection = olCurrExplorer.Selection
Set olDestFolder = olNameSpace.Folders(mailboxNameString).Folders(folderName)
For m = 1 To olCurrSelection.Count
Set olCurrMailItem = olCurrSelection.Item(m)
Debug.Print "[" & Date & " " & Time & "] moving #" & m & _
": folder = " & folderName & _
"; subject = " & olCurrMailItem.Subject & "..."
olCurrMailItem.Move olDestFolder
Next m
End Sub
Sub Delete()
MoveToFolder ("Deleted Items")
End Sub
This line is for Outlook 2003. mailboxNameString = "Mailbox - David Beach"
Take a look at your 2010 mailbox and use that name.