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
Related
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 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
I am using the below code to archive emails that have been marked completed. It is supposed to check all emails in our shared folder for anything marked complete prior to today's date. It works, but I must run the code multiple times to archive all of the affected quoted. Does anyone have any ideas how to get this to work in one shot?
Public Const CEpath As String = "\\s-estimating\CentralEstimating\"
Option Explicit
Public Const sArchivePath As String = Miscellaneous.CEpath + "Archives\"
Public Sub ArchiveInbox()
Dim dtDateToMove As Date
Dim iMessageCount As Integer
Dim oDestination As MAPIFolder
Dim oFileName As String
Dim oNamespace As NameSpace
Dim oMailItem As MailItem
Dim oProgress As New ProgressDialogue
Dim oSource As MAPIFolder
Dim oStore As Store
Dim oOSPsource As MAPIFolder
'Dim oOSPDestination As MAPIFolder
On Error GoTo HandleError
' Obtain a NameSpace object reference.
Set oNamespace = Application.GetNamespace("MAPI")
Set oStore = oNamespace.Stores.item("Rings")
Set oSource = oStore.GetDefaultFolder(olFolderInbox)
' try to connect to the OSP Folder
On Error Resume Next
'Debug.Print oSource.Folders("OSP Quotes").Items.count
Set oOSPsource = oSource.Folders("OSP Quotes")
On Error GoTo HandleError
' Start Progess form
oProgress.Configure title:="Archive Old RFQs", _
status:="Please stand by while the operation is being processed…", _
Min:=0, _
Max:=CDbl(oSource.Items.count), _
optShowTimeElapsed:=True, _
optShowTimeRemaining:=True
oProgress.Show vbModeless
' Open Archive (or create and open)
dtDateToMove = PreviousBusinessDay(Date)
If Month(PreviousBusinessDay(Date)) < 7 Then
oFileName = "RFQs " & Year(dtDateToMove) & " - Jan-Jun"
Else
oFileName = "RFQs " & Year(dtDateToMove) & " - Jul-Dec"
End If
' Debug.Print dtDateToMove
' Debug.Print oFileName
oNamespace.AddStoreEx Store:=sArchivePath & oFileName & ".pst", _
Type:=olStoreUnicode
Set oDestination = oNamespace.Folders.GetLast
If Not oDestination.Name = oFileName Then oDestination.Name = oFileName
' Sort through all closed emails in Rings and move them to the archive folder
For Each oMailItem In oSource.Items
iMessageCount = iMessageCount + 1
If oProgress.cancelIsPressed Then Exit For
' Debug.Print " " & oMailItem.TaskCompletedDate
If oMailItem.FlagStatus = olFlagComplete Then
If oMailItem.IsConflict Then
Err.Raise Number:=95, _
Description:="Mail Item Conflict Detected"
End If
If oMailItem.TaskCompletedDate <= dtDateToMove Then
oMailItem.Move oDestination
' Debug.Print " Moved"
End If
End If
oProgress.SetValue iMessageCount
Next oMailItem
ExitRoutine:
oProgress.Hide
If oOSPsource Is Nothing Then
Debug.Print "OSP Quotes folder was not found."
Else
If oOSPsource.Items.count > 0 Then
MsgBox "There are items in OSP Quotes.", vbInformation + vbOKOnly
End If
End If
' close the store
oNamespace.RemoveStore oDestination
Set oProgress = Nothing
Set oDestination = Nothing
' Set oOSPDestination = Nothing
Set oOSPsource = Nothing
Set oSource = Nothing
Set oStore = Nothing
Set oNamespace = Nothing
Exit Sub
HandleError:
Debug.Print Err.Number
Debug.Print Err.Description
Select Case Err.Number
Case 95
MsgBox Prompt:=oMailItem.Subject & vbCrLf & vbCrLf & "An email with the above subject line is in conflict." & _
vbCrLf & "You will need to resolve the conflict and run Export to Excel again.", _
Buttons:=vbCritical + vbOKOnly, _
title:="Conflict Resolution Required"
oProgress.Hide
GoTo ExitRoutine
Case Else
If Not ErrorHandling.ErrorLog(Err.Number, Err.Description, "Archive The Inbox") Then
Err.Clear
Resume
End If
End Select
End Sub
Do not use "for each" loop if you are modifying the collection
Change the loop
For Each oMailItem In oSource.Items
to a down "for" loop:
dim oItems = oSource.Items
for I = oItems.Count to 1 step -1
set oMailItem = oItems.Item(I)
This Outlook macro is supposed to, when the local folder has 5 emails, ask the user to move them to a public shared folder and delete the original 5 emails.
I keep getting this "Operation failed" error message on the line below.
**Set NewFolder = myFolder.CopyTo(PblcSharedFolder)**
From comment: This line is meant to copy the entire folder of five emails.
Sub MoveEmail()
Dim app As New Outlook.Application
Dim nameSpace As Outlook.nameSpace
Dim currentExplorer As Outlook.Explorer
Dim currentSelection As Outlook.selection
Dim currentMailItem As MailItem
Dim emailCopy As MailItem
Dim myFolder
Dim PblcSharedFolder As MAPIFolder
Dim NewFolder As MAPIFolder
Dim i As Integer
Dim folderName
Dim mailboxNameString
Dim result
folderName = "Local Folder"
mailboxNameString = "My Inbox Name"
Set nameSpace = app.GetNamespace("MAPI")
Set currentExplorer = app.ActiveExplorer
Set currentSelection = currentExplorer.selection
Set myFolder = nameSpace.Folders(mailboxNameString).Folders("Inbox").Folders(folderName)
If (myFolder.Items.Count = 5) Then
result = MsgBox("Would you like to move the content of your Local folder to the Public-shared Folder?", vbYesNo)
If result = vbYes Then
Set PblcSharedFolder = nameSpace.GetDefaultFolder(olPublicFoldersAllPublicFolders)
Set PblcSharedFolder = PblcSharedFolder.Folders("Subfolder")
Set PblcSharedFolder = PblcSharedFolder.Folders("Public Shared Folder")
Set NewFolder = myFolder.CopyTo(PblcSharedFolder)
NewFolder.Name = "_" & nameSpace.CurrentUser.Name & " " & Now
For i = myFolder.Items.Count To 1 Step -1
myFolder.Items(i).Delete
Next i
Else
Stop
End If
End If
For i = 1 To currentSelection.Count
Set currentMailItem = currentSelection.Item(i)
Debug.Print "[" & Date & " " & Time & "] moving #" & m & _
": xfolder = " & folderName & _
"; subject = " & currentMailItem.Subject & "..."
currentMailItem.To = nameSpace.CurrentUser.Name
currentMailItem.Move myFolder
Next i
End Sub
untested!
If result = vbYes Then
Set PblcSharedFolder = nameSpace.GetDefaultFolder(olPublicFoldersAllPublicFolders)
Set PblcSharedFolder = PblcSharedFolder.Folders("Subfolder")
Set PblcSharedFolder = PblcSharedFolder.Folders("Public Shared Folder")
Dim myCopiedItem As Outlook.MailItem
For i = myFolder.Items.Count To 1 Step -1
Set myCopiedItem = myFolder.Items(i).Copy
myCopiedItem.Move PblcSharedFolder
myFolder.Items(i).Delete
Next i
Else
Stop
End If
I did to be honest not quite unterstand what this line is for:
NewFolder.Name = "_" & nameSpace.CurrentUser.Name & " " & Now
There are instances when we forget to cancel a meeting which we scheduled, maybe due to absence of someone important, or maybe due to lack of time. But in many cases we forget to cancel the meeting from outlook. So, I am looking for a VBA code which will ask the organizer of a meeting if the meeting is good to go, or if it is to be cancelled, and will send out a cancellation mail if it is to be cancelled. Please help me with this. Thanks in advance! :)
After using the code from #alina as well as some other macro's from around the web, I came up with a solution for the same which i am sharing here.
Public WithEvents objReminders As Outlook.Reminders
Sub Initialize_handler()
Set objReminders = Application.Reminders
End Sub
Private Sub objReminders_ReminderFire(ByVal ReminderObject As reminder)
Dim oApp As Outlook.Application
Dim oNameSpace As Outlook.NameSpace
Dim oApptItem As Outlook.AppointmentItem
Dim oFolder As Outlook.MAPIFolder
Dim oMeetingoApptItem As Outlook.MeetingItem
Dim oObject As Object
Dim iUserReply As VbMsgBoxResult
Dim sErrorMessage As String
MsgBox (VBA.Time)
On Error Resume Next
' check if Outlook is running
Set oApp = GetObject("Outlook.Application")
If Err <> 0 Then
'if not running, start it
Set oApp = CreateObject("Outlook.Application")
End If
On Error GoTo Err_Handler
Set oNameSpace = oApp.GetNamespace("MAPI")
Set oFolder = oNameSpace.GetDefaultFolder(olFolderCalendar)
For Each oObject In oFolder.Items
If oObject.Class = olAppointment Then
Set oApptItem = oObject
If ReminderObject.Caption = oApptItem.Subject Then
If oApptItem.Organizer = Outlook.Session.CurrentUser Then
iUserReply = MsgBox("Meeting found:-" & vbCrLf & vbCrLf _
& Space(4) & "Date/time (duration): " & Format(oApptItem.Start, "dd/mm/yyyy hh:nn") _
& " (" & oApptItem.Duration & "mins)" & Space(10) & vbCrLf _
& Space(4) & "Subject: " & oApptItem.Subject & Space(10) & vbCrLf _
& Space(4) & "Location: " & oApptItem.Location & Space(10) & vbCrLf & vbCrLf _
& "Do you want to continue with the meeting?", vbYesNo + vbQuestion + vbDefaultButton1, "Meeting confirmation")
If iUserReply = vbNo Then
oApptItem.MeetingStatus = olMeetingCanceled
oApptItem.Save
oApptItem.Send
oApptItem.Delete
End If
End If
End If
End If
Next oObject
Set oApp = Nothing
Set oNameSpace = Nothing
Set oApptItem = Nothing
Set oFolder = Nothing
Set oObject = Nothing
Exit Sub
Err_Handler:
sErrorMessage = Err.Number & " " & Err.Description
End Sub
I found this here
Public Function DeleteAppointments(ByVal subjectStr As String)
Dim oOL As New Outlook.Application
Dim oNS As Outlook.NameSpace
Dim oAppointments As Object
Dim oAppointmentItem As Outlook.AppointmentItem
Dim iReply As VbMsgBoxResult
Set oNS = oOL.GetNamespace("MAPI")
Set oAppointments = oNS.GetDefaultFolder(olFolderCalendar)
Count = oAppointments.Items.Count 'for test purposes
For Each oAppointmentItem In oAppointments.Items
If InStr(oAppointmentItem.Subject, subjectStr) > 0 Then
iReply = msgbox("Appointment found:" & vbCrLf & vbCrLf _
& Space(4) & "Date/time: " & Format(oAppointmentItem.Start, "dd/mm/yyyy hh:nn") & vbCrLf _
& Space(4) & "Subject: " & oAppointmentItem.Subject & Space(10) & vbCrLf & vbCrLf _
& "Delete this appointment?", vbYesNo + vbQuestion + vbDefaultButton2, "Delete Appointment?")
If iReply = vbYes Then oAppointmentItem.Delete
oAppointmentItem.Delete
End If
Next
Set oAppointmentItem = Nothing
Set oAppointments = Nothing
Set oNS = Nothing
Set oOL = Nothing
End Function