Link to home
Start Free TrialLog in
Avatar of Dev2003
Dev2003

asked on

Error 'Microsoft Word unable to run specified macro'

I wrote a software solution in the form of a Lotus Notes database for a company.

The company is running Notes 4.6.
I wrote an agent to perform a mail merge with Microsoft Word.

When a user wishes to perform a mail merge, they create a letter in Word from a template I set up.
This template stores 4 macros used to perform the mail merge (eg cut the letter, paste the letter, create page break etc.)
In Lotus Notes, the user clicks a button to run the agent.

The code works fine!!
I've got the code running fine on at least one computer at the company. No probs!
However, on one particular machine it throws an error.

The error 'Microsoft Word unable to run specified macro'
I have had this error before when writing the agent.
The solution was to change the security of macros in Microsoft Word. Instead of being 'High' security, it was made 'Medium' or 'Low' (ideally Medium, I know!)

So to get the code working on this one computer, I would need to change the security settings as done previously.

No heres the catch:-

 - Both machines at the company (the one with the error and the one that works fine with the code) are running Windows XP and Office 97!

 - Both machines are connected to a network and have the same type of user account (same security)

 - The manager of the company spoke to the network guys and they said Word 97 does not have the option in the menu to change the macro security (in Word 2000, this is in the menu 'Tools - Macro - Security')

 - On the MSDN website (microsoft website), they seem to think Word 97 onwards has the ability to change macro security.  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnword2k2/html/odc_wdtemp.asp

 - I spoke to the lady whose computer has the problem and she couldn't see the 'Security' option in the menu.

 - So, who's right! By the sounds of it, probably the network guys. Or maybe the user accounts have had restrictions not allowing them to change security settings in Word.

Anybody know whether it does or does not? Also how can I change the settings? If I can't change the settings in Word 97, what else could be ther problem for causing the error?

Thanks
Avatar of Dev2003
Dev2003

ASKER

Since posting the question, I have found out a bit more.

Microsoft Word 97 does not have macro security settings as such.

When opening a document that contains a macro, Word 97 will as the user if they wish to run the macro. When the message pops up the user has the chance to uncheck the option 'Do not as this again'.

The user can also go into the options via 'Tools - Options - General Tab'
On the General Tab towards the bottom of the list is the check box for 'Macro virus protection' or something similar.

I did try unchecking this option and then run the mail merge in Lotus Notes.
The error still came up.

I just wonder if it has anything to do with the user's security in Lotus Notes. That would make more sense!

I know that in the Domino Server setup you can specify who runs restricted or unrestricted agents. However, I have had no experience with this in Notes 4.6, only in 5.

Is it still possible to specify who runs what on a 4.6 server?

I'm currently looking into the company server setup to see what the user's access rights are!

Watch This Space
Avatar of CRAK
So you use a macro in Word (in your template) to take part in the merge?
In that case, if you launch the template manually, the problem should still occur, right? It has nothing to do with Notes (code or authorisation). You don't get any notes errors?!
In that case you should perhaps post or move this question in the MS office topic area.....

The rights to run restricted / unresticted agents are set on the server document, under Security > Agent restrictions (R5) or -if I recall right- under "Restrictions" in R4.x. You'd need restricted access for operations controlled by notes, or unrestricted to move beyond that, like writing files to disk. If you change the server document, you may need to restart the (notes) server for the change to become effective immediately.
Avatar of Dev2003

ASKER

no.

if i launch the template manually nothing happens because the macros aren't set to run on an event.

However, above I said that the mail merge works fine on one persons machine. It only causes an error on one machine. The code is fine.

The error message appears in Lotus Notes! Not in the Word GUI.

I know about restricted and unrestricted but does a restricted agent stop the user from running a Word macro? I think it does, so thats why i'm looing at the server document
So by triggering the (word) macro manually, it doesn't fail?!
Strange!
Does the notes agent open word at all? That already sounds "unrestricted"....
If the error message is fixed (predefined), it should be documented somewhere! It doesn't sound like a notes error to me. The phrase "Microsoft Word...." gives me that feeling. Notes would rather report about an "object" or a "method". It probably doesn't refer to the application by its name!
Avatar of Dev2003

ASKER

Triggering the (word) macro manually won't fail.

