[Public] Sub Auto_Open()
in a standard/procedural module is the old/legacy way to go. Nothing besides its name says "this procedure runs automatically when the workbook is first opened", how it's wired-up to run on open is kind of magic: a public procedure by that name runs on open, and who knows what happens if you have two such procedures in two separate modules. The name isn't standard either: the well-established and rather familiar Interface_Member
convention (with the underscore between the two identifiers) isn't respected here: there's no Auto
object in the Excel object model.
Private Sub Workbook_Open()
is an event handler procedure that handles the Open
event of the Workbook
interface, which ThisWorkbook
implements; like Auto_Open
, it runs when the workbook is opened, however its mechanics are much more transparent, and work exactly like every other event-handling procedure: Workbook
is the interface, Open
is the event/member.
It being a Workbook
event has interesting implications: a workbook that's programmatically opened (from VBA code) will always open with macros enabled - and if that workbook has a Workbook_Open
handler, then that macro will run - however it being an actual event means your calling code can decide to switch it off with Application.EnableEvents = False
.
As for it not running, barring macro security settings the only reason I can think of is if there's a typo in the name. Never type event handler signatures by hand - by using the dropdowns at the top of the code pane, you make the VBE generate the correct event handler signatures for you.
You know you're looking at an event handler procedure when the left-hand-side dropdown contains the name of the object/interface, and the right-hand-side dropdown contains the name of the event/member:

