I implemented smart dropdown (using Active X controls) in my sheet, so it is protected.
This functionality is not able to work because of protection.
When I right click on the sheet and Unprotect it, providing the password, it works.
I do not want the user to do this manually. I want that when user opens the sheet the sheet should get unprotected using VBA code.
The entire cells in the sheet are Locked (Format cells-> Protection -> Locked marked).
I cannot untick the Locked mark, as there are some validations which gets failed and not allow me to upload such template.
Below is an example as I cannot share the application code.
VBA code:
In sheet1-> name of sheet is "tab0"
Private Sub Worksheet_BeforeDoubleClick _
(ByVal Target As Range, _
Cancel As Boolean)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
ws.Unprotect Password:="xxx"
Inside ThisWorkbook I have this
Private Sub Workbook_Open()
ThisWorkbook.UnProtect Password = "password"
End Sub
A late input to this question:
I've been experiencing similar problems with Unprotecting sheets, and ended up doing aa fair bit of testing to find what works and what doesn't (always!).
The problem appears to be when assigning the sheet to an object and using the object's dot notation to unprotect e,g.:
'Setting the worksheet (globally) in sub Main()
Public goXsTT As Worksheet
Set goXsTT = goXbWb.Sheets(2)
'Somewhere else in the code
goXsTT.Unprotect
'This ***may*** fail, whereas:
Sheets(2).Unprotect
'Works!
No idea why this is the case - just pointing out that it's a workaround if you're stumped, as I was. Hope it helps. DG
Related
I have a workbook with multiple tabs. All tabs are protected. Some are fully protected while others are partially protected (that is, column and row size can be adjusted). There is one page of inputs. When the macro button is pressed, all the other tabs are populated. In order to allow the tabs to be populated by a macro even where the cells are locked I have used the following code on Workbook Opening:
Private Sub Workbook_Open()
Dim wSheet As Worksheet
For Each wSheet In Worksheets
wSheet.Protect Password:="Secret", _
UserInterFaceOnly:=True
Next wSheet
End Sub
However, this resets all the tabs to be fully protected (whereas some only need to be partially protected).
Is there a way around this?
Many thanks in advance
The Sheet.Protect seems to have a parameter for
AllowFormattingColumns Optional Variant
True allows the user to format any column on a protected worksheet. The default value is False .
Have you tried this?
I have to create an Excel sheet automatically with vba.
Some cells need an Onchange Event Listener and I wanted to know if there is a way to create this Event Listener automatically by calling a macro instead of writing it down everytime in every sheet code ?
Thank you
I'm going to answer this question because I think it might have some relevance to quite a few other people too, so the code below should get you started in the right direction.
However, there is an expectation on this site that you try to help yourself at least to the same extent as we try to help you. The commenters have mentioned the VBA Object Model, Application Events and AddIns. It shouldn't be beyond the wit of most people to then research these key words (say with a google search). It's not really acceptable simply to say you "dunno where to put the code or what to do", and, in all honesty, doesn't particularly motivate people to help you - put another way, you're pretty lucky to get an answer with that post and comment.
I don't want to get into a huge comment exchange on exactly how to code your specific case. The code here is an example and I would expect you then to research it further. So here goes ...
Insert a class module (research that if you don't know how) and name it - I've called mine cApp. This will enable you to access the Application object and capture its events, like so:
Option Explicit
Private WithEvents mApp As Application
Private mSheetList As Collection
Private Sub Class_Initialize()
Dim ws As Worksheet
'Create instance of the sheet collection
Set mSheetList = New Collection
'If you wanted to add any existing sheets to be checked for changes,
'then you'd do it here.
'Just for an example, I'm using any existing sheets whose name contains "LoP".
For Each ws In ThisWorkbook.Worksheets
If InStr(ws.Name, "LoP") > 0 Then
mSheetList.Add ws
End If
Next
'Create instance of Application
Set mApp = Application
End Sub
Private Sub mApp_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim ws As Worksheet
'Test if the changed sheet is in our list.
'Check if the Sh object is a worksheet.
If TypeOf Sh Is Worksheet Then
'Loop through out list of sheets and see if the Sh object is in the list.
For Each ws In mSheetList
If Sh Is ws Then
'Check if the changed range is in the desired range of your sheet.
'In this example, we'll say it has to been in the range "A1:B2".
If Not Intersect(Target, ws.Range("A1:B2")) Is Nothing Then
MsgBox ws.Name & "!" & Target.Address(False, False) & " has changed."
End If
Exit For
End If
Next
End If
End Sub
Private Sub mApp_WorkbookNewSheet(ByVal Wb As Workbook, ByVal Sh As Object)
'A new sheet has been created so add it to our sheet list.
If Wb Is ThisWorkbook Then
If TypeOf Sh Is Worksheet Then
mSheetList.Add Sh
End If
End If
End Sub
You then want to create an instance of this class. I've done it in a standard Module:
Option Explicit
Private oApp As cApp
Public Sub RunMe()
'Create instance of your app class
Set oApp = New cApp
End Sub
You'd then call the RunMe routine somewhere within your code. You might choose to do this in your Workbook_Open() event, but it could be anywhere of your choosing.
I've commented the code pretty heavily so you can see what it's doing and you can always research each of the keywords if you're not sure what they're doing.
I have a spreadsheet with several sheets, which is protected except where I want people to make changes, and all is password protected. I am trying to make a command button so others can view the data, but can't make changes to the cells. Here is what I have (not working quite right).
Private Sub mdRead_Click()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Sheets
'To open wookbook as read only, while proctecting changes.
Worksheet.Unprotect = True
Worksheet.Range("C10:I23,L10:R23,C25:I36,L25:R36,C45:I58,L45:I58,C60:I71,L60:R71").Select
Selection.Locked = True
Next ws
End Sub
Having set the Locked property, you might want to protect the sheet again.
I am new in using Excel VBA. I have an Excel VBA code that will duplicate a certain sheet for n times. I want to prevent user from changing the workbook structure manually (such as adding new sheet, duplicating sheet, or moving sheet), but I still want the VBA to be able to run.
How should I do it?
I was hoping you could use UserInterfaceOnly but that appears to be only worksheet level and not workbook level - it locks the worksheet for users, but allows VBA code to make updates.
The only other way I can think of is to lock and unlock the workbook as needed:
Sub Test()
Dim wrkSht As Worksheet
UnlockWorkbook
Set wrkSht = ThisWorkbook.Worksheets.Add
LockWorkbook
End Sub
Sub LockWorkbook()
ThisWorkbook.Protect Password:="aaa", Structure:=True
End Sub
Sub UnlockWorkbook()
ThisWorkbook.Unprotect Password:="aaa"
End Sub
I have a userform which opens one of a list of worksheets. I want to create a macro that recognises the last sheet opened by the userform and then runs data validation based on data types in the sheet.
How can I reference the sheet opened so that it can be called later my the validation macro?
All help gratefully accepted!
You need to "remember" it in a Public variable.
In a Standard Module, near the top of that module, include:
Public LastSheet As Worksheet
and in the UserForm, code like:
Sub WithinUserForm()
Dim x As String
x = Application.InputBox(Prompt:="pick a worksheet", Type:=2)
Sheets(x).Select
Set LastSheet = ActiveSheet
End Sub
Finally within the DV macro:
Sub MacroForDV()
LastSheet.Select
End Sub