Automatically Run VBA Code when an Excel Workbook Opens - excel

I have VBA code in I would like to run when the Excel workbook is opened.
I tried creating a public procedure in the sheet the code is supposed to run in:
Public Sub Workbook_Open
' Some code here
End Sub
It does not run when the workbook opens.
It is supposed to create a combobox in one of the cells and then fill it with information from the database.

Make sure that the code is in the ThisWorkbook scope of the VBA editor and not in a module or worksheet:
Option Explicit
Private Sub Workbook_Open()
MsgBox "Autorun works!"
'your code here
End Sub
And make sure that your macros are enabled.
For details also see Microsoft's documentation: Automatically run a macro when opening a workbook.

Adding to #Pᴇʜ's answer, you can also use the following procedure in standard module:
Sub Auto_Open()
'// Your code here...
End Sub

You are trying to create an event procedure that activates when you open a book. Go to thisworkbook in the VBA editor and choose workbook open procedure from the drop down list above the coding window, or you can type manually:
Private Sub Workbook_Open()
End Sub

Related

Trigger a VBA Macro on any opened workbook and sheets with following code

I am using the following code to highlight spelling mistakes in the cell-on-cell change
Sub ColorMispelledCells()
For Each cl In ActiveSheet.UsedRange
If Not Application.CheckSpelling(Word:=cl.Text) Then _
cl.Interior.ColorIndex = 15
Next cl
End Sub
Now, the problem is that every time I have to run this code by pressing f5 and also this only works on a particular workbook (Workbook specific).
So, my question is, what is the process to make a universal/global macro that runs on every workbook and every sheet which is opened, and that too runs internally when the cell is changed? It should not open up with the VBA editor window again and again.
Along with this is there any way where I can make a enable and disable button highlighted on the excel toolbar for this macro?
see image to see my VBA editor project explorer hierarchy
I tried searching on the internet and also saw many sample codes but nob body explained to make a global/universal macro, I am unable to figure out how to develop a global/universal macro that runs automatically on cell changes. which is not bounded to any one workbook but works globally on any opened workbook on all sheets.
I'm interested in your case. I myself is not an expert, so just now I search the internet and playing around and try to "cheat" by making this kind of code - which I'm not so sure if that meets your requirement.
In PERSONAL.XLSB workbook - ThisWorkbook module :
Private WithEvents app As Application
Private Sub app_WorkbookOpen(ByVal Wb As Workbook)
On Error Resume Next
If Wb.Name <> "PERSONAL.XLSB" Then
Set src = Workbooks("PERSONAL.XLSB").VBProject.VBComponents("Sheet1").CodeModule
Set trg = Wb.VBProject.VBComponents("ThisWorkbook").CodeModule
trg.insertlines 1, src.Lines(1, src.countoflines)
End If
End Sub
Private Sub Workbook_Open()
Set app = Application
End Sub
In PERSONAL.XLSB workbook - Sheet1 module :
Private Sub Workbook_SheetChange(ByVal sh As Object, ByVal Target As Range)
If Not Application.CheckSpelling(Word:=Target.Text) Then _
Target.Interior.ColorIndex = 15 Else Target.Interior.ColorIndex = xlNone
End Sub
Source code from this link and this link
The sub in "ThisWorkbook" module of PERSONAL.XLSB will be triggered when opening any workbook. The sub will copy the macro in "Sheet1" module of PERSONAL.XLSB into "ThisWorkbook" module of the open workbook.
The sub in "Sheet1" module of PERSONAL.XLSB is an event handler to any sheet of the active workbook which will be triggered if there is a change on any cell of any sheet.
I noticed that if I edit the sub in the PERSONAL.XLSB to something else, then I open another workbook, the sub will not run. I need to close the Excel application first, then open it again. If I don't do any sub-editing, opening other workbook will trigger the sub to run.
The animation above is opening two xlsx workbook which for sure there can't be any code in that workbook. But because at the time it's opened the macro in PERSONAL.xlsb is triggered (copying a sub to "ThisWorkbook" module of that xlsx workbook), so then there is a sub in that xlsx workbook. If I close this xlsx workbook, it will prompt me if I want to save the workbook. If I click yes, it will complain because it can't be saved as xlsx while there is a macro in "ThisWorkbook" module of this workbook.
Still not sure though if this is the kind that you want. Also maybe what you want is something like this : in whatever computer which has Excel app, it can do the same thing without doing anything before hand. So it's not doable, because to any computer which has Excel app, the macro need to be copied to PERSONAL.XLSB on each computer before hand.
Please note, I don't test to open an xlsm workbook which already has Private Sub Workbook_SheetChange(ByVal sh As Object, ByVal Target As Range) in it's "ThisWorkbook" module. And I think most likely it will throw an error if the opened workbook has already Private Sub Workbook_SheetChange(ByVal sh As Object, ByVal Target As Range) in it's "ThisWorkbook" module

