In my company we have a number of different email addresses which go to "Shared Inbox" accounts that are managed by a few people.
We want to keep track of how many emails are in each Inbox.
A user might look after several different shared inboxes, and no one user has access to the same set of inboxes.
The VBA code I have loops through all of the logged-in user's shared inboxes and counts how many emails are in each inbox folder which isn't their own "personal" inbox and logs that data to a table using a separate procedure:
Sub WorkPosition()
Dim ThisUser As String
Dim Mailbox As Object
Dim MailBoxName As String
Dim oStore As Outlook.Store
Dim olFolder As Outlook.Folder
ThisUser = UCase(Environ("UserName"))
For x = Application.Session.Stores.Count To 1 Step -1
Set Mailbox = Nothing
On Error Resume Next
Set Mailbox = Application.Session.Stores(x)
On Error GoTo 0
If Mailbox Is Nothing Then GoTo SkipMailbox
MailBoxName = Mailbox
If InStr(UCase(Mailbox), ThisUser) = 0 Then
Set olFolder = Mailbox.GetDefaultFolder(olFolderInbox)
Set objItems = olFolder.Items
MailCount = objItems.Count
LogFolder MailBoxName, MailCount, ThisUser 'Run the "Logfolder" sub which logs the data
End If
SkipMailbox:
Next x
End Sub
This all works, except users don't name their shared inbox accounts very well. Several users have the same name for their shared inbox, but they're associated to different email addresses.
For example:
Charles might have info#mycompany.com as an Outlook store named "Customer Questions"
David might have queries#mycompany.com as an Outlook store also named "Customer Questions"
When Charles and David log their mail counts using my VBA code, they are both being logged with the MailBoxName as "Customer Questions".
I've come to the conclusion that I don't want to log the mailbox name. I want to log the email address instead, which they can't change and will be unique to that inbox.
I am able to do this if there is an email in the inbox, since I can just take the "to" address from the first mail item in the folder, but not if there are 0 emails in the folder.
How can I extract the incoming email address(es) which are associated to a user's Outlook store into a VBA string, so that I can pass it to my "LogFolder" procedure?
Outlook Object Model does not expose anything like that.
If using Redemption is an option (I am its author), it exposes RDOExchangeMailbox.Owner property (returns RDOAddressEntry object):
skPrimaryExchangeMailbox = 3
skDelegateExchangeMailbox = 4
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
for each Store in Session.Stores
If (Store.StoreKind = skPrimaryExchangeMailbox) or (Store.StoreKind = skDelegateExchangeMailbox)Then
Debug.Print Store.Name & " : " & Store.Owner.SMTPAddress
End If
next
Related
I need to change the subject line of 1000s of emails in my drafts.
Here is the code I'm using but it's not changing the subject line. Could someone please let me know what I'm missing.
Sub Drafts_Send()
Dim objDrafts As Outlook.Items
Dim objDraft As Object
Dim strPrompt As String
Dim nResponse As Integer
Dim i As Long
Set objDrafts = Outlook.Application.Session.GetDefaultFolder(olFolderDrafts).Items
For i = objDrafts.Count To 1 Step -1
If objDrafts.Item(i).Subject = "Please Thank You" Then
objDrafts.Item(i).Subject = "Please & Thank You"
objDrafts.Item(i).Save
End If
Next i
Set objDrafts = Nothing
End Sub
My guess is that the default Drafts folder is not the folder containing the drafts you wish to update.
Run this macro:
Sub DsplStoreContainingfDefaultDrafts()
Dim NS As Outlook.NameSpace
Dim DefaultInboxFldr As MAPIFolder
Set NS = CreateObject("Outlook.Application").GetNamespace("MAPI")
Set DefaultInboxFldr = NS.GetDefaultFolder(olFolderDrafts)
Debug.Print "Default Drafts folder in """ & DefaultInboxFldr.Parent.Name & """"
End Sub
On my system it outputs:
Default Drafts folder in "Outlook Data File"
“Outlook Data File” is the default store that came with the installation but it is only used for information not associated with an email account. Outlook has created a separate store for each of my email accounts with names like JohnSmith#AcmeIsp.com and JohnSmith#gmail.com. Each of those stores has its own Drafts folder and drafts are in the Drafts folder of the account from which I will send the email.
Go to the folder containing the drafts you wish to update. Is it within the store identified by my macro? If not continue reading.
The complication is that on my system, Drafts is a top level folder in the store for my regular ISP account but a second level folder in folder for my gmail account.
You will need to replace:
Set objDrafts = Outlook.Application.Session.GetDefaultFolder(olFolderDrafts).Items
Outlook.Application. is redundant since you are running this within Outlook.
If you store is like my regular ISP account, you will need something like:
Set objDrafts = Session.Folders("JohnSmith#AcmeIsp.com").Folders("Drafts").Items
If you store is like my gmail account, you will need something like:
Set objDrafts = Session.Folders("JohnSmith#gmail.com").Folders("[Gmail]").Folders("Drafts").Items
There are some tricks you can try.
.DoEvents, .GetInspector and as a last resort .Display.
Sub Drafts_Send()
Dim objDrafts As Items
Dim objDraft As Object
Dim i As Long
Set objDrafts = Session.GetDefaultFolder(olFolderDrafts).Items
For i = objDrafts.Count To 1 Step -1
If objDrafts.Item(i).Class = olMail Then
Set objDraft = objDrafts.Item(i)
With objDraft
If .Subject = "Please Thank You" Then
' this has some .Display behaviour, without displaying
.GetInspector
'.Display ' as a last resort
objDrafts.Item(i).Subject = "Please & Thank You"
DoEvents
' if in Draft folder reading pane should be off
.Save
End If
End With
Set objDraft = Nothing
End If
Next
Set objDrafts = Nothing
End Sub
I'd like to list all of my emails in a specific folder by using Outlook MAPI. I have tried the following code,
but it only shows 400 out of the 20,000 emails in the folder. I would greatly appreciate it if anyone could please show me how to list all of the emails.
Sub EmailListinFolder()
Dim mn As Long
Dim Message As String
Dim item As Object
Dim NS As Object
Dim Folder As Object
'Get the MAPI Name Space
Set NS = CreateObject("Outlook.Application").GetNamespace("MAPI")
'Allow the user to select a folder in Outlook
Set Folder = NS.PickFolder
For Each item In Folder.Items
If item.Class = olMail Then
Message = item.Subject & "|" & item.CreationTime
If Len(Message) Then
mn = mn + 1
End If
End If
Next item
MsgBox (mn)
End Sub
Is that an online profile? Most likely you end up opening too many items (for each loop keeps all items referenced until the loop exits). Use Table object instead - see example at https://msdn.microsoft.com/VBA/Outlook-VBA/articles/folder-gettable-method-outlook.
I am sending an email using the QTP outlook object model.
Here is the piece of code.
'Create an object of type Outlook
Set objOutlook = CreateObject("Outlook.Application")
Set myMail = objOutlook.CreateItem(0)
'Set the email properties
myMail.To = "some_mail_id#gmail.com"
myMail.CC = "some_mail_id_2#gmail.com; some_other_mail#yahoo.com" 'Sending mails to multiple ids
myMail.BCC = "" 'If BCC is not required, then this line can be omitted
myMail.Subject = "Sending mail from MS Outlook using QTP"
myMail.Body= "Test Mail Contents"
myMail.Attachments.Add("D:\Attachment.txt") 'Path of the file to be attached
'Send the mail
myMail.Send
Now I needed to retrieve the sender email address & store it in an environment variable. myMail.Sender or myMail.sendermailaddres both of them are not working me.
The following code will give you the first email address the user you're connected to Outlook has access to:
objOutlook.Session.Accounts.Item(0)
I use a loop to find the account I want to send from like this:
iAccount = 0
For iLoop = 1 To oOutlook.Session.Accounts.Count
If UCase(Trim(oOutlook.Session.Accounts.Item(iLoop))) = UCase(Trim(EmailData("SendFrom"))) Then
iAccount = iLoop
Exit For
End If
Next
where EmailData is a Dictionary object containing the items I'm using for the mail item. When creating the mail item I use Set oMailItem.SendUsingAccount = oOutlook.Session.Accounts.Item(iAccount) to specify the account it should be sent from.
I have a large number of forwarding email addresses which are all set to forward to the same email account. I find this is useful because if a business is hacked and my email address is stolen then I only have the change the email address for that business. For example, "amazon#mydomain.com", "ebay#mydomain.com" and "facebook#mydomain.com" would all be forwarded to "mailbox#mydomain.com".
When I want to send an email to the business, I have to go into Outlook and change the account set up to have the forwarding email address as the email address. I find this a nuisance. I know I can change who the email is from when I write it, but then the recipient sees "J Smith on behalf of newaddress#mydomain.com". I would rather it just showed the address I am using in the from field, as it does if I go into the account set up and change the email address there.
It would be nice to have a macro set up which asked me which email address I wanted to use and then sent the email for me. I have looked up how to change email account details in VBA, but it looks as if the details are all read-only. Is there a way to change my "from" email address cleanly? Or even setting up a new email account in VBA and deleting it immediately after sending it?
Try creating a userform with a combobox and a button on it. Load all your available accounts into the combobox to be able to select from it:
Private Sub UserForm_Initialize()
Dim acc As Account
For Each acc In ThisOutlookSession.Session.Accounts
Me.ComboBox1.AddItem acc.UserName
Next acc
End Sub
Then add some code to the button that selects the proper account:
Dim objApp As Outlook.Application
Dim objMail As Outlook.MailItem
Set objApp = ThisOutlookSession.Application
Set objMail = objApp.CreateItem(olMailItem)
With objMail
.To = "lala#lala.com"
.CC = ""
.BCC = ""
.Subject = "Test"
.Body = "Test"
Dim i As Integer
For i = 1 To ThisOutlookSession.Session.Accounts.Count Step 1
If ThisOutlookSession.Session.Accounts.Item(i).UserName = Me.ComboBox1.Value Then
.SendUsingAccount = ThisOutlookSession.Session.Accounts.Item(i)
End If
Next i
.Display
End With
Maybe there is an event that is called when you are creating a new email, otherwise you have to add a button or something to bring the form up.
I had this exact same problem and ended up being able to solve it by installing Outlook Redemption and using the following script...
' Redemption code below. Must install Redemption to work.
' http://www.dimastr.com/redemption/faq.htm#14
Dim sItem, Tag
Set sItem = CreateObject("Redemption.SafeMailItem")
sItem.Item = oMailItem
Tag = sItem.GetIDsFromNames("{00020386-0000-0000-C000-000000000046}", "From")
Tag = Tag Or &H1E 'the type is PT_STRING8
sItem.Fields(Tag) = GetHashedReply(oMailItem)
Tag = sItem.GetIDsFromNames("{00020386-0000-0000-C000-000000000046}", "Sender")
Tag = Tag Or &H1E 'the type is PT_STRING8
sItem.Fields(Tag) = GetHashedReply(oMailItem)
sItem.Subject = sItem.Subject 'to trick Outlook into thinking that something has changed
sItem.Save
...where oMailItem is a normal Outlook MailItem that you can get with CreateItem() or get passed to you in the ItemSend() parameters.
I am connected to my company's MS Exchange. From my own Outlook profile, I access a generic mailbox. All incoming messages will be tagged to a category and then moved to a folder (Mailbox - Generic > Resolved). How can I generate a total count of each category in this folder?
Mailbox - Javen
Inbox
Sent Items
...
Mailbox - Generic
Inbox
Sent Items
Resolved
...
Each category will be named to a name...
Example: Red = John, Yellow = Peter, Purple = Peggy
This should get you going. It filters the folder a specified category. You can edit it to do loop of the Outlook Categories collection to get the counts. Or you could change it to be a function that returns the count...passing the Category name as a parameter.
Private Sub CountbyCategory()
Dim fldr As Outlook.Folder = Nothing
Dim itms As Outlook.Items = Nothing
Dim filteredItms As Outlook.Items = Nothing
'Do this for each category...
Dim typeFilter As String = "[Category] = " & Chr(39) & "INSERT CATEGORY NAME HERE" & Chr(39)
'This assumes default inbox, you'll need to select you folder...maybe use PickFolder?
'fldr = Application.Session.PickFolder()
fldr = Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox)
itms = fldr.Items
filteredItms = itms.Restrict(typeFilter)
Dim iCount As Integer = filteredItms.Count
'Repeat for each category
End Sub
You can learn more about working with Outlook items here:
Working with Outlook mail items: how to create, delete, access & enumerate
Working with Outlook Accounts, Stores, Folders and Items