Running vba code whenever a workbook is opened - vba

I'm writing vba which manipulates data within a worksheet however I'm trying to make it run whenever a workbook is opened.
The problem I'm having is that due to the workbook (that the code needs to run on) is different/new every time, I need the auto_open code to be within a personal macro workbook.
Sub Auto_Open()
Dim bookname As String
Dim checkbook As String
Dim Workbook As Workbook
For Each Workbook In Application.Workbooks
bookname = Workbook.Name
checkbook = Left(bookname, 3)
If checkbook = "EDN" Then
Data_generator
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Application.Quit
Else
End If
Next Workbook
End Sub
When this code runs it checks all open workbooks and sees if the first 3 letters of it are 'EDN', if it is then run the public sub called 'Data_generator', save it and quit. If it isn't check the next open workbook, etc.
When a file is opened from windows explorer, excel launches (with both the desired workbook and the personal macro workbook) however because excel opens the personal macro workbook first and runs the code before opening the desired workbook it doesn't find a workbook called 'EDN'.
If the above code is ran after both workbooks have opened then the code works as intended and cycles through each open workbook to see if there's one called 'EDN' (this was proved by putting a messagebox after the 'then' and running the code), if so run the sub.
I've proved this by putting a messagebox after the 'else', when this is done it displays the messagebox with the workbook I want, not open. After the message box is cleared, the workbook then opens.
Is there any way to make the desired workbook open first or any other work around for this?

You can create an Add-in that runs whenever a workbook is open
https://msdn.microsoft.com/en-us/library/office/gg597509(v=office.14).aspx
this tool may help to create the Add in http://www.andypope.info/vba/ribboneditor.htm

You should be able to use the Application.OnWindow event to trigger a macro when a file is opened or closed.
In ThisWorkbook
Private Sub Workbook_Open()
Call StartTracking
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call StopTracking
End Sub
In a Module
Function StartTracking()
Application.OnWindow = "AutoRunOnWindowChange"
End Function
Function StopTracking()
Application.OnWindow = ""
End Function
Function AutoRunOnWindowChange()
If Left(ActiveWorkbook.Name, 3) = "EDN" Then
Call Data_generator
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Application.Quit
End If
End Function

Related

How can I tell which workbook triggered an event?

I have a BeforeClose event in a workbook, however if the user closes the workbook when it is not the active workbook, e.g. from the taskbar, the script executes on the wrong workbook.
Is there a way to tell which workbook triggered the event and reference that workbook rather than ActiveWorkbook?
Private Sub Workbook_BeforeClose(Cancel As Boolean)
' Replaces default Save message box with custom one
' that includes request stats, warnings, and errors.
If Not ActiveWorkbook.Saved Then
UF_Stats.Show
If Not GlobalVariables.bAllowClose Then Cancel = True
End If
End Sub
Use ThisWorkbook instead of ActiveWorkbook – Vincent G

Adding security to my workbook internally using VBA

For testing purposes lets assume the code to unlock the workbook is 1.
I want an input box to show up on opening, if the user puts in an incorrect code/Or selects cancel on the input box then the workbook closes.
Private Sub Workbook_Open()
ActiveSheet.Range("A1").Activate
Code = Application.InputBox("Enter School Code", CancelCode)
If Code < 0 > 1 Or False Then
Code = Int(1)
MsgBox ("Unrecognised Code")
Application.Workbooks("CODING.xlsm").Close 'False
End If
End Sub
At the moment it appears but runs if any number is entered and also closes the input box and allows access if cancel is clicked.
Try this:
Private Sub Workbook_Open()
Dim Code As Variant
Code = Application.InputBox("Enter School Code", CancelCode)
If Not Code = 1 Then
MsgBox ("Unrecognised Code")
ThisWorkbook.Close SaveChanges:=False
End If
End Sub
Just tested it and it works for me.
I should add, however, that this is extremely low-level security, which could be bypassed by anyone with even rudimentary knowledge of VBA. You simply have to set Application.EnableEvents = False in another workbook (or in the VBA Immediate window) before opening up your workbook, and the Workbook_Open event will not run at all.

Error with ActiveWorkbook Path VBA macro Excel 2013?

