Fair warning - the code is not my own, so any ideas will be welcomed on how to change it.
Public Sub ChangeMeeting()
Dim oRequest As MeetingItem
Dim oAppt As AppointmentItem
Set oRequest = Application.ActiveExplorer.Selection.Item(1)
If oRequest.MessageClass = "IPM.Schedule.Meeting.Request" Then
Set oAppt = oRequest.GetAssociatedAppointment(True)
' use this to autoaccept
Dim oResponse
Set oResponse = oAppt.Respond(olMeetingAccepted, True)
oResponse.Send
' set fields on the appt.
With oAppt
' .Categories = "Slipstick"
.BusyStatus = olFree
.Save ' use .Display if you want to see the appt. and set the reminder yourself
End With
End If
'delete the request from the inbox
oRequest.Delete
End Sub
This one's interesting. On my computer, it works just fine. However, on the other one it can be clicked on and clicked on, and nothing will happen. No errors, no popups, no nothing. So, I know that the code works, but is there any reason (rights?) that the exact same code would work on one and not the other?
First of all, make sure that VBA macros are allowed to run. Is the VBA macro run in Outlook at all? Did you try to debug it?
Do you get any errors in the code on another machines?
I'd suggest starting from breaking the chain of property and method calls and declaring them on separate lines of code. Thus, you will be able to find what property or method fails.
The code is based on the selected item in the Explorer:
Application.ActiveExplorer.Selection.Item(1)
Is the selection not empty all the time?
If oRequest.MessageClass = "IPM.Schedule.Meeting.Request"
Does the selection contains the first item with the specified message class?
In general, VBA macros are not designed for distributing on multiple PCs. If you need to get a solution working on multiple machines you need to develop an add-in instead. See Walkthrough: Creating Your First VSTO Add-In for Outlook .
Finally, you may find the Getting Started with VBA in Outlook 2010 article helpful.
Related
I was automating an Outlook email from excel today when I noticed I forgot a line but somehow it still worked and I didn't get a compile error. Is there such as thing as a default library object?
Sub sendmail()
Dim olmsg As Outlook.MailItem
'This works
Set olmsg = Outlook.CreateItem(olMailItem)
'What it should be
Set olmsg = Outlook.Application.CreateItem
End Sub
When working in Outlook, it automatically recognizes Outlook types.
Similar to how Excel will recognize keywords such as ActiveSheet and ActiveCell without first expressing Excel.Application.
It is good practice to use the longhand expression, incase you ever need to port a similar code to Excel for working in Outlook, and because VBA does not handle overflows well.
I am trying to automatically update certain information (such as names, dates and numbers) across 3 different Word documents by putting the data into a spreadsheet and linking to the respective cells from Word. The spreadsheet has some Macros in it which auto-update parts of the spreadsheet internally.
Everything is working fine, except for updating the links in the Word documents.
When trying to update a link in Word by right-clicking on it and selecting the "update link" option it brings up the Macro warning dialog for the spreadsheet, asking whether I want to activate Macros or not. It doesn't do this just once but constantly during the 20s or so the update process takes (which seems unusually long to me). So updating the link works, but only if you're willing to click the "activate Macros" button of a few dozen times.
I tried to automate updating all fields in a document from Word with VBA, but that has the same problem, it also brings up the Macros dialog constantly for half a minute.
Here's my code for that:
Sub UpdateFields()
ActiveDocument.Fields.Update
End Sub
I also tried to update the Word documents directly from the spreadsheet, but that does not work either, because when Excel tries to open a Word document via VBA the program stops executing and trows this error:
"Excel is waiting for another application to complete an OLE action."
Clicking ok and waiting does not help because the error message reappears after a few seconds, and the only way to stop it is to manually kill the Excel process.
Here's my Excel Macro code:
Sub LoopThroughFiles()
Path = Application.ActiveWorkbook.Path
Dim WordFile As String
WordFile = Dir(Path & "\*.doc")
Do While Len(WordFile) > 0
Run Update(Path & "\" & WordFile)
WordFile = Dir
Loop
End Sub
Function Update(Filepath As String)
Dim WordDoc As Word.Document
Set WordApplication = CreateObject("Word.Application")
Set WordDoc = WordApplication.Documents.Open(Filepath) 'This produces the error
ActiveDocument.Fields.Update
End Function
Note that the only files in the folder are the 3 documents and the spreadsheet, and the program does find the files without any problems.
I have searched for solutions online but I did not really find anything, which I found odd, since it seems like a pretty common thing that someone would do with VBA.
Then again, I have very little experience with VBA, so I might be completely missing the point and there is a super simple solution I am just not aware of.
I think I see the error, which is a silent failure, becuase the document contains links, there is an open dialog waiting for you to say "yes" or "no" to update the links.
We can suppress this dialog by disabling the automatic link updates (WordApplication.Options.UpdateLinksAtOpen = False).
Function Update(Filepath As String)
Dim WordApplication As Word.Application
Dim WordDoc As Word.Document
Dim updateLinks As Boolean
Set WordApplication = CreateObject("Word.Application")
updateLinks = WordApplication.Options.UpdateLinksAtOpen 'capture the original value
WordApplication.Options.UpdateLinksAtOpen = False 'temporarily disable
Set WordDoc = WordApplication.Documents.Open(Filepath)
WordDoc.Fields.Update
'MsgBox "Links updated in " & WordDoc.Name
'## Save and Close the Document
WordDoc.Save
WordDoc.Close
'## reset the previous value and Quit the Word Application
WordApplication.Options.UpdateLinksAtOpen = updateLinks '
WordApplication.Quit
End Function
Also, remember to Save and Close the document, and Quit the word application inside the function.
I made this other modification:
In your function, ActiveDocument is not an object in Excel, so you would need to qualify it, otherwise that line will also throw an error. Rather than refer to WordApplication.ActiveDocument, I just simply refer to the WordDoc which you have already assigned.
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 am trying access window of MS Word from Excel. I found methods to access a new Word document or a specific one, like the one at
Copy Text from Range in Excel into Word Document,
But in my case I do not know the name of the document, it should be the last active one. I was hoping to use something like
Word.ActiveDocument
but no success. I also tried to simulat Alt+Tab keystroke to activate the window with
Application.SendKeys("%{TAB}")
but it does not work too. Any hint?
I am trying to create a macro that will just copy charts and some text around to Word and do some formating of the text along with it. So basically I can use any approach to this task.
Thanks a lot.
You can access an open instance of Word by using late binding (http://support.microsoft.com/kb/245115) and GetObject. If you have multiple instances of Word open you are not guaranteed of getting any one of them in particular though.
Getting an instance of Word will allow you to access the ActiveDocument or the Application's current Selection. I'd still suggest doing some error checking to make sure you've got what you want.
Sub GetWordDocument()
Dim wdApp As Object
'Turn off error handling since if the Application is not found we'll get an error
'Use Late Binding and the GetObject method to find any open instances of Word
On Error Resume Next
Set wdApp = GetObject(, "Word.Application")
On Error GoTo 0
'Check to see if we found an instance. If not you can create one if you desire
If wdApp Is Nothing Then
MsgBox "No instances of Word found"
Exit Sub
End If
'Check if there are documents in the found instance of Word
If wdApp.Documents.Count > 0 Then
wdApp.Selection.TypeText "Cool, we got it" & vbCr
'You can now access any of the active document properties too
wdApp.ActiveDocument.Range.InsertAfter "We did indeed"
End If
'Clean up the Object when Finished
Set wdApp = Nothing
End Sub
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