The agent in Notes (on the machine that doesn't work) will open Word, just won't be able to call any macros in the document. That is why I believed it was to do with macro security.

But if opening Word is a restricted command in a Notes agent then it doesn't make sense why it will open Word but not run a macro (which i gather is a restricted command)

Are you able to tell me whether or not 'opening Word' and 'calling a macro' are restricted commands?
ASKER CERTIFIED SOLUTION
Avatar of CRAK
CRAK
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This is definitely a Word error, Notes is reporting it nly because you accessed Word from Notes.

I owuld like to see your code that accesses Word.  Are you using CreateObject and then using the Word object model to create document from template and start Macro code?
Avatar of Dev2003

ASKER

Heres the code that I am running. In fact the code isn't in an agent, just in a button. So are restricted commands still applicable?

My code does NOT create the actual document used in the mail merge. The user will open Word and create the letter document from the template BEFORE running the code in Notes.

The code will ask the user to select the document that they wish to mail merge.

It will then open this document, Run the 'Cut' macro, get the address from the database, add the address to the document, 'Paste' the letter with a macro, then 'Add a Page' macro will add a page and repeat the process for each contact selected in the Notes view.



   ' declare and set Notes back-end objects and variants
      Dim session As New notessession
      Dim db As notesdatabase
      Dim doc As NotesDocument
      Dim dc As NotesDocumentCollection
      Set db = session.currentdatabase
      Dim settings As NotesDocument
      Set settings=db.GetProfileDocument("Settings","")
      Dim ws As New NotesUIWorkspace
      Set dc=db.UnProcessedDocuments
      
     'define variants and strings
      Dim letterSubject As String                    
      Dim letterContents As String                    
      Dim saveLetter As Variant                        
      Dim answer As Variant
      
     'check that the user wants to mail merge and print the document and that they have actually selected a document
      If dc.count = 1 Then
            
          'ask user if they want to mail merge the one document, if no then exit the routine
            answer = Messagebox("Are you sure you want to mail merge this document",4,"Mail Merge?")
            If Not answer =6 Then
                  Exit Sub
            End If
      End If
      
     'ask user if they want to save docuemtns as letters
      saveLetter = Messagebox("Do you want to save the letter under the contact?", 4, "Save Letter?")            
      If saveLetter = 6 Then                                                                                                                                  
            letterSubject = Inputbox$("Please enter the letter subject." , "Letter Subject")                                    
            Dim letterDoc As NotesDocument
      End If                                                                                                                                                            
      
     'if the user has selected one or more documents then
      If dc.count > 0 Then
            
          ' set variable as carriage return
            cr = Chr(13) & Chr(10)
            
          ' set variable as first document in the view
            Set doc=dc.GetFirstDocument
            
          ' create an instance of Word  
            Dim wrd As Variant
            Set wrd = CreateObject("word.application")
            
            
 '***************************************************open document window box code
          ' declare temporary strings
            Dim szFileName As String*256
            Dim szTitle As String
            Dim szFilter As String
            
          ' set the strings values
            szFilename = Chr(0)
            szTitle = "Select a Word Document"
            szFilter = "Word Document|*.doc|All Files|*.*|"
            
          'If ok is pressed then save the file name as filepath
            If NEMGetFile( 0, szFileName, szFilter, szTitle) <> 0 Then             'requires function declared in declarations*********************
                  filepath = szFileName
            Else
          'if can't get the filepath then exit sub
                  Exit Sub
            End If
 '**************************************************open document window box code ^
            
          ' open the word document specified by the filepath
            wrd.Documents.Open filepath
            
           ' view document
            wrd.Visible = True
            
          'copy letter from document
            wrd.Run("CopyLetter")
            
         ' for each item in the view create a page and print it
            While Not doc Is Nothing
                  
               ' build letter address
                  LetterAddress = "" 
                  LetterAddress = LetterAddress & cr & cr & cr & cr & cr & cr
                  LetterAddress = LetterAddress & doc.GetItemValue("ModeOfAddress")(0) & cr
                  LetterAddress = LetterAddress & doc.GetItemValue("Company")(0) & cr
                  LetterAddress = LetterAddress & doc.GetItemValue("Address_Line_1")(0) & cr
                  LetterAddress = LetterAddress & doc.GetItemValue("Address_Line_2")(0) & cr
                  LetterAddress = LetterAddress & doc.GetItemValue("Address_Line_3")(0) & cr
                  LetterAddress = LetterAddress & doc.GetItemValue("Address_Line_4")(0) & cr & cr
                  LetterAddress = LetterAddress & Date$
                  
               ' input data into letter template
                  Call wrd.Selection.TypeText(LetterAddress)
                  Call wrd.Selection.TypeText(cr & cr & "Dear " & doc.GetItemValue("Greeting")(0) & ",")
                  
              ' run macro to insert new page
                  wrd.Run("PasteLetter")
                  wrd.Run("NewPage")
                  
               'create letter document under the contact in the database if user wishes
                  If saveLetter = 6 Then
                        
                        Set letterDoc = db.CreateDocument
                        letterDoc.Form = "Letter"
                        Call letterDoc.MakeResponse( doc )
                        
                        letterDoc.Contact = doc.GetItemValue("Contact")(0)
                        letterDoc.Last_Modified = Date
                        letterDoc.LetterDate = Date
                        letterDoc.DocDate = Date
                        letterDoc.Account_Manager = doc.GetItemValue("Account_Manager")(0)
                        letterDoc.ModeOfAddress = doc.GetItemValue("ModeOfAddress")(0)
                        letterDoc.Company = doc.GetItemValue("Company")(0)
                        letterDoc.Address_Line_1 = doc.GetItemValue("Address_Line_1")(0)
                        letterDoc.Address_Line_2 = doc.GetItemValue("Address_Line_2")(0)
                        letterDoc.Address_Line_3 = doc.GetItemValue("Address_Line_3")(0)
                        letterDoc.Address_Line_4 = doc.GetItemValue("Address_Line_4")(0)
                        letterDoc.Subject = letterSubject
                        letterDoc.Greeting = doc.GetItemValue("Greeting")(0)
                        letterDoc.LetterText = GetClipboardContents()
                        letterDoc.DocName = "Letter"
                        
                        Call letterDoc.Save(True, True)
                        
                  End If
                  
               'set variable as next document in the view
                  Set doc = dc.GetNextDocument(doc)
                  
          ' end while loop
            Wend
            
          'delete last page which is empty
            wrd.Run("DeleteLastPage")
            
      Else
            
          'inform user that no contacts were selected
            Messagebox "No contacts were selected"
      End If
      
End Sub
wrd.Run("CopyLetter")
         
       
This is your problem statement.  It would probably not hav any problem if you converted the internal Word macro into more LotusScript.
Avatar of Dev2003

ASKER

sorry qwaletee, explain further...

i cant see how :

wrd.Run("CopyLetter") is the problem!
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial