I work with a a group of six interlinked Excel workbooks that all feed into one summary/reporting workbook (let's call it "Main Report.xlsm").
Since the various workbooks are updated with new information throughout the day as it comes to hand, they need to be saved regularly throughout the day. I have therefore created a simple VBA macro that saves all open workbooks at the press of a button, which I have located as on object on Sheet1 of MainReport.xlsm. The macro works OK and saves all open workbooks as expected, however two aspects of the code are not working as expected:
No matter where I insert ScrenUpdating = FALSE, Excel still displays each workbook on the screen as it saves it. I don't want that because it slows down the save process, plus it looks weird as the macro toggels through each open workbook and the workbooks flash up momentarily on the screen. Since I activate the save macro from Main Report.xlsm, I want the screen to freeze on that workbook whilst Excel saves all open workbooks as a 'background' process. Can anyone tell me how I can make ScreenUpdating work properly with this code?
At the end the macro is supposed to select the 'Main Report.xlsm' workbook, but instead of activating that workbook, Excel seems to get stuck on displaying the second-last workbook in the group of six open workbooks. If I test the code by stepping through it, it seems to work OK, but when I run it from the assigned button on Main Report.xlsm, it does not work. Why would this be happening?
Here is my simple 'SaveAll' macro VBA code:
Sub SaveAll()
Application.ScreenUpdating = False
Dim Wkb As Workbook
Application.Calculate
For Each Wkb In Workbooks
If Not Wkb.ReadOnly And Windows(Wkb.Name).Visible Then
Wkb.Save
End If
Next
Application.Workbooks("Main Report.xlsm").Activate
ActiveWorkbook.Worksheets("Sheet1").Select
ActiveSheet.Range("C4").Select
Application.ScreenUpdating = True
End Sub
Can anyone spot what I am doing wrong?
I am trying to provide an option to my users to save and close excel application after they finish to complete a specific form. However, it is closing the whole Excel and not only the current Excel workbook that they just used. In other words, if they have 4 different Excel files opened, it will close all of them and not only the current workbook. What am I doing wrong?
This is the code that I am using:
ThisWorkbook.Application.Quit
ThisWorkbook.Save
You must not quit the Application - but close the workbook:
ThisWorkbook.Close SaveChanges:=True
will save and close the workbook.
If it is the only open workbook, Excel gets closed as well.
If not Excel and the other workbooks are still open.
What is the best way of protecting a specific Excel workbook?
I have an inherited script that includes the following common lines at the end:
ActiveSheet.Protect "my-password"
ActiveWorkbook.Protect "my-password"
However, I've noticed that as the script can take a few minutes to run users often switch to a new unrelated workbook whilst it solves - whatever else they are working on. The password protection is then inherited by the unrelated workbook upon the completion of the macro - since whatever other Excel file the user is working within is now "Active" (presumably? this is my reading of the problem).
The above script is in a workbook that can be renamed to whatever the user chooses, and be saved in any number of directories. How can I ensure that only the original excel file is locked/unlocked by the Macro, when other workbooks are in use?
I am sure there are many ways to do this, but which is the most foolproof method?
NOTE: using office 365
Thanks Dean's answers in the comments:
Early in the code (and in Worksheet_Change if appropriate) enter the following to define your sheet as an object (named default_ws in my case):
Set default_ws = ActiveSheet
When you are ready to lock your sheet or workbook you can then use:
default_ws.Protect "password-here" 'protect your sheet
ThisWorkbook.Protect "password-here" 'protect your workbook
Also note:
You could also define your workbook as an object as follows if desired:
Set default_wb = ActiveWorkbook
Excel 2016 (or 365) does not seem to fire the Workbook_Open() sub reliably or more precisely, not at all!
The simple event sub
Private Sub Workbook_Open()
MsgBox "Work book is open"
End Sub
does not seem to work. However, if a workbook is already open and then the workbook containing the above Sub is then opened, it does run as expected.
I notice that unlike Excel 2010, 2016 (365) opens each workbook in its own window, not a workbook window in the Excel application window. Is this a bug in 2016 and is there a workaround?
I have produced a work around for my own applications and that is call the activation of a worksheet and call my initialization routines from there. But a bit "rough" and it would be good to have the Workbook_Open() sub working correctly.
It is a simple single Sub in the ThisWorkbook module. Macros are enabled. In Excel 2010 it works perfectly, as do two other macros in other workbooks for which I have written macros. It is just this one thing with Excel 2016. Given that the Workbook_Open() sub is the gateway to a workbook it seems a little strange that we have to go to a workaround to make it function.
Try encapsulating the call with a new instance of Excel. Example below:
Sub OpenInNewExcel()
Dim Background_Excel As Excel.Application
Dim pathName As String
Dim fileName As String
Let pathName = "Enter your path here" 'include "\" at the end
Let fileName = "Enter your file name here"
Background_Excel.Workbooks.Open fileName:=pathName & fileName
Background_Excel.Parent.Quit ' This is how you close the file completely using VBA otherwise the file will close and the Excel Shell will remain.
End Sub
Also make sure that enable macros is turned on in the Options-Trust Center.
You have to add the file/folder location of your workbook as a "Trusted Location".
You can see more info about that in Designate trusted locations for files in Office 2016.
I have same problem then I found solution after google it:
https://www.myonlinetraininghub.com/excel-forum/vba-macros/excel-2016-workbook_open-event-doesnt-trigger
Then I also use "Private Sub Workbook_Open()" and "Public Sub Auto_Open()" open in excel 2016 that work fine:
Private Sub Workbook_Open()
CustomStartUp
End Sub
Public Sub Auto_Open()
CustomStartUp
End Sub
Private Sub CustomStartUp()
MsgBox "Work book is open"
End Sub
I've had this problem (I'm using Microsoft 365), and I found this thread.
It happens for me sometimes when I have another workbook already open, then, on trying to open my macro-enabled workbook, before any sheet is displayed I get the Microsoft warning message about macros. Then, although I click its 'Enable' button, the Workbook opens, macros do get enabled, but Workbook_Open doesn't run.
I've never known the problem to occur if no other workbook is open. (Of course, the user might still get the yellow-backed messages at the top of the workbook, asking them to click the Enable Editing and/or Enable Macros buttons.)
Note that my Workbook_Open just calls another 'workbook-opening' sub in a module to do all the opening processing.
My solution: When my workbook-opening sub is called, it sets a global variable to True to indicate it has run.
I've made it obvious to the user that the problem has occurred, by means of a 'Welcome' sheet with all its cells locked, so the user can do nothing; at this point all other sheets are very hidden. The workbook-opening sub, when it runs, deactivates this sheet and makes it very hidden, so the user never normally sees it, and makes the other sheets visible. But if this screen remains, it instructs the user to select the other workbook, then select this one again. My Workbook_Activate code then runs, and because the global variable isn't True, it calls the workbook-opening sub. If this global variable is True, it does nothing.
To make this work, the Workbook_Close sub makes the other sheets very hidden and the Welcome sheet visible, ready for the next time the Workbook is opened.
Hey presto, the problem is solved.
The Welcome sheet actually has a dual purpose, in that if either of the yellow-backed warning messages are displayed, it will remain and force the user, with suitable instructions, to click Enable Editing and/or Enable macros. If the users aren't au fait with macro-enabled Excel, they will just ignore these and try to carry on regardless.
All this is much easier to implement than to explain. I hope it's clear.
And I hope this might be of help to someone.
I had this issue with one of my files as well. I managed to fix this issue by running Workbook_Open manually in the VBA editor once open and saving the file in another location. The file in the new location should have no issue with auto-running Workbook_Open. If this doesn't work, copy the original file to a new location before manually running & saving.
If the newly saved file does not run Workbook_Open, repair your version of Office.
In Excel 2013: macro was working fine until today. Now, I can open the "Personal.xlsb" file, but I cannot use the Macro view button anymore, all I get is Excel in unresponding mode; and then, only way is to stop Excel entirely. When I go in design mode, I cannot access the macro registry at all (trying to do so results in the same unresponding state). I rebooted the PC entirely, did not help.
Pb seems specific to one specific "Personal.xlsb" file (I replaced the incriminated file with another "Personal" file in the XSTART folder and Excel macros worked just fine with a different .xlsb file). So I am suspecting a file corruption pb. If that is the case, is it possible to recover the original macros, or at least crack the macro file open and get a copy of the original coding?
You can try to get back your code if you manage to open the workbook from a macro in another workbook. Give this a shot:
create a folder where you will get the recovered code modules. Let's say "C:\myRecoveredCode". Put in a copy of your corrupt file "Personal.xlsb"
In Excel Options, Trust Center Settings, Check Trust Access to the VBA project object module
create a fresh workbook, copy/paste and run the following macro:
Sub TryRecovery()
myFolder = "C:\myRecoveredCode\"
Set wb = CreateObject(myFolder & "Personal.xlsb")
For Each comp In wb.VBProject.VBComponents
comp.Export myFolder & comp.Name
Next
wb.Close False
End Sub
If all goes well, you will have files a set of files that you can edit, or import to another workbook.