Posting another answer structured as generalized tools to delete and/or add or replace any number of procedures from any number of files. As mentioned earlier it is assumed that Trust Access to Visual Basics Project must be enabled.
In a new excel file with added reference to Microsoft Visual Basic for Application extensibility, add a module named “Copy_Module”. Specifically in your case, copy Worksheet_SelectionChange
code in a module named “Copy_Module”.
Its AddReplaceProc
function would copy any procedure from a module named “Copy_Module” in the source workbook while DeleteProc
function would delete a procedure.
Sub test4()
Dim Wb As Workbook, ws As Worksheet
Dim Path As String, Fname As String
Dim Fno As Long
Path = "C:\Users\User\Documents\TestFolder\"
Fname = Dir(Path & "*.xlsm")
Fno = 1
Do While Fname <> ""
Set Wb = Application.Workbooks.Open(Path & Fname)
If Wb.VBProject.Protection = vbext_pp_none Then
Set ws = ThisWorkbook.ActiveSheet
Fno = Fno + 1
ws.Cells(Fno, 1).Value = Fname
'ws.Cells(Fno, 2).Value = AddReplaceProc(Wb, "ArchiveHistoricalData", "DoStuff2")
ws.Cells(Fno, 2).Value = DeleteProc(Wb, "ArchiveHistoricalData", "Auto_Open")
ws.Cells(Fno, 3).Value = AddReplaceProc(Wb, Wb.Worksheets("Data Dump").CodeName, "Worksheet_SelectionChange")
Wb.Close True
Else
Wb.Close False
End If
Fname = Dir
Loop
End Sub
Private Function DeleteProc(Wb As Workbook, CompName As String, ProcName As String) As Boolean
Dim Vbc As CodeModule, Vbcomp As VBComponent
DeleteProc = False
For Each Vbcomp In Wb.VBProject.VBComponents
If Vbcomp.Name = CompName Then
Set Vbc = Vbcomp.CodeModule
On Error GoTo XExit
If Vbc.ProcStartLine(ProcName, 0) > 0 Then
Vbc.DeleteLines Vbc.ProcStartLine(ProcName, 0), Vbc.ProcCountLines(ProcName, 0)
DeleteProc = True
Exit For
End If
End If
Next Vbcomp
XExit: On Error GoTo 0
End Function
Private Function AddReplaceProc(Wb As Workbook, CompName As String, ProcName As String) As Boolean
Dim Vbc As CodeModule, Vbcomp As VBComponent
Dim VbcSrc As CodeModule, StLine As Long, EndLine As Long
Dim i As Long, X As Long
'Check for older version of the procedure and delete the same before coping new version
AddReplaceProc = DeleteProc(Wb, CompName, ProcName)
Debug.Print "Old Proc " & ProcName & " Found and Deleted : " & AddReplaceProc
AddReplaceProc = False
For Each Vbcomp In Wb.VBProject.VBComponents
If Vbcomp.Name = CompName Then
Set Vbc = Vbcomp.CodeModule
Set VbcSrc = ThisWorkbook.VBProject.VBComponents("Copy_Module").CodeModule
StLine = VbcSrc.ProcStartLine(ProcName, 0)
EndLine = StLine + VbcSrc.ProcCountLines(ProcName, 0) - 1
X = 0
For i = StLine To EndLine
X = X + 1
Vbc.InsertLines X, VbcSrc.Lines(i, 1)
Next i
AddReplaceProc = True
Exit For
End If
Next Vbcomp
End Function
Proper caution is a must for this type of remote changes. It is always wise to try the code first only to copies of target files and confirm proper working etc.
It only works with files with unprotected VBA projects. For files with protected VBA files refer SO post Unprotect VBProject from VB code.