i want to create a vba macro for excel 2013. this vba macro must be available for all excel files, i make a search in the internet and i found that i must put the code in Excel add-in, so i try to make a code for event opening of excel; the code is the following:
Private Sub Workbook_Open()
If (ActiveWorkbook.Path = "C:\GED\TEMP") Then
MsgBox "Hello"
End If
End Sub
the problem is that when i open excel file, vba dont know the active workbook because it opens the file in XLSTART first then my current file, so i have the following error:Run-time error '91 ': Object variable or With block variable not set. So any idea please; i should check the path of the workbook at the opening
You'll need Application-level events to trap the opening of any workbook. Replace your code with this:
Option Explicit
Private WithEvents app As Excel.Application
Private Sub app_WorkbookOpen(ByVal Wb As Workbook)
If UCase$(Wb.Path) = "C:\GED\TEMP" Then MsgBox "Hello"
End Sub
Private Sub Workbook_Open()
Set app = Application
End Sub

How to get Excel to require user to allow macro else cannot open workbook?

I have a macro in my Excel file that is meant to determine whether a user can open it or not. However, it seems like, depending on the settings of the user's machine, Excel by default disables the macro. This ended up opening and revealing the contents in the xls file.
How can I make sure that the user has to accept running the macro or Excel will close the workbook?
UPDATED the code as it was not doing exactly what it was meant to...
This is pretty much the only way you can do this WITH a macro (thanks to #OlleSjögren for the insight :p)
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim Current As Worksheet
Worksheets.Add(Before:=Worksheets(1)).Name = "Protection"
Worksheets("Protection").Cells(1, 1) = "Please activate macros to view this workbook."
For Each Current In Worksheets
If Current.Name <> "Protection" Then
Current.Visible = xlSheetVeryHidden
End If
Next Current
End Sub
Private Sub Workbook_Open()
Dim Current As Worksheet
For Each Current In Worksheets
Current.Visible = xlSheetVisible
Next Current
Application.DisplayAlerts = False
Worksheets("Protection").Delete
Application.DisplayAlerts = True
End Sub
The property xlSheetVeryHidden means that it cannot be made visible through the UI (VBA code only can change it).
I think you can't do it. But we can make a workaround.
First of all you need to hide all your worksheet and prevent user to unhide it. Link. Following the link you will see that you can make a sheet veryHidden. As the link shows, you need to add a password to vba code too.
Then you can to create a macro that adds an InputBox with password
Sub CheckPassword()
Dim password As String
password = InputBox("Enter the password") 'You can use a Form with Textbox [PasswordChar] to put ****
If password = "myPass" Then
Sheets(3).Visible = xlSheetVisible
Sheets(3).Select
End If
End Sub
Finally you can attach a sub in the close event.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Sheets(3).Visible = xlSheetVeryHidden
End Sub

Open a workbook (mode automatic) by VBA command without recalculating it

In my VBA addin.xlam, I use workbooks.Open("C:\f.xlsm") to open workbook f.xlsm. The workbook calculation mode of f.xlsm is Automatic, thus I realize that everything in f.xlsm is recalculated automatically, after calling workbooks.Open("C:\f.xlsm"). But this is not what I want.
Is it possible to open a workbook by VBA command without refreshing it, even though the mode of the workbook is Automatic?
Edit 1:
I tried the idea #Ripster suggested:
1) I created a class model CExcelEvents in addin.xlam:
Private WithEvents App As Application
Private Sub App_WorkbookOpen(ByVal Wb As Workbook)
Application.Calculation = xlCalculationManual
End Sub
Private Sub Class_Initialize()
Set App = Application
End Sub
2) I linked CExcelEvents to the code in addin.xlam which opens f.xlsm:
Private XLApp As CExcelEvents
Sub try()
Set XLApp = New CExcelEvents
workbooks.Open ("C:\f.xlsm")
End Sub
Then, what try() does turns out to be first opening f.xlsm (which triggers automatic recalculation), then changing its calculation mode to manual. The workbook has been already re-calculated before changing the mode --- it is too late! Does anyone have any idea?
Try setting XLCalculation to Manual immediately before you open the workbook:
Sub try()
Application.Calculation = xlCalculationManual
workbooks.Open ("C:\f.xlsm")
End Sub