Every weekday morning I would like to see the content of a specific subfolder in my personal profile right after starting Outlook.
I have an Outlook macro that when fired manually the folder is activated, content (all mails) is shown.
I copied the macro to ThisOutlookSession and restarted Outlook.
The macro starts and the folder is activated.
Nothing is shown (it is not empty for sure).
Nothing is shown in any folders having run the macro this way. Content of any folder is shown for a second when I switch from one folder to another. The content is there but won't show permanently.
Private Sub Application_Startup()
Activate_SubFolder
End Sub
Sub Activate_SubFolder()
Dim myfolder As Folder
Set myfolder = Session.Folders("myname#mycompany.com").Folders("Subfolder1").Folders("Subfolder2")
Set ActiveExplorer.CurrentFolder = myfolder
Set myfolder = Nothing
End Sub
Related
I am wondering if there is a way using VBA/Outlook to look through a number of personal folders (all added to Outlook and called personal folders) and copy the contents of the inboxes (the folder will always be called Inbox) to a single PST/inbox/folder. The number of personal folders would vary depending upon the email search completed (GVault).
Personal Folder - Inbox,
Personal Folder - Inbox,
Personal Folder - inbox,
Final Personal Folder - Inbox
The aim is to give the user one PST with all the emails in.
This is part of an attempt to streamline our email archive search process which creates a folder + PST for each email address found in the search (good old Google....) It is obviously a nightmare combining them all into one PST which we can then give to a user. It is possible (using Outlook) to manually combine each PST with a master PST but this is far from automating the process + there could be a large amount of separate email addresses.
The original problem was taking all the PSTs and getting them into Outlook, this has been solved but the format is as described above (seperate PSTs all added).
Any help would be greatly appreciated as I cant get past this final hurdle, there are scripts that do manipulate PSTs in Outlook, they just dont do this.
Thanks
Dan
Below code will loop your outlook attached PST files copying files in a folder called 'Inbox' (any case) to the PST callled 'Master PST'
Included very trivial error checking <-- free to improve
'include reference to Microsoft Outlook XX.0 Object Library
Public Sub copyInbox()
Dim ns As Outlook.Namespace
On Error GoTo hell
Dim sourceFolder As Outlook.MAPIFolder
Dim copyToFolder As Outlook.MAPIFolder
Dim subfolder As Outlook.MAPIFolder
Dim objItem As Outlook.MailItem
Dim objItemCopy As Outlook.MailItem
Set ns = Application.GetNamespace("MAPI")
Set copyToFolder = ns.Folders("MASTER PST").Folders("Inbox")
'Personal folder called 'MASTER PST' with inbox subfolder must exist
For Each sourceFolder In ns.Folders
For Each subfolder In sourceFolder.Folders
If Trim(UCase(subfolder.Name)) = "INBOX" Then
For Each objItem In subfolder.Items
'modified below to use copy as per MSDN
'https://msdn.microsoft.com/en-us/vba/outlook-vba/articles/mailitem-copy-method-outlook
Set objItemCopy = objItem.Copy
objItemCopy.Move copyToFolder
Next
End If
'copy items in subfolders in inbox can be added here
Next
Next
Exit Sub:
hell:
MsgBox Err.Description, vbExclamation, Err.Source
End Sub
Summary: We need to go to a website, download an Excel file, and copy&paste the data into an Excel template file all automatically.
Current Problem: My current VBA code opens IE, does the data scrape and downloads the file automatically without any problems. However, ONLY in Break Mode that it opens the downloaded workbook and copy&paste the data into the template.
What Didn't Work: I tried multiple ideas like Sleep, Application.Wait, and DoEvents. Unfortunately, it keeps getting stuck on the same line. The code does not recognize a Workbook has been open and can't find the data to copy&paste. Only after I enter into the Break Mode that the file will eventually open.
Observation: Security Settings on Excel removed so I do not receive a warning message when opening a file.
This snippet is part of a loop which will make the same procedure you will find below for 5 different files. After it downloads each file, it copies&paste the data into my template.
Any idea & solution is totally welcomed!
Please find my code below:
sub test()
'-----------------------------------
'Code to do the Data Scrape in here. It works fine.
'-----------------------------------
Dim o As IUIAutomation
Dim e As IUIAutomationElement
Dim h As Long
Dim wkbook As Workbook
Dim Cwkbook As String, ThisWkbook As String
'Code to Automate IE Download
Set o = New CUIAutomation
h = ieApp.hWnd
h = FindWindowEx(h, 0, "Frame Notification Bar", vbNullString)
If h = 0 Then Exit Sub
Set e = o.ElementFromHandle(ByVal h)
Dim iCnd As IUIAutomationCondition
Set iCnd = o.CreatePropertyCondition(UIA_NamePropertyId, "Open")
Dim Button As IUIAutomationElement
Set Button = e.FindFirst(TreeScope_Subtree, iCnd)
Dim InvokePattern As IUIAutomationInvokePattern
Set InvokePattern = Button.GetCurrentPattern(UIA_InvokePatternId)
InvokePattern.Invoke
'Download Completed and File Should be opened.
DoEvents
Application.Wait Now + #12:00:10 AM#
'Even after using DoEvents & Application.Wait, the code won't open the workbook until it goes into Break Mode.
'Code to find Downloaded Workbook which will come named either as X or Y.
ThisWkbook = ThisWorkbook.Name
For Each wkbook In Application.Workbooks
If Left(wkbook.Name, 9) = "XXXXXXXXX" Or Left(wkbook.Name, 9) = "YYYYYYYYY" Then
Cwkbook = wkbook.Name
'-----------------------------------
'Code to Copy&Paste data in here. It works fine.
'-----------------------------------
End If
Next
End Sub
You will need the UIAutomationClient reference to make the code work. If you get an error when including it (like I did), add "Microsoft Visual Basic for Applications Extensibility" reference and run the code below:
Sub MyUIAutomation()
'----------------------------------------------------
'Add UIAutomation as VBA Reference
'----------------------------------------------------
Dim VBProj As VBIDE.VBProject
Set VBProj = ThisWorkbook.VBProject
VBProj.References.AddFromFile Environ("systemroot") & "/system32\uiautomationcore.dll"
Set VBProj = Nothing
End Sub
UPDATE 8.28.17: I tried a work around to copy/paste the data only when a Workbook is opened. The idea would be to finish my main "data extract" code. After the code is finished the Workbooks should open as it was behaving before, and the second code would trigger, copying/pasting the data.->
Run VBA macro whenever any workbook is opened
Outcome: It is still not working. It would only open the last workbook of the whole loop and copy&paste the data of it. The other 4 previous files wouldn't open.
UPDATE 8.31.17 Another work around failed. I tried to create an User Form, where the user would have to click on 5 different buttons. The idea is to check if my problem was the looping. Each button would extract the file and after that my Copy&Paste Macro would trigger.
Outcome: It did not work as well. I figure that while I have my "User Form" open excel recognizes that a macro is running. If I run it under Break Mode it will still open the file and copy the data.
I believe it would be important to other people know that I found a solution to my own problem.
The main problem was that my original code was structured this way:
'Open IE -> Search for a specific criteria -> Download File -> Open File -> Copy&Paste File.
It would repeat the above procedure 5 times for each different file I need.
The code would run perfectly under break mode. However, when you actually ran it, it wouldn't bring over the data from the downloaded file.
FIX: It is a work around. I separated my code into pieces. The first piece is going to search, download, and open the file I want. The second piece will only trigger when a file with a specific name is opened. It will then perform all the remaining steps I need.
I used the Workbook_Open event to do such thing:
Private Sub Workbook_Open()
The third and last piece, is a form created using shapes like circles, squares, and text box. It actually looks way nicer than an userform. Each circle performs like a button and will trigger the download of a specific file when clicked.
Now the code is structured like:
'1. Form using Shapes, each circle activates a specific script
'2. 5 Scripts -> Open IE, Search for a specific criteria, Download File, Open File
'3. 1 Script. Only Triggers when Excel Workbooks are opened. It will then only copy the data over if it meets certain criteria (such as filename).
I use Task Scheduler to manage a VBScript which starts a vba sub procedure in Workbook X. This procedure opens two other Workbooks and move data to Workbook X and closes them again. The procedure outcome is an updated Workbook X which I need to save. The VBA procedure works fine and is triggered by the VBScript as expected. However, the part of the VBScript which should save the file doesn't work. The VBScript is based on code I have found on Stackoverflow.com and other sites.
When I open the file X I tried to save with the VBScript, It asks me to decide whether I want to save the file. If I do, I can see the data the above procedure has created has worked.
I can see in the Task Manager that the Excel instance I have created with the VBScript is never closed although I tried to do it in the VBScript. I have also tried the Save method, but with no luck. I have tried different parameters for the methods with no luck. I have search on this site and other sites for how the issue could be solved. However, they suggest Save and SaveAs methods and I tried them with the different suggested parameter configurations without success.
I have now found the root cause but not the solution. It has nothing to do with the script itself. In the open workbook event.
I have code which activate a userform (StartUpForm.Show). In the workbook before close and open events I call procedure RemoveFilter which remove a filter on a set of filtered data. If I mark UserForm.Show and the RemoveFilter in the before close workbook event as notation it works. It is not enough to avoid call StartUpForm.Show. StartUpForm.Show needs to be marked as notation or deleted. How can that be? And is there a workaround?
This doesn't work:
Private Sub Workbook_Open()
Dim batRun As Boolean
RemoveFilter
ResolveStartUp (batRun)
If Not batRun Then
StartUpForm.Show vbModal
End If
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
RemoveFilter
End Sub
This works:
Private Sub Workbook_Open()
Dim batRun As Boolean
RemoveFilter
ResolveStartUp (batRun)
If Not batRun Then
' StartUpForm.Show vbModal
End If
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
' RemoveFilter
End Sub
VBScript:
On Error Resume Next
ImportAccesFilesToHolidaysAndWorkshops
Sub ImportAccesFilesToHolidaysAndWorkshops()
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
xlApp.DisplayAlerts = False
Set xlBook = xlApp.Workbooks.Open ("Z:\ResourceManagement\Holiday and workshops input.xlsm", 0, False,,,,,,,,True)
xlApp.Run "ImportResourcesAndProjects"
xlApp.ActiveWorkbook.Close
xlBook.SaveAs "Z:\ResourceManagement\Holiday and workshops input.xlsm",,,,,,xlExclusive, xlLocalSessionChanges
xlBook.Close
Set xlBook = Nothing
xlApp.Quit
Set xlApp = Nothing
WScript.Echo "Finished."
WScript.Quit
End Sub
Try saving to your C: drive. If that works you are probably running into a scheduled task problem. If the task runs whether or not a user is logged in or it is set to use highest privileges, you aren't running under the security context you think you are. In either of those cases job scheduler will use S4U authentication which will prevent you from accessing network resources. I'm guessing that Z: drive is a mapped network drive. Mapped drives belong to the user who mapped the drive so it won't be available unless you are running as the user that mapped the drive and that user is logged in.
If you use "run with highest privileges", you are actually running under the built in Administrator account. That is a separate account and it won't have your drive mappings.
Task Security Context
Some Programs Cannot Access Network Locations When UAC Is Enabled
windows 7 scheduled tasks run with highest privileges
So firstly, I'm very new to VBA and due to the number of emails I get that follow a certain template, I'm trying to automate the data collation to save myself from all the cutting and pasting that is currently required. I've looked at some previous questions but due to my very little knowledge, the answers aren't specific enough for me to understand.
Each one of these emails is from a particular email address and has a standard format as shown below:
"
dd/mm/yyyy hr.min.sec
xxx xxxxxxx xxxxxxxxxxxxxxxxx xxxx xxxxx "
I would like to export or copy this information to an excel 2003 worksheet so that each separate piece of information is in a new column of a single row, where each email is a new row.
I would like the macro to be able to search through my received emails in a particular folder (as I've already set up some rules in outlook relating to this email address), copy the information from each email matching the template and paste it into a single excel worksheet. Then each time I get a new email, the information will be added to the bottom of the table thats been created.
Hopefully that all makes sense, please let me know if you need anymore information.
Thanks in advance.
I did something exactly like this recently, except that I had it entered into an access database instead of an excel sheet, but the idea is the same. For some reason, I was having trouble getting it to run with rules, but I anyways found that I could control it better from a manually run macro. So use a rule to put everything into a folder, and make an AlreadyProcessed subfolder under that. Here is some code to start from:
Sub process()
Dim i As Integer, folder As Object, item As Object
With Application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Folders("YourFolderName")
For Each item In .Items
processMail item
item.Move .Folders("AlreadyProcessed")
Next
End With
End Sub
Sub processMail(item As Outlook.MailItem)
Dim bitsOfInformation() As String
bitsOfInformation = Split(item.Body, " ")
'Use this information to make an Excel file
End Sub
Making Excel files from VBA are very easy - just read up on opening excel and making new documents from other Office program VBAs - you're looking for Excel.Application. You can even record a macro in Excel, filling the information manually, and basically copy the code into Outlook and replace the hard-coded information with variables. But if you're going to be running this on thousands of e-mails, be warned that recorded macros (that use selection objects) are inefficient.
Start with the following code:
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Set Items = GetItems(GetNS(GetOutlookApp), olFolderInbox)
End Sub
Private Sub Items_ItemAdd(ByVal item As Object)
On Error GoTo ErrorHandler
Dim msg As Outlook.MailItem
If TypeName(item) = "MailItem" Then
Set msg = item
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
Function GetItems(olNS As Outlook.NameSpace, folder As OlDefaultFolders) As Outlook.Items
Set GetItems = olNS.GetDefaultFolder(folder).Items
End Function
Function GetNS(ByRef app As Outlook.Application) As Outlook.NameSpace
Set GetNS = app.GetNamespace("MAPI")
End Function
Function GetOutlookApp() As Outlook.Application
Set GetOutlookApp = Outlook.Application
End Function
This sets an event listener on your default Inbox. Whenever an email message is received, the code inside the If TypeName statement will be executed. Now it's simply a matter of what code you want to run.
You can check the sender using the .SenderName or .SenderEmailAddress properties to make sure it's the right sender.
If you provide more specific information, I can amend the code.
I use Outlook (MS Exchange) and have an individual as well as two group inboxes (I'm working logged in with the individual profile through which I also have access to the group inboxes).
When I send an email, I chose either my individual or one of the two group email addresses in the From field. When the email is sent, I want a copy saved in the inbox of myIndividualMailbox, groupAMailbox, or groupBMailbox depending on which From email address I used.
Example: If I send an email From groupA#myCompany.com, I want a copy of the email saved in the inbox of the groupAMailbox (and not in my individual inbox).
I have understood that this is not possible by setting up a rule in Outlook but that it could be done with a VBA macro. I don't now how to write the VBA macro and don't know if this is a just a short script or more complicated. In fact I have never written a macro in Outlook so I don't even know how to begin. Can anyone show how to do this?
I started looking for a solution with this question: Outlook send-rule that filter on the 'From' field
I made this for you as far as I can tell, it works. You should put this in the Microsoft Outlook Objects - ThisOutlookSession Module.
Note that the myolApp_ItemSend event will never trigger unless you run enableEvents first. And you will need to make sure it is enabled every time you close an re-open Outlook. This will take some customization, but it should give you the general idea.
Option Explicit
Public WithEvents myolApp As Outlook.Application
Sub enableEvents()
Set myolApp = Outlook.Application
End Sub
Private Sub myolApp_ItemSend(ByVal item As Object, Cancel As Boolean)
Dim items As MailItem
Dim copyFolder As Outlook.Folder
Dim sentWith As String
'Identify sender address
If item.Sender Is Nothing Then
sentWith = item.SendUsingAccount.SmtpAddress
Else
sentWith = item.Sender.Address
End If
'Determin copy folder based on sendAddress
Select Case sentWith
Case "groupA#myCompany.com"
'get groupAMailbox's inbox
Set copyFolder = Application.GetNamespace("MAPI").folders("groupAMailbox").folders("Inbox")
Case "myE-mailAddress"
'get My inbox
Set copyFolder = Application.GetNamespace("MAPI").folders("myE-mailAddress").folders("Inbox")
End Select
'copy the Item
Dim copy As Object
Set copy = item.copy
'move copy to folder
copy.Move copyFolder
End Sub
EDIT: It looks like they've actually built the event functionality into the Application object for Outlook directly now, but it from testing you still have to do what I outlined above.
Outlook stores all sent items in default sent items folders. however you can apply a patch to save sent items in its own folder.
http://support.microsoft.com/kb/2181579