I am looking to create an add-in for outlook that works in Outlook 2010 and Office 365.
What I want it to do is Save an email in MSG format to a folder on our network, that I specify, and then move that email to an archive folder within outlook.
I don't know a lot about programming (Just the basics). I am hoping someone can point me in the right direction on how to begin this project and what resources I can use to do this.
Any help is much appreciated.
Thanks
See Walkthrough: Creating Your First VSTO Add-In for Outlook for getting started.
What I want it to do is Save an email in MSG format to a folder on our network, that I specify, and then move that email to an archive folder within outlook.
To save the email to a folder you need to use the SaveAs method of the MailItem class which 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. For example:
Sub SaveAsTXT()
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 &; ".txt", olTXT
End If
Else
MsgBox "There is no current active inspector."
End If
End Sub
To move an Outlook item to another folder you need to use the Move method which moves a Microsoft Outlook item to a new folder.
Finally, you may find the Selecting an API or technology for developing solutions for Outlook article helpful. It explains possible options for extending Outlook.
Create a COM addin using VSTO. Start at https://msdn.microsoft.com/en-us/library/ms268878.aspx
Related
So i am using Word to create a template for the generation of a .pdf using XDocReport in Java. The problem i have encountered is that when i add a bookmark to an image in Word the allowed names cannot contain "." , for example i cannot name the bookmark estimate2.Photo , which is the name needed to correctly map the variable to the virtual object being passed. My question is the following, is there any way i can alter this default Word behaviour in order for it to allow me to add bookmarks that contain special characters like "." ?
I have found a way to rewire this default behaviour by modifying the configuration .xml files. In order to access the bookmarks file follow these steps:
Go to the .docx file right-click on it go to 7zip and open as archive.
Access the word folder and there you will find the document.xml file.
extract it
Open with notepad or any other text editor, find the bookmark start xml tag which contains the name property and modify it.
Once the file has been modified drag it back inside the archive and save.
Wow. I wouldn't have thought this would work... Nice find #Patratel
not withstanding the fact that it seems to work, I wouldn't recommend doing this for anything other than a temporary file or curiosity...
That said, here's the steps to do / test this:
The manual approach:
Add a regular bookmark (shortcut: Alt > I > K)
give it a name like dot_dot
save the file
change the extension from .docx to .zip
open the .zip folder
save document.xml to the desktop (or somewhere)
Find the text dot_dot and replace with dot.dot
save .xml file
copy .xml file back to .zip folder
rename .zip back to .docx
Open in MS Word
open bookmarks dialog (Alt > I > K)
select dot.dot from list
press Goto
A quick test of functionality
From there it is easy enough to test whether or not the bookmark can be used as normal... To that end I added a new paragraph and inserted a cross reference back to the bookmarked text. The cross reference worked.
The .InsertXML approach
Next I was also curious about #Cindy's comment about Range insert XML... It worked, to test this I used the following code in the immediate window:
' replace text in document with the equivalent XML (generates a few pages)
selection.Range.Text = thisdocument.Range.WordOpenXML
' replace the XML with the result of inserting itself into the document
thisdocument.Range.InsertXML thisdocument.Range.Text
An Automatic Approach
Sub dottyBM()
Dim newDoc As Word.Document
Set newDoc = Application.Documents.Add
newDoc.Range.Text = "Testing a dot bookmark"
Dim bmRange As Word.Range
Set bmRange = newDoc.Paragraphs(1).Range
bmRange.Start = bmRange.Start + InStr(bmRange.Text, " dot")
bmRange.End = bmRange.Start + 3
' bmRange.Bookmarks.Add "dot.dot" ' Err: 5828, Bad bookmark name
bmRange.Bookmarks.Add "dot_dot"
bmRange.InsertXML Replace$(bmRange.WordOpenXML, "dot_dot", "dot.dot")
Application.Dialogs(168).Show
newDoc.Close False
End Sub
First let me start by saying that I have no idea what I'm doing. Well, some idea, but mostly I'm just winging it. I've been working on an Excel macro to run a Word mail merge from Excel for a couple of weeks and I've pieced together different codes to encompass everything I need it to do. My problem is that it works the first time but it gets stuck each subsequent time if I do not reset the macro.
The sheet I made is designed so the macro can pull all of the information it needs from the sheet (code contains no hard coded locations). This is because a folder containing the Excel form, the letter templates and the finished letters will be sent to multiple users and will therefore be saved in a different location on each user's computer. The user enters details into the Excel form which will ultimately create a formatted disciplinary letter in a Word document to send out to the player being reviewed. There may need to be multiple infractions included in the letter so the Excel form provides that option, whereas a Word form would have a bunch of unnecessary empty fields. (I initially tried setting up the letter in Word as a form but I couldn't get all of the factors that I needed to work together) A Word form also doesn't have the ability to hide fields and can't support the dependent drop down lists or the amount of text in each drop down that I require. Anyway...
The process:
User opens the Excel file and enters information into a nicely laid out, user friendly form which contains dependent drop down lists, etc as well as buttons that hide and show fields (in case the user needs to include multiple infractions being reviewed).
When the user is finished entering their information, they click a command button to run the mail merge ("Create Disciplinary Letter").
The information they select in the form is linked to another worksheet (same workbook) called "Data Sheet" that contains the columns that the merge will pull from.
The workbook also contains a "Control Sheet" worksheet which provides the location of the files and folders that the macro is to pull from.
The macro should:
Open Word merge template (it chooses the correct template based on a choice that the user makes in the form)
Run the merge
Send merged product to a new document
Close the original merge template without saving changes
Save the new document with a specific file name (based on choices the user made in the original Excel form)
Save it to a "Final Documents" folder which is located in the original folder that I send out to the user(s).
The newly saved document/letter stays open for further editing (if necessary)
New doc contains a button that will save the finished letter as a .pdf (also to a specific location) but that macro is in Word so it is not part of my problem.
The Excel form would likely be closed and reopened before a user needs to use it again, and in that case, the macro would run fine. There is a good possibility though, that the user will see the finished letter in Word, realize that they forgot the include an infraction, go back to the open Excel form to add the infraction, and click the macro button again. If this happens, the macro will get stuck at macro process #4 onward (from list above). I don't know what is in the code (or missing) that is causing this but I've been fighting with it for days and I can't find anything out there that I can apply to my issue. Or maybe I have, but I'm unaware because I'm seriously just winging it.
Sub RunMerge()
Dim bCreatedWordInstance As Boolean
Dim wdapp As Word.Application
Dim wddoc As Word.Document
Dim rng1 As Range
Dim wb As Workbook
Dim wsControl As Worksheet
Dim wsData As Worksheet
Dim strWorkbookName As String
Dim strTemplateFolder As String
Dim strTemplateName As String
Dim lngTemplateNameColumn As Long
Dim strFinalDocumentFolder As String
Dim strFinalDocumentName As String
Dim lngDocumentNameColumn As Long
Dim lngRecordKount As Long ' not used but retained for future use
Set wb = ThisWorkbook
Set wsControl = wb.Worksheets("Control Sheet")
wsControl.Activate
strTemplateFolder = wsControl.[Template_Folder].Value
strFinalDocumentFolder = wsControl.[Document_Folder].Value
Set wsData = wb.Worksheets(wsControl.[Data_Sheet].Value)
wsData.Activate
lngTemplateNameColumn = wsData.[Template_Name].Column
lngDocumentNameColumn = wsData.[Document_Name].Column
Set rng1 = wsData.Range("B1:B8")
strTemplateName = strTemplateFolder & "\" & wsData.Cells(2, lngTemplateNameColumn) & ".doc"
strFinalDocumentName = strFinalDocumentFolder & "\" & wsData.Cells(2, lngDocumentNameColumn)
strWorkbookName = ThisWorkbook.Path & "\" & ThisWorkbook.Name\
On Error Resume Next
' Create a Word Application instance
bCreatedWordInstance = False
Set wdapp = GetObject(, "Word.application")
If wdapp Is Nothing Then
Err.Clear
Set wdapp = CreateObject("Word.Application")
bCreatedWordInstance = True
End If
If wdapp Is Nothing Then
MsgBox "Could not start Word"
Err.Clear
On Error GoTo 0
Exit Sub
End If
' Let Word trap the errors
On Error GoTo 0
' Set to True if you want to see the Word Doc flash past during construction
wdapp.Visible = True
' check that template exists
If Dir(strTemplateName) = "" Then
MsgBox strTemplateName & " not found"
End If
Set wddoc = wdapp.Documents.Open(strTemplateName)
If wddoc Is Nothing Then Set wddoc = wdapp.Documents.Open(strTemplateName)
wddoc.Activate
With wddoc
.MailMerge.OpenDataSource Name:=strWorkbookName, SQLStatement:="SELECT * FROM `Data Sheet$`"
With wddoc.MailMerge 'With ActiveDocument.MailMerge
.Destination = wdSendToNewDocument
.SuppressBlankLines = True
.Execute Pause:=False
End With
End With
' Save new file
ActiveDocument.SaveAs strFinalDocumentName
' Close the New Mail Merged Document
If bCreatedWordInstance Then
wddoc.Close savechanges:=wdDoNotSaveChanges
Set wddoc = Nothing
End If
0:
Set wdapp = Nothing
Set rng1 = Nothing
Set wsData = Nothing
Set wsControl = Nothing
Set wb = Nothing
End Sub
It gets stuck the second time around on:
' Save new file
ActiveDocument.SaveAs strFinalDocumentName
I created a new style in word(through "create a style...") and I want to assign this style to 200 word files. it is very time consuming to open them one by one and assign the style to them. Is there any way to assign the style to them without opening them?
The easiest way to do this is using Word VBA.
Place the 200 Word files that will be assigned the style into a directory that contains no other files. Then create a .dotm (Word 2007 or higher) or .dot (Word 2003 or lower) template file in a different location. Create the style to be copied in the template file and also place the following code into a module within that same template file (ALT-F11 to access the editor):
Sub BatchCopyStyles()
'Make sure that the template that contains the style to be copied and this code
'is open and acting as the active document before running this macro
Dim file As Variant
Dim folderPath As String 'path to files receiving the style
Dim targetPath As String
Dim templateFile As String 'file that contains style and this code
Dim styleTemplate As Document
folderPath = "C:\Users\Joe\Desktop\TargetFolder\"
templateFile = "C:\Users\Joe\Desktop\CopyStyle.dotm"
Set styleTemplate = ActiveDocument
file = Dir(folderPath)
While (file <> "")
Set file = Documents.Open(FileName:=folderPath & file)
styleTemplate.Activate
targetPath = folderPath & file
Application.OrganizerCopy Source:=templateFile, _
Destination:=targetPath, _
Name:="StyleToCopy", _
Object:=wdOrganizerObjectStyles
file.Close wdSaveChanges
file = Dir
Wend
End Sub
Edit the code for the correct paths, file name, style name, etc. With the file containing this code and the style to be assigned as the Active Document, run the macro from the VBA editor (F5). This will open each file, copy the style, and then close the file. Opening and closing a document 200 times won't be pretty, but it should do the job.
I am going nuts here. I have tried countless permutations/variations of "save as active document file format PDF" but none seem to work. I get AppleScript errors with all of them.
So can anyone tell me:
What is the exact syntax to save the active document as a PDF file in AppleScript, using Word?
It seems that there is no coherence whatsoever in the Office for Mac scripting, as I have this working for Excel and PowerPoint and even there the syntax is different:
excel
save active workbook in 'MyFile.pdf' as PDF file format
PowerPoint
save active presentation in 'MyFile.pdf' as save as PDF
What is the correct syntax for Word?
Thanks!
It seems I found it after all:
set myDoc to "/Users/X/Desktop/test.docx"
set pdfSavePath to "Users:X:Desktop:test.pdf"
tell application "Microsoft Word"
activate
open myDoc
set theActiveDoc to the active document
save as theActiveDoc file format format PDF file name pdfSavePath
end tell
I am no AppleScript expert. I had slashes instead of : as path separators. With : it works
Joris Mans script is pretty nice, but has a flaw. It does not ensure that Word has an active document ready (set theActiveDoc to the active document might return missing value)
I also improved the script to use the Finder selection as input, placing the PDFs into the same place as the word files. I did not test the file types, but word will complain about that.
tell application "Finder"
set input to selection
end tell
tell application id "com.microsoft.Word"
activate
repeat with aFile in input
open aFile
set theOutputPath to ((aFile as text) & ".pdf")
repeat while not (active document is not missing value)
delay 0.5
end repeat
set activeDoc to active document
save as activeDoc file name theOutputPath file format format PDF
close active document saving no
end repeat
end tell
Is there a way to link to a chm file, and therein to a certain topic, from a Microsoft Word docx document? Something in the lines of:
"For more information about this Property see [link ref="./SomeDirectory/somedocument.chm!Sometopic.Somesubtopic" text="MyClass.MyProperty"]
I don't think that simply a file link to the .chm file will do the job.
For me, the following link format works (note that the .chm file must be in a trusted location, network shares will not work per default):
mk:#MSITStore:C:\SomeDirectory\help.chm::/helppage.htm
EDIT
For relative paths it seems the
following pattern must be used:
ms-its:.\help.chm::/html/main.htm
(see
Linking to a CHM - Some Notes)
This link will be opened in IE (right-click in the HTML help viewer to see the location of this link under properties).
Another option would be to insert a MACROBUTTON and have a macro opening the HTML help viewer. This would be the VBA code:
Declare Function HtmlHelp Lib "HHCtrl.ocx" Alias "HtmlHelpA" _
(ByVal hwndCaller As Long, _
ByVal pszFile As String, _
ByVal uCommand As Long, _
dwData As Any) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Function GetWindowHandle() As Long
'obtain Word's hwnd
'NOTE: there is a possibility of getting the wrong hwnd. If two word windows
'are open with the same caption, this *could* happen. In order to prevent this,
'you can either change the caption to something strange before trying to find it,
'or you can compare processId's with GetCurrentProcessId and GetWindowThreadProcessId
'You can always search the top level windows yourself.
GetWindowHandle = FindWindow(Word8ClassName, ActiveDocument.Windows(1) & " - " & ActiveDocument.Application.Caption)
End Function
Public Function ShowHelp(strPage As String)
On Error Resume Next
HtmlHelp GetWindowHandle, "fullpathtohelpfile.chm", HH_DISPLAY_TOPIC, ByVal strPage
End Function
In order to find the address of a page in a chm file, you need to richt-click the page (the page itself, not the link in the contents tree) and select 'Properties'. Under 'Address (URL)', you find what you are looking for, something like
mk:#MSITStore:D:\Tools\Foo\Bar.chm::/help/base/index.html
And the good thing: You can select the text in the property sheet with your mouse and copy it ;-)
As for how you have to insert the URL into word in order for this to work, I have no idea, but a short trial and error should get you there.
You should be able to do it by setting the hyperlink to the file and use the "#" header anchor (I'm not sure what it is called...) but here is an example:
C:\Helpfiles\Help.chm#Topic