Calling a macro when selecting a chart sheet

I'm using the following simple code to run a macro "mymacro" when clicking/selecting a sheet.
Private Sub Worksheet_Activate()
Call mymacro
End sub
When i execute the macro manually it's working very well but when i click on the sheet it is not.
Basically i'm using the macro to change a chart colors...so when i apply this to a normal sheet where i have a chart as object it's working but when i tried with a sheet where there is only a chart (created by using "Move Chart" on new sheet option) nothing happens
Thank you for the help
The name needs to be Private Sub Chart_Activate() since it is a Chart and not a Worksheet. As VBasic2008 pointed out, the code needs to be in the code module for the Chart. Press Alt+F11 to open the VB Project, CRTL+R to open the Project Explorer. Double click on the Chart, eg.Chart1.
Your code module should look like :
Private Sub Chart_Activate()
Call mymacro
End Sub
Ensure that mymacro is Public or is also in this code module.

Workbook_Open() does not work with Workbook Protection

I am using Excel 2016 and have this code written in the ThisWorkbook object in VBA:
Private Sub Workbook_Open()
ThisWorkbook.Protect (password = "password")
End Sub
It is not working. The point here is that this should prevent users from touching the Power Query functions in this workbook. I have saved it as a Macro-enabled workbook, I have all macros and events enabled and this is the only workbook open.
I also have this additional code:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Protect (password = "password")
ThisWorkbook.Save
End Sub
And that is not working either. It works fine if I insert that "ThisWorkbook.Protect" code into a general module or worksheet object and run it manually, but when I want this particular excel file to run this code automatically on open or close, it does not do it.
Any ideas what could be causing this?
For some reason running ThisWorkbook.Protect on a protected workbook seems to unprotect it (even though I couldn't find any documentation that says that it does this) so try this:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If Not ThisWorkbook.ProtectStructure Then ThisWorkbook.Protect Password:="password"
ThisWorkbook.Save
End Sub
In order for automatically-running subroutines to work correctly in Microsoft Excel, they must be contained within a Visual Basic module.
If an Auto_Open, Auto_Close, or other automatically-running subroutine is stored "behind" a worksheet or ThisWorkbook, it may not function correctly when you open or close your workbook, or when you perform an action that should cause the subroutine to run.
MS Topic Discussion - Code "Behind" a Workbook

Excel vba - How to refer to workbook builtin document properties in excel VBA?

I am building a macro workbook in which ctl+D is deactivated.
Now, the issue is - When another workbook is opened when this macro workbook is still open, ctl+D is getting disabled in the other workbook as well, as this is an application level setting. I want to restrict disabling ctl+D only in the macro workbook.
For this, I can add a condition in the code which checks for the workbook name before disabling ctl+D. But, there is 90% chance that users would change the name of the workbook after saving to their desktop.
Is there a way I can use Workbook builtin properties instead of workbook name in code? Please advise.
Thank you!
https://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.workbook.builtindocumentproperties.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
Example (Pseudo code):
if ThisWorkbook.Title = 'TEST' Then
Application.OnKey "^d", ""
end if
Use workbook events to detect when the workbook is activated or not.
Private Sub Workbook_Activate()
Application.OnKey "^d", ""
End Sub
Private Sub Workbook_Deactivate()
Application.OnKey "^d"
End Sub
Put this in the ThisWorkbook module. You might also want to add the Ctrl+d deactivation line to a Workbook_Open event.

Attach Existing UserForm Button to Excel Workbook Sheet

I have an Excel workbook that has a macro (the only macro in the workbook) attached to a button on a sheet.
In VB mode, I created a UserForm under Forms with a CommandButton1_Click Sub and when run from within VB (Run > Run Sub/UserForm or F5) it runs fine. I have it calling a Shell command that runs a BAT file that runs a Python script.
How do I run CommandButton1_Click from a button on a sheet? If I try to add a button to a sheet, it offers me the macro I have already associated with the other button.
Create one macro for example
Sub ShowForm
YourForm.show
End Sub
And associate this macro in button.
Why don't you move the main code into a new macro to modularise it. You can then call your macro via both UserForm and worksheet ActiveX (or Forms) buttons
'Normal Code Module
Sub TestCode()
MsgBox "Hi"
End Sub
'UserForm code
Private Sub CommandButton1_Click()
Call TestCode
End Sub
'ActiveX button code
Private Sub CommandButton1_Click()
Call TestCode
End Sub

Resources