I have a template (dotm) file in the word startup folder -C:\Users(username)\AppData\Roaming\Microsoft\Word\STARTUP.
I want to have a macro (vba code) in this dotm file that delete this template from the startup folder. The template is an add-in with custom RibbonXML. I want one of my buttons to be "uninstall" button, which deletes the template file from the startup folder.
What you envision is not possible.
In order for the macro in the template to run, that template must be open or loaded as an add-in. In that case, there's a "file lock" on the template: it cannot be moved or deleted.
Deleting the template must be done from code that is not associated with the template, when the template is closed and there is no longer a file-lock.
Edit based on new information edited into the question
Possibly, code in another file could do this, although it's not certain the file lock will be released in a timely manner after the Unload method removes it from Word. It might require running code on a Timer to repeat the Kill command until it's successful.
Use the idQ attribute for the RibbonX tab/group that will contain the "Uninstall" button. This lets other RibbonX share the tab/group by using the same idQ value. Put the Ribbon XML defining that button, as well as the code for it, in the other file. When both files' Ribbons are loaded it will appear to the user as one Ribbon.
The startup template would load this other file as an add-in using the method Application.AddIns.Add.
Related
The scenario:
When word starts, it connects via vba to a Service, which returns a list of paths. Each of These paths points to a .dotm file. These files contain information about various controls (inside the ribbon, for example a butto which adds a specific footer).
What I want: I need a possibility to load several .dotm files, but without copying or moving them to a specific location.
Basically that's it. I've searched wide and far and I have the fear, that this Approach is actually not possible, and that I have to copy all dotm files inside the startup-folder and let word do the rest
Is there any way how I can load several dotm files into a single word-file, so that the ribbon gets extended depending on the dotm's
Best regards, please and thanks :)
From word documentation:
This example attaches the template "Letter.dot" to the active document.
ActiveDocument.AttachedTemplate = "C:\Templates\Letter.dot"
You can use this to attach all your templates to the document.
See also the Templates collection.
you can add a template to the Templates collection by using the Add method with the Addins collection to load a global template
Sub AddTemplate()
' For this example to work correctly, verify that the
' path is correct and the file exists.
AddIns.Add FileName:="C:\Program Files\Microsoft Office" _
& "\Templates\Letters & Faxes\MyFax.dot", Install:=True
End Sub
It's not possible to load multiple templates to a single Word file. Only one template can be attached to a document.
It is possible to load multiple templates as add-ins in the Word environment. These will be available then to all documents opened in the Word application. Use the Addins-Add method to add a template to the list in Document/Document Template, the "Global templates and add-ins" list. (This is the equivalent of the "Add" button in the dialog box.)
Dim bInstalled as Boolean
Dim Path as String
Dim fileName as String
'Populate the variables, then...
Application.Addins.Add Filename:=Path & fileName, Install:=bInstalled
Set bInstalled to false if you want the template in the list, but not loaded (Ribbon isn't displayed, for example); set it to true to also load it. Once a template is in the list, whether loaded or unloaded, it will generally remain in the list unless Word is reset in some manner. The code for managing template add-ins would be more efficient if it first checks whether an Add-in is already in the list before adding it again.
Templates that are in the list can be loaded/unloaded using the Addins.Installed property. If the tools in a template should be available only to certain documents then they can be loaded/unloaded dynamically by using events, such as DocumentChange.
The code to load the add-ins and manage them (events) should probably be in a central template in Word's Startup folder or in the template attached directly to the document.
I have an existing Macro Enabled Template which I would like to add Content Control to, to be available on the screen when the Template is accessed.
I know how to add the Content to a Word Document and then save it as a Template. The problem is that I cannot view the Exisiting Template's Word Document due to the view Object being greyed out. See below:
I really do not want to copy all my Macros and my quick texts over to a new document just to add one line of text and a button.
I can easily add the required text and CommandButton by having a script run in a Document_New Sub under the ThisDocument. The problem is that this Sub bombs out due to Macros not being enabled. I intend to have the Template distributed to numerous colleagues, therefore having the Text and button on the document will avoid any confusion as to what to do with the template.
You need to open the Template via File - Open
Opening the Template this way will display give you access to the Template.
For info: The name of the Template will appear in the Center of the Word Application.
I have multiple files with the same VBA code in them, which will most likely have to be changed over time. I don't want to go one by one and c/p the code, so one obvious idea that came to mind is to have one centralized document with the code (template?) that all files refer to.
I found a few topics here at stackoverflow, but none of them work for me or are inconclusive:
Run external vba-code in MS Word
Centralized VBA code (one file) for multiple workbooks
Calling an External VBA from VBScript
Any ideas?
Yes, your idea of centralizing the code in a template and attaching that template to the various Word docs will work. These pics are using Word 2007 but I think it's pretty similar for newer versions. First create a new document and put the code in a Module (named "CommonFunctions" in the picture):
Save the doc as a macro-enabled template:
Now make a new document, save it as a *.docm (necessary for it to run code because a *.docx is macro-free), and attach the document template as shown below. (An alternative is to put the *.dotm file in the startup directory C:\Users\<username>\AppData\Roaming\Microsoft\Word\STARTUP, which loads it automatically.) If you don't put it in the Startup, you'll see the name but it won't be loaded (ie, checked), but you can load it in code, as I'll show.
Make a user form in this document:
Put this code for the button's click event:
If AddIns("c:\_b\MasterDocWithFunctions.dotm").Installed = False Then
AddIns("c:\_b\MasterDocWithFunctions.dotm").Installed = True
End If
Application.Run "CommonFunctions.Test1"
Application.Run "CommonFunctions.Test2"
Notice how the code can load the AddIn for you, because it won't be automatically loaded unless you put it in the Startup directory. This pic shows how the AddIn is referenced but not loaded. You need the checkbox to be able to call code in it. If you don't load it using code and don't put it in the Startup, then the user will have to manually put a checkmark everytime the document opens.
Now the form should work when you click the button. Notice how it can call both public and private functions. The Private keyword definitely shields one module from another, but it seems like modules that are called from an AddIn are considered to be part of the same module, not sure why? Also if you don't put Public or Private at all then VBA considers it Public, I'm pretty sure.
I have a template with a macro that runs every time I open the .dotm file.
However when I go to New and click on the template it generates the new file based on the template and with references to its code but the macro doesn't run.
What I need for the macro to do is to open a form in the template.
Take a look at this article (old but still relevant) which should help:
Running a macro automatically when a document is created, opened or closed.
Basically, you need to handle the AutoNew() and possibly the AutoOpen() events in your code module.
I have written some code for an excel spreadsheet. This sub has been added to the ribbon using the standard customizations found in File -> Options -> Customize Ribbon. What is funny though, is that the customization will run the Sub on the EXACT EXCEL FILE that the Sub is written in, i.e. the original.
My users copy the excel file and make adjustments and then run the sub (by clicking the customized button in the ribbon), which then opens the ORIGINAL template file and runs the code. This actually works fine - and I like it because it runs the TEMPLATE code on the ACTIVE sheet. But the only problem is it is also OPENING the original template file. How do I get it to close? Remember it is not the ActiveSheet anymore.
One possible answer is to check if the template is open, then close it (using a static reference), but I would prefer something a little more elegant than that.
You should be able to find the template/original using ThisWorkbook.
Also, if you deliver your workbook's code as a .xlam instead of .xlsm, it will be opened, but there won't be a window for it, so users won't see it.
Not sure if you're using this already, but you might also want to use "for this workbook only" when adding ribbon buttons for a .xlam . (Delivering as .xlam allows you to install buttons from a workbook into the ribbon, without relying on file path and without needing your users to also install buttons (they install .xlam instead).)