PDA

View Full Version : [SOLVED:] Word Add-In Not Working (Word 2013)



davis1118
12-06-2017, 08:51 AM
I have ran into an issue once again. I have a macro that runs before save to update footers, print to pdf, and create a backup document. The macro works when it is ran on a single document as just a macro, and it also works on a single document if it is loaded as a template. The problem is when I place the macro as a template in the startup folder. I don't see it load the add-in in the word startup pop up box, and nothing happens when I save a file. It shows up in the Active Application Add-In list on the add-in menu, and it is checked in the add-in prompt screen under Global Templates and Add-Ins. It also shows up in the project window in the VBA editor. I'm not sure if I am missing something in the code or if somehow the security settings at work are blocking it from running? But the startup folder is a trusted location, so I'm not sure how it would be blocked. There are hundreds of files that I want this code to run on, so I would like to have a global update rather than load the template to each file individually. Below it the code that I have.

ThisDocument

Private Sub Document_New()
Call Register_Event_Handler
End Sub
Private Sub Document_Open()
Call Register_Event_Handler
End Sub


Module (mdlEventConnect)

Dim X As New EventClassModule
Public Sub Register_Event_Handler()
Set X.App = Word.Application
End Sub


Class Module (EventClassModule)

Public WithEvents App As Word.Application
Private Sub App_DocumentBeforeSave(ByVal Doc As Document, SaveAsUI As Boolean, Cancel As Boolean)
If SaveAsUI Then
GoTo lbl_End
Else
Dim myForm As frmSaveMethod
Dim i As Long, bAdd As Boolean: bAdd = True
Dim sTab As String
Dim oSection As Section
Dim oHF As HeaderFooter
Dim myName As String
Dim ext As String
Dim myPath As String
Dim T As String
Dim fso As Object
myName = Left(ActiveDocument.Name, (InStrRev(ActiveDocument.Name, ".") - 1))
ext = Right(ActiveDocument.Name, Len(ActiveDocument.Name) - InStrRev(ActiveDocument.Name, "."))
myPath = ActiveDocument.Path & "\"
T = Format(Now, "DDMMMyy")
On Error GoTo lbl_Error
'SAVE & UPDATE MESSAGE BOX
Set myForm = New frmSaveMethod
myForm.Show
Select Case myForm.Tag
Case 1
'FOOTER SECTION
With ActiveDocument.Sections.First.Footers(wdHeaderFooterPrimary).Range
For i = 1 To .Fields.Count
If .Fields(i).Type = wdFieldPage Then
bAdd = False: Exit For
End If
Next
sTab = vbTab & " "
If bAdd = True Then
.Fields.Add .Characters.Last, wdFieldEmpty, "FILENAME", False
.InsertAfter "_"
.Fields.Add .Characters.Last, wdFieldEmpty, "DATE \@ ""DDMMMyy""", False
.InsertAfter sTab
.Fields.Add .Characters.Last, wdFieldEmpty, "PAGE", False
.InsertAfter " of "
.Fields.Add .Characters.Last, wdFieldEmpty, "NUMPAGES", False

End If
End With
For Each oSection In ActiveDocument.Sections
For Each oHF In oSection.Footers
oHF.Range.Font.Size = 8
Next
Next
'-SAVE & BACKUP SECTION-
If ActiveDocument.Path = "" Then GoTo lbl_Exit
'SAVE AS PDF
ActiveDocument.ExportAsFixedFormat _
OutputFileName:=myPath & myName & ".pdf", _
ExportFormat:=wdExportFormatPDF, OpenAfterExport:=True
'SAVE IN ARCHIVE FOLDER
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(ActiveDocument.Path & "\Archive") Then
fso.CreateFolder (ActiveDocument.Path & "\Archive")
End If
fso.CopyFile ActiveDocument.FullName, ActiveDocument.Path & "\Archive\" & myName & "_" & T & "." & ext

ActiveDocument.Save

Case 2
'MORMAL SAVE - NO MACRO
ActiveDocument.Save

Case 3
'CANCEL BUTTON
Cancel = True
End Select
Unload myForm
Set myForm = Nothing
lbl_Exit:
Set fso = Nothing
End If
lbl_End:
Exit Sub
lbl_Error:
MsgBox "The following error occurred: " & Err.Description
Unload myForm
Set myForm = Nothing

End Sub



Thank you for the help. -David

SamT
12-07-2017, 12:19 PM
Maybe

Public With Events X As Application
Public Sub Register_Event_Handler()
Set x = New EventClassModule
Set X.App = ActiveDocument.Application
End Sub

Personally, I would rather use a Property Set statement than a Public Variable. I would also name the Class Module, "clsEventHandler," and Change "X" to "EventHandler." At the very least, Change "X" to a meaningful name.

davis1118
12-07-2017, 07:22 PM
After giving your suggestion a try and many, many other attempts I was not able to get the event/macro to run as an add-in. But after hours of searching online I finally found my answer. I simply needed to change the module procedure name. I found this answer from "Microsoft Word MVP FAQ Site".
https://wordmvp.com/FAQs/MacrosVBA/AppClassEvents.htm

Here is what I had to change in the Module:

Dim EventHandler As New clsEventHandler
Public Sub AutoExec()
Set EventHandler.App = Word.Application
End Sub

The AutoExec automatically fires when the add-in is opened. But this procedure name doesn't run the event when it is a .docm file. It only works when ran as an add-in.

Even though I couldn't get your suggestion to work, I appreciate the reply and the help! Thank you very much SamT.
-David

SamT
12-07-2017, 07:40 PM
I've heard that using the "New" Keyword in the Set Statement is more stable than in the Declare Statement.:dunno: It's the way I do it.

davis1118
12-07-2017, 09:28 PM
I'm not sure if I was doing something wrong but I could not get the "New" set statement to work. That's the only reason why I went back to declaring it new. Most likely it's my lack of knowledge.

I do have one other question that I wanted to get your opinion on. I want to give this template to multiple people so all of our documents are saved the same. Initially I was going to have each person place the template in the word "Startup" folder for each user. At my company, everyone works from a main "K:" drive separate from the users "C:" computer drive.

I started to think about if I ever wanted to make a change to the macro, I would have to have re-distribute the template to all the users to place in their own "Startup" folder.

My question is whether it would be a good idea to put the template in a central folder and then distribute shortcuts to the main template? The shortcuts would then be placed in each users Word "Startup" folder. This way if I need to make a change to the main template I just replace the template in the central folder. Also, if any user wants/needs to remove the add-in template they can delete their shortcut without affecting any of the other users.

Or is this just a bad way to handle this?

Thanks again for any advice! - David

SamT
12-08-2017, 07:14 AM
Here's a real life example from my archives

Const StartCountingAt As Long = 1000000
Private pUpdateCount As Long

Private MarketWriter As Object
Private HorsesWriter As Object
Private MicroTimer As Object

Private Sub Class_Initialize()

On Error GoTo HandleError

pUpdateCount = StartCountingAt

Set HorsesWriter = New clsTableWriter_Brand
Set MarketWriter = New clsTableWriter_Market
Set MicroTimer = New clsMicroTimer

Exit Sub
HandleError:
ErrorHandler.DisplayMessage "InitRecorder"
End Sub
ErrorHandler is the name of a Standard Module. Public Function DisplayMessage uses the Parameter to select the message to display.


The Shortcuts idea sounds good... if Shortcuts will work.

davis1118
12-08-2017, 09:17 AM
Thank you for the example SamT. I will have to give that setup a try! Thanks for the help.

I ran into another issue, but I think it needs a new thread so I will not be putting it in here.