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
Related
I am new to VBA!
I have a workbook A that I use as a template for spinoff workbooks B, C, D, etc.
I made an error in formulas range A36:E37. I need to correct it in all the subsequently created workbooks, which can have any random name
I want to open the corrected master workbook A, and copy range from A to whateverworkbookname
Every time I use thisworkbook refrerence, it pastes the data to my personal macro workbook, same thing with activeworkbook.
I'm sure there's a simple solution, (like assigning a variable to the freshly opened workbook that needs fixing?) but I don't know how to do that.
Help is much appreciated!
Also of note, I am planning on manually opening the whaverworkbookname, then VBA unprotecting the sheet, copy paste function, protecting the sheet, saving, and closing the whateverworkbookname book when the macro completes, to be repeated with the rest of the incorrect workbooks.
If there is a smarter way to do this (which is probably way over my head) like applying a macro to all workbooks in a folder for instance, I would be interested in a point in the right direction to learn about it.
First a note:
ThisWorkbook always refers to the workbook the code is written in. This never changes.
ActiveWorkbook is the workbook that has focus (is on top). This changes easily with a mouse click on any workbook.
The issue is probably that you run the code from VBA editor. But if it is in your personal workbook and you run from the editor, then as soon as you are in the code your active workbook is the personal one because that is where your code is and if you click there to run the code it has focus.
You can check if the active workbook is the personal one
If ActiveWorkbook.Name = ThisWorkbook.Name Then
MsgBox "The active workbook is the personal one. Make sure to focus on the correct workbook."
Exit Sub
End If
'rest of your code
Create a button or link a ribbon button to launch your macro and use ActiveWorkbook in your code.
Start to get Excel catastrophic failure error
On OK opening debug windows, with auto creating each time new sheets, which is empty and strange structure
If I want something to do appears
So how to delete those sheets? or fix that error?
No background process started, file stored in xlsm and xlsb format do the same things. workbook and worksheets is not protected.
It looks like the file has been corrupted. It is unlikelly the problem can be easily reproduced from scratch.
Never the less you can script a vba macro to delete Sheets based on their names or not delete the sheets you want to keep.
sheetnametodelete= "sheetname"
With Application.Workbooks(ThisWorkbook.Name())
.Unprotect (yourpassword) ' required if protection is set
Dim wks As Worksheet
Set wks = .Sheets(sheetnametodelete)
If (Not wks Is Nothing) Then ' also check if wks belong to the defined blacklist
wks.Delete
End If
.Protect (yourpassword) ' required if protection is set
End With
Try to open the file from another computer in case your local Excel config is corrupted.
I had a similar problem (a fake workbook duplicated) in the past and decided to script a build process for my Excel vba based application.
See following links to learn more about module management.
https://www.rondebruin.nl/win/s9/win002.htm
http://www.cpearson.com/excel/vbe.aspx
you can also look at this post
Import a cls files and create a sheet
It provides code and comments from other contributors.
This is obviously not direct answer to your problem but if you intend to work on a consistent vba project I recommand to save your vba code out of your Excel file once in a while and setup a build of your Excel app.
I have a workbook ("CodeBook.xlsm") that runs code using a BeforeSave event. When a user has multiple workbooks open and chooses to quit excel via File/Exit, the user is prompted whether to save workbooks, and if yes to CodeBook.xlsm, then the BeforeSave code is run. The problem is, at that point the ActiveWorkbook may not be CodeBook.xlsm, unless that happens to be the workbook that the user was in when he/she selected Exit Excel. If the user quit excel from another workbook, the BeforeSave code is running but the activeworkbook is some random file of the user, so all the references to specific worksheets and ranges in the BeforeSave code do not work.
I have tried various ways using a Static declaration to retain the name of CodeBook and workbook().activate to activate it when the application is quitting, but when BeforeSave runs, it can't pick up the name CodeBook anywhere, short of hard-coding the name into the code.
Any suggestions? How to retain a variable name in memory when there is no code running, but is there when a user initiates a quit excel, OR how to activate a specific workbook when Excel is quitting from a user command and not from application.quit. Using excel 2010.
I overcame this by including a reference to the specific workbook.
For example, this code simply saves the date/time stamp in cell A1 of Sheet1 before closing the document. By adding ThisWorkbook, it works on the specific workbook that the code resides in. If you don't add ThisWorkbook then it will work on the active workbook when the user quits.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Worksheets("Sheet1").Range("A1").Value = Now()
End Sub
Place this code in the ThisWorkbook module.
I am using VBScript to make lots of calculations on different sheets on the same workbook. Now one concern is if somehow someone deleted any of the sheet, the script would then lead to massive data loss. Is there any way to protect it from users?
(Make sure you read the edit at the end of this answer)
I have similar workbooks I have made that use sheets like databases, so I understand your concern of protecting the information. If you are protecting the Workbook, it will prevent your macro from performing certain changes to the sheets/book. However, if you only want to protect the sheet contents, you can use the setting UserInterfaceOnly, which will allow your macro to run freely while still protecting the sheets from the users. You can detect if the sheets are protected when opened, and if not, protect them.
Sub test()
dim mySheet as worksheet
dim myPass as string
myPass = "password"
set mySheet = Excel.ActiveSheet
if mySheet.ProtectContents = False then
mySheet.Protect Password:=myPass, UserInterfaceOnly:=True
end if
'Enter your code here
mySheet.Unprotect Password:=myPass
End Sub
Furthermore, if you want to give the user the ability to unprotect the sheets after being warned, then you can use Custom UI Editor to remove the protect/unprotect sheets group from the review tab and then replace it with a customized button. I've done this in the past and it actually helped a lot with maintaining the sheets later. I've included a couple links on Custom UI Editor below.
Custom UI Editor Download
Custom UI Editor Tutorial - Change the Ribbon in Excel 2007 or
2010
EDIT:
At first glance I thought this question pertained to VBA (my bad). I believe the above code can still apply, just place the code within the tags and set the workbook and worksheet variables properly (not the way they are set above). If you don't already know how to set/reference your workbook/worksheetsheet objects, this forum post shows how. Albeit I don't normally work with VBscript, but the forum looks correct. Good luck!
i nw this was a few years ago, but i ran into it when searching for the answer, hopefully someone fins this helpfull.
First add a password to your workbook that way other users will only be able to open as read only.
http://www.k2e.com/tech-update/tips/728-tips-adding-a-password-to-make-an-excel-workbook-read-only
then to make as part of the vbscript when opening the excel file(s)
Set oExcel = CreateObject("Excel.Application")
Set oWorkbook = oExcel.Workbooks.Open(file.path,,,,"password","password",True,,True,True)
full list of switches can be found here:
http://msdn.microsoft.com/en-us/library/office/ff194819%28v=office.15%29.aspx
hope that helps, took me hours to figure this out.
I have 10 XLS's, each of which contain a a few hundred lines of VBA that do the same thing. I want to move this common code into an 11th XLS, and have the other 10 call the code in the 11th XLS. The common code must have access to all of the data and worksheets in the calling XLS. This last requirement does not seem to be addressed by other answers to this question on SO. Can I pass the calling XLS's worksheets in as a parameter, or something similar?
Instead of putting this into a secondary XLS file, I'd recommend creating an XLA file (an Excel Add In).
This is the exact scenario for which XLA was intended. XLA will work the way you intend in this case.
For details on creating an XLA, see this page.
Yes, you can pass references to workbooks, worksheets, ranges, etc. as parameters to any function:
Public Sub CallMe(ByVal oWorkbook as Workbook)
Dim oWorksheet as Worksheet
Set oWorksheet = oWorkbook.Worksheets(1)
' Do stuff...
End Sub
Note that you'll probably have to re-write a lot of the code you copy from the 10 workbooks since they'll be full of implicit references to "this" workbook, such as Worksheets(1) etc. As in the example above, you now need to say oWorkbook.Workbooks(1) instead.