Renaming form controls and underlying code
You've basically implemented (parts of) a rename refactoring.

The problem is that the VBIDE API only gives you strings to work with, so you essentially have a "smart find &amp; replace", but it's still a find &amp; replace.

A LOT of things can go wrong when processing code without a symbol table.

Imagine a control named MyButton that you want to rename to SomeButton. Then you have this code in the module:

Dim MyButtonForeColor As Long
MyButtonForeColor = vbBlack


Your code will rename MyButtonForeColor too, because it contains MyButton - but did you mean to? In this case, probably.

UserForm controls are Public, so you can have code outside the form that does this:

With New UserForm1
    .Show vbModal
    ActiveSheet.Cells(1, 1) = .SomeTextBox.Text
End With


And that code will break when you rename SomeTextBox to anything else.

Or, you could have conflicting but unambiguous names in different scopes, that a simple find &amp; replace will break:

UserForm1.SomeButton.Caption = UserForm2.SomeButton.Caption


Naming is hard. Renaming is even harder.



Having worked on Rubberduck for over two years, I can assure you that there is absolutely no way to implement any kind of rename refactoring without a symbol table - and that means lexing, parsing and resolving the VBA code you want to refactor.

Ctrl+H isn't a refactoring tool. Rubberduck is. I don't mean to sound like an ad, but your code needs to know exactly which code across the entire project is referencing the control you're renaming - and that simply isn't possible to implement reliably in VBA. Heck, Rubberduck has a proper parser and resolver, and still struggles with a number of edge cases.

I give you this code to play with - it's EVIL beyond words, I know... but it's 100% legal VBA code, and Rubberduck sorts it all out:


'Project Name = MyProject
'Module Name = MyModule
Option Explicit

Private MyVar As MyProject
Private MyVar1 As MyModule

Private Type MyProject
  MyModule As String
  MySub As String
End Type

Private Type MyModule
  MyVar As String
  String As MyProject
End Type

Private Type MySub
  MyVar As MyModule
  MyVar1 As MyProject
End Type

Private Type MyVar
  MyProject As MyModule
End Type

Sub MySub()

  Dim MyProject As MyProject
  Dim MySub As MySub
  Dim MyVar As MyVar

  MyVar.MyProject.MyVar = "Smith"
  MySub.MyVar1.MySub = MyProject.MySub

  'My brain hurts....

End Sub



Your strategy (I know you're only looking at controls, but the principle is the same) will fail to correctly rename MySub here (whichever you pick).

Your code looks great though - good naming, clean code, nice spacing, indentation, casing, a bit large for a single procedure though, but as I said I don't think any of it is relevant, since there's no way any identifier-renaming VBA macro can work [in all cases] simply by looking at context-less strings.