'VBA macro code not executing on workbook opening

I have VBA macro code that is supposed to execute on opening a workbook but the vbaproject password prevents the code executing. My understanding is than a macro protection password prevents viewing and editing the code, and should not prevent execution.

I suspect the problem is that the code makes use of 'Extensibility 5.3' to list all the procedures in the code base, as turning off password protection allows execution on workbook open

I would be grateful for any advice on how to password protect the code and still ensure that code using extensibility features still executes

I think i need a way to unprotect the vbaproject by supplying the password programmatically

Code ends with VBA Excel - Run-time Error 50289

Function genHashesAndStore(ByVal nameCol As Integer, ByVal hashCol As Integer) As Integer

Dim VBAProj As VBIDE.VBProject
Dim VBAComp As VBIDE.VBComponent
Dim VBAProc As VBIDE.CodeModule
Dim procKind As VBIDE.vbext_ProcKind
Dim modName As String
Dim ProcName, procHash As String
Dim concatLines As String
Dim index As Long
Dim wsModuleHashRow, count, noOfLines As Integer
Dim noOfProcNames, noOfProcHashes As Integer
Dim process As Boolean

 
wsModuleHashRow = firstDataRow
genHashesAndStore = 0

'On openning and closing, calculate each module procedures hash
Set VBAProj = ActiveWorkbook.VBProject
With Worksheets("Module Hashes")
    For Each VBAComp In VBAProj.VBComponents
        Set VBAProc = VBAComp.CodeModule
        'Process decision
        Select Case VBAComp.Type
        Case vbext_ct_StdModule
            'Subroutines and Functions
            modName = VBAComp.Name
            process = True
        Case vbext_ct_Document
            'Exceptions list
            process = False
            If VBAComp.Name = "ThisWorkbook" Then                   'Object:    "ThisWorkbook"
                modName = VBAComp.Name
                process = True
            End If
            If VBAComp.Name = "Sheet8" Then                         'Worksheet: "Setup & User Guide"
                modName = ThisWorkbook.Worksheets(3).Name           'Worksheet position: DO NOT CHANGE
                process = True
            End If
            'add exception, If...
        Case Else
            'Excluded: userforms and class modules, not used
            process = False
        End Select

        If process Then
            'Module or Object declaration lines (module/object or project scope declarations)
            concatLines = vbNullString
            noOfLines = 0
            index = VBAProc.CountOfDeclarationLines + 1
            'Start count at 1: No procedure declaration line for an Object/document type
            'End count at (index-1) because index points to the start of the first procedure
            For count = 1 To index - 1
                'Do not include empty/spaceing lines or commnet lines in the hash
                If Not (VBAProc.Lines(count, 1) = vbNullString Or _
                        Left(LTrim(VBAProc.Lines(count, 1)), 1) = "'") Then
                    concatLines = concatLines & VBAProc.Lines(count, 1)
                    noOfLines = noOfLines + 1
                End If
            Next count
            If Len(concatLines) > 0 Then
                procHash = stringToMD5Hex(concatLines)
            Else
                procHash = "No declaration section"
            End If
            'Write the declaration name and hash
            'Debug.Print concatLines
            .Cells(wsModuleHashRow, nameCol).Value = modName & ".Dec"
                                                    'procKindIs(procKind)
                                                    '"(" & noOfLines & ")"
            .Cells(wsModuleHashRow, hashCol).Value = procHash
            wsModuleHashRow = wsModuleHashRow + 1
            
            'Procedure lines, combine declaration and code lines
            Do While index < VBAComp.CodeModule.CountOfLines
                ProcName = VBAProc.ProcOfLine(index, procKind)
                'Debug.Print modName & "." & procName
                index = VBAProc.ProcStartLine(ProcName, procKind) + VBAProc.ProcCountLines(ProcName, procKind)
                concatLines = vbNullString
                noOfLines = 0
                'Start count at (...+1), don't include the procedure decalarion line in the hash:
                '                        allows for procedure renaming to be identified
                'End count at (index-1) because index points to the start of the next procedure
                'End count at (index-1)
                For count = VBAProc.ProcStartLine(ProcName, procKind) + 1 To index - 1
                    '
                    If Not (VBAProc.Lines(count, 1) = vbNullString Or _
                            Left(LTrim(VBAProc.Lines(count, 1)), 1) = "'") Then
                        concatLines = concatLines & VBAProc.Lines(count, 1)
                        noOfLines = noOfLines + 1
                    End If
                Next count
                If noOfLines > 1 Then
                    'Procedure has at least one line of code and "End Sub/Function"
                    'Don't hash procedure declaration line Sub/Function name(...) [As ...]
                    'Greater than one (>1) ensures at least 2 or more lines
                    procHash = stringToMD5Hex(concatLines)
                Else
                    'Set warning: Nothing to hash, empty procedure (maybe a place holder?)
                    genHashesAndStore = 1
                    procHash = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                End If
                'Write the procedure name and hash
                'Debug.Print concatLines
                .Cells(wsModuleHashRow, nameCol).Value = modName & "." & ProcName
                                                        'procKindIs(procKind)
                                                        '"(" & noOfLines & ")"
                .Cells(wsModuleHashRow, hashCol).Value = procHash
                wsModuleHashRow = wsModuleHashRow + 1
            Loop
        Else
            'Not processed, skip to next VBAComp
        End If
    Next VBAComp

    'Verify procedure names and hashes have been generated and written
    noOfProcNames = getLastUsedRow(.Name, nameCol)
    noOfProcHashes = getLastUsedRow(.Name, hashCol)
    If noOfProcNames <> noOfProcHashes Then GoTo errorHandlerLabel
    If noOfProcNames < firstDataRow Then GoTo errorHandlerLabel
    If noOfProcHashes < firstDataRow Then GoTo errorHandlerLabel
End With

'Skip error handling
Set VBAProj = Nothing
Set VBAProc = Nothing
Exit Function

'Error handlig errorHandlerLabel: 'Set error: Nothing generated or written. Automated Version Control will not proces code-base changes genHashesAndStore = 2 Set VBAProj = Nothing Set VBAProc = Nothing Exit Function

End Function



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source