Answered by:
Use VB script to paste code into a module?

Question
-
There are many users in my company who currently use Word 2007. These are ordinary users who know nothing about programming or macros or Visual Basic. I would like to install some VBA macro code into each user's "Normal" project area, either in the "ThisDocument" code section or the "NewMacros" code section.
Rather than manually typing VBA code into each user's "Normal" project space, can I somehow create a Word macro file that each user can run which will insert code or functions into their Visual Basic project spaces??
Thanks!
jmmcFriday, May 6, 2011 6:55 PM
Answers
-
Hi Robert,
You could use something like:
Sub AddModule()
Dim VBComp As VBComponent
With ThisDocument.AttachedTemplate.VBProject
For Each VBComp In .VBComponents
If VBComp.Name = "NewModule" Then Exit Sub
Next
Set VBComp = .VBComponents.Add(vbext_ct_StdModule)
VBComp.Name = "NewModule"
End With
Application.Visible = True
End Sub
Cheers
Paul Edstein
[MS MVP - Word]- Marked as answer by Calvin_Gao Friday, May 13, 2011 3:15 AM
Tuesday, May 10, 2011 10:01 PM
All replies
-
Hi Robert,
There are various approaches one could take, including:
Add A New Module
With the macro below you can add a new module in a document. The procedure below will add a new module named "NewModule" to the target document (in the example below, ThisDocument):Sub AddModule()
Dim VBComp As VBComponent
Set VBComp = _ ThisDocument.VBProject.VBComponents.Add(vbext_ct_StdModule)
VBComp.Name = "NewModule"
Application.Visible = True
End SubAdd A Procedure To A Module
The procedure below will add a new procedure called "MyNewProcedure" to the module named "NewModule" in the target document (in the example below, ThisDocument):Sub AddProcedure()
Dim VBCodeMod As CodeModule
Dim LineNum As Long
Set VBCodeMod = ThisDocument.VBProject.VBComponents("NewModule").CodeModule
With VBCodeMod
LineNum = .CountOfLines + 1
.InsertLines LineNum, _
"Sub MyNewProcedure()" & Chr(13) & _
" Msgbox ""Here is the new procedure"" " & Chr(13) & _
"End Sub"
End With
End SubNote the way in which the .InsertLines method is called. The entire procedure is passed as one argument - a string with embedded Chr(13) characters for the line breaks.
Add Content To A Module From A File
If you don't want to add a complete module, you can add just the missing procedures to an existing module by using the macro below. It adds the content of a text file to an existing module in a document.Sub ImportModuleCode(ByVal Doc As Document, ByVal ModuleName As String, ByVal ImportFromFile As String)
' imports code to ModuleName in wb from a textfile named ImportFromFile
Dim VBCM As CodeModule
If Dir(ImportFromFile) = "" Then Exit Sub
On Error Resume Next
Set VBCM = Doc.VBProject.VBComponents(ModuleName).CodeModule
If Not VBCM Is Nothing Then
VBCM.AddFromFile ImportFromFile
Set VBCM = Nothing
End If
On Error GoTo 0
End SubExample:
ImportModuleCode ActiveDocument, "TestModule", "C:\FolderName\NewCode.txt"Add A New Module From A File
With the macro below you can insert new modules with contents into the target document (in the example below, ActiveDocument). This requires you to have created the new module previously in another (temporary) document. Export the finished module to a text file by right-clicking the module name and select Export file... in the shortcut menu.Sub InsertVBComponent(ByVal Doc As Document, ByVal CompFileName As String)
' inserts the contents of CompFileName as a new component in wb
' CompFileName must be a valid VBA component suited for import (an exported VBA component)
If Dir(CompFileName) <> "" Then ' source file exist
On Error Resume Next ' ignores any errors if the project is protected
Doc.VBProject.VBComponents.Import CompFileName ' inserts component from file
On Error GoTo 0
End If
Set Doc = Nothing
End SubExample:
InsertVBComponent ActiveDocument, "C:\FolderName\Filename.bas"Copy A VBA Module From One Document To Another
To copy a module to another document, the user opens the document containing the code, which exports the module then imports it into the destination document.Sub ExportModule()
' Delete any old copies of the module
On Error Resume Next
Kill ("Module1.bas")
On Error GoTo 0
' Export Module 1
ActiveDocument.VBProject.VBComponents("module1").Export ("Module1.bas")
' Put code to target the destination document here
'
' Import Module 1
Application.VBE.ActiveVBProject.VBComponents.Import ("Module1.bas")
ActiveDocument.Close
' Delete the module copy
Kill ("Module1.bas")
End SubPS: To use the above procedures, you need to set a reference to Microsoft Visual Basic For Applications Extensibility and the user running the code must grant access to VBA object model (see http://support.microsoft.com/kb/282830).
Cheers
Paul Edstein
[MS MVP - Word]- Edited by macropodMVP Sunday, May 8, 2011 5:33 AM See new last paragraph
Saturday, May 7, 2011 12:49 AM -
You really shouldn't do anything to a user's Normal template. Why not create a new template with whatever code you want and then copy it to each user's STARTUP directory with a logon script?
Enjoy,
Tony
www.WordArticles.comSaturday, May 7, 2011 9:53 AM -
Hi Paul,
Thank you for the code. The top two code examples seem to be what I was looking for. However, I might NOT want to add a new module; instead, I might want to add a subroutine into the Normal->Microsoft Word Objects->ThisDocument section. I tried modifying the code so it uses the "Normal.ThisDocument" object, but it keeps adding a new module, instead of inserting a subroutine into the Normal.ThisDocument. Do you know how to do this?
Thanks!
jmmcSunday, May 8, 2011 1:42 AM -
Hi Robert,
For the second method, assuming you've opened Normal.dot(m) for editing, you'd use something like:
Set VBCodeMod = ThisDocument.VBProject.VBComponents("ThisDocument").CodeModuleAlternatively, if you've only opened a document to which the Normal.dot(m) template is attached, I think you'd need something like:
Set VBCodeMod = ThisDocument.AttachedTemplate.VBProject.VBComponents("ThisDocument").CodeModulePS: I should have mentioned the need to have a reference set to Microsoft Visual Basic For Applications Extensibility and the user running the code must grant access to VBA object model (see http://support.microsoft.com/kb/282830).
Cheers
Paul Edstein
[MS MVP - Word]Sunday, May 8, 2011 5:12 AM -
Thanks for the code Paul. It works fine for me.
I have another question: How can I test if a module already exists? If I run this function twice ("ThisDocument.VBProject.VBComponents.Add") in a row it will cause problems for me, so I need to check that a module doesn't already exist before I add a new one.
Thanks
jmmcTuesday, May 10, 2011 8:32 PM -
Hi Robert,
You could use something like:
Sub AddModule()
Dim VBComp As VBComponent
With ThisDocument.AttachedTemplate.VBProject
For Each VBComp In .VBComponents
If VBComp.Name = "NewModule" Then Exit Sub
Next
Set VBComp = .VBComponents.Add(vbext_ct_StdModule)
VBComp.Name = "NewModule"
End With
Application.Visible = True
End Sub
Cheers
Paul Edstein
[MS MVP - Word]- Marked as answer by Calvin_Gao Friday, May 13, 2011 3:15 AM
Tuesday, May 10, 2011 10:01 PM -
I have a very similar need to add a module filled with code to the Normal.dot for several users. Thanks for the tips! I will try it and check back...
Thursday, May 26, 2011 5:34 PM -
Hi,
I have a little problem when dynamically creating a macro in ThisDocument. The document protected. So I unprotect the document, add the macro with the InsertLine command and try to reprotect the document. However, Word always crashes when performing the last step. Any idea ?
Thanks
Monday, October 31, 2011 10:51 AM