locked
Run-time error 5941 "The requested member of the collection does not exist" RRS feed

  • Question

  • OKAY... I thought I understood how Watermarks worked, but heres the story.

    There are several missives regarding this issue, mine is similar, but different.  In a protected file which is Read-Only, I want to create a macro that when run, unlocks the password protected document, inserts a "Draft 1" watermark on the header/footer page, then locks back down.  This is being run on Word 2010, System 7  to all users. 

    I noticed when reviewing the code, the 'path' includes my employee number in the path.  It did not do this in 2003 on XP.  I thought by changing this to: %username% in the path, the code would work on any computer it was opened on. 

    First, I ran a macro, recording all the steps to insert the watermark.  Then I edited the code in the editor.  When running the macro, the file does not unlock the file, but rather, inserts a watermark behind the text layer.  It is not placing the watermark on the header/footer as it did when I first recorded the macro, therefore, I cannot select Page Layout-Watermark-Remove Watermark.  If I change my id number in the code to: %username%, it gives me the run-time error 5941 and produces nothing.  Where is this going wrong?  When I debug the code, nothing comes up

    If ActiveDocument.ProtectionType <> wdNoProtection Then
        ActiveDocument.Unprotect Password:="password"
        Application.Templates( _
            "C:\Users\emp_no or %username%\AppData\Roaming\Microsoft\Document Building Blocks\1033\14\Built-In Building Blocks.dotx" _
            ).BuildingBlockEntries("DRAFT 1").Insert Where:=Selection.Range, RichText _
            :=True
        ActiveDocument.Protect wdAllowOnlyReading, False, Password:="passsword"

    End If

    End Sub

    Thursday, July 11, 2013 10:30 PM

Answers

  • Hi Lenny

    I think there are two issues, here. One is, where the code should find the building blocks template, the other, where the building block is inserted.

    For the one, it might make sense to do a For Each loop of the templates collection, looking for a template with the correct Name. Something like this, perhaps:

    Dim tmpl as Word.Template
    For Each tmpl in Application.Templates
      If Instr(tmpl.FullName, "Built-In Building Blocks.docx") <> 0 Then
        Exit For
      End If
    Next
    tmpl.BuildingBlockEntries("DRAFT 1")").Insert Where:=Selection.Range, RichText _
            :=True

    The other problem is that you're telling Word to insert the Building Block at the current Selection. Apparently, that is not in the Header/Footer of the document. Generally, it's better to not rely on the Selection being in the right place. Instead, you should specify an exact RANGE. Perhaps:

    Dim rngTarget As Word.Range
    Set rngTarget = ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Range

    And then:

    tmpl.BuildingBlockEntries("DRAFT 1")").Insert Where:=rngTarget, RichText _
            :=True

    If you have any code that activates ("seeks") the headers/footers comment that out as it's not necessary when working with a Range.


    Cindy Meister, VSTO/Word MVP, my blog

    • Marked as answer by Damon Zheng Tuesday, July 23, 2013 7:09 AM
    Friday, July 12, 2013 11:19 AM
  • H Lenny,

    Instead of hard coding the full path to the user's roaming directory you might consider using:

    Environ("APPDATA")

    That is of course is you are running the macro from the logged in user account.

    Before inserting a new watermark you should make sure that one doesn't already exist, otherwise you will build up successively stacked watermarks in the document. Here is sample code that I lifted from on of my apps. It looks for custom watermarks by document section and that might not be something you need to do, and instead just use the primary range as Cindy has indicated. Also if no shape exists this code will error out, so you either have to suppress error checking (resume next) or include a check for shapes count.

        Sub RemoveWatermarks(ByRef wApp As Word.Application, ByRef Doc As Word.Document)
            Dim scn As Word.Section, hdft As Word.HeaderFooter, shp As Word.shape
            On Error Resume Next
                With Doc
                    For Each scn In .Sections
                        For Each hdft In scn.Headers
                            For Each shp In hdft.Shapes
                                If shp.TextEffect.Text = "Evaluation Only" Then
                                    shp.Delete
                                End If
                            Next
                        Next
                    Next
                End With
    
        End Sub
    


    Kind Regards, Rich ... http://greatcirclelearning.com

    • Marked as answer by Damon Zheng Tuesday, July 23, 2013 7:10 AM
    Friday, July 12, 2013 1:07 PM

All replies

  • Hi Lenny

    I think there are two issues, here. One is, where the code should find the building blocks template, the other, where the building block is inserted.

    For the one, it might make sense to do a For Each loop of the templates collection, looking for a template with the correct Name. Something like this, perhaps:

    Dim tmpl as Word.Template
    For Each tmpl in Application.Templates
      If Instr(tmpl.FullName, "Built-In Building Blocks.docx") <> 0 Then
        Exit For
      End If
    Next
    tmpl.BuildingBlockEntries("DRAFT 1")").Insert Where:=Selection.Range, RichText _
            :=True

    The other problem is that you're telling Word to insert the Building Block at the current Selection. Apparently, that is not in the Header/Footer of the document. Generally, it's better to not rely on the Selection being in the right place. Instead, you should specify an exact RANGE. Perhaps:

    Dim rngTarget As Word.Range
    Set rngTarget = ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Range

    And then:

    tmpl.BuildingBlockEntries("DRAFT 1")").Insert Where:=rngTarget, RichText _
            :=True

    If you have any code that activates ("seeks") the headers/footers comment that out as it's not necessary when working with a Range.


    Cindy Meister, VSTO/Word MVP, my blog

    • Marked as answer by Damon Zheng Tuesday, July 23, 2013 7:09 AM
    Friday, July 12, 2013 11:19 AM
  • H Lenny,

    Instead of hard coding the full path to the user's roaming directory you might consider using:

    Environ("APPDATA")

    That is of course is you are running the macro from the logged in user account.

    Before inserting a new watermark you should make sure that one doesn't already exist, otherwise you will build up successively stacked watermarks in the document. Here is sample code that I lifted from on of my apps. It looks for custom watermarks by document section and that might not be something you need to do, and instead just use the primary range as Cindy has indicated. Also if no shape exists this code will error out, so you either have to suppress error checking (resume next) or include a check for shapes count.

        Sub RemoveWatermarks(ByRef wApp As Word.Application, ByRef Doc As Word.Document)
            Dim scn As Word.Section, hdft As Word.HeaderFooter, shp As Word.shape
            On Error Resume Next
                With Doc
                    For Each scn In .Sections
                        For Each hdft In scn.Headers
                            For Each shp In hdft.Shapes
                                If shp.TextEffect.Text = "Evaluation Only" Then
                                    shp.Delete
                                End If
                            Next
                        Next
                    Next
                End With
    
        End Sub
    


    Kind Regards, Rich ... http://greatcirclelearning.com

    • Marked as answer by Damon Zheng Tuesday, July 23, 2013 7:10 AM
    Friday, July 12, 2013 1:07 PM