unlock specific area in a protected excel sheet with vba - vba

I have to unlock a specific range (D6:BC116) in a excel sheet. It should be able for other people editing this specific area. So it should be unlocked for them.
At first I manually protect the whole sheet without any code. And after that I want to unprotect the specific area for editing. But something always goes wrong. I have these two codes. The first code has the hidden property it only hides empty cells. The other code I am trying to unprotect specific area I want to edit after protecting the whole sheet.
I am not really sure if the problem is in the first code because of the hidden property? And I am not sure if they are in a relation?
Private Sub Worksheet_Change(ByVal Target As Range)
For Each cell In Range("B6:B112")
If cell.Value <> "" Then
cell.EntireRow.Hidden = False
Else
cell.EntireRow.Hidden = True
End If
Next cell
End Sub
Sub UnlockCells()
Worksheets("Sheet1").Range("D6:BC116").Locked = False
Worksheets("Sheet1").Protect
End Sub
And when I execute this I always get "Index out of range"
Thanks!

I think you need to unprotect before unlocking.
Like this:
With Worksheets("Sheet1")
.Unprotect "MyLongAndSecurePassword"
.Range("D6:BC116").Locked = False
.Protect
End with
Concerning the first part of the code - make sure that you use a variable, which is not named cell, because cell is used by the VBEditor. Name your variable rngCell, myCell or anything else but cell. And declare it like this: Dim rngCell as Range.
Last point - lock your worksheet and try to hide and unhide manually the rows. Is it possible? If not, you know the reason for the error.
Edit:
To check whether the sheet is protected, try this in the Worksheet_Change:
Private Sub Worksheet_Change(ByVal Target As Range)
If Worksheets("Sheet1").ProtectContents Then Exit Sub
For Each cell In Range("B6:B112")
If cell.Value <> "" Then
cell.EntireRow.Hidden = False
Else
cell.EntireRow.Hidden = True
End If
Next cell
End Sub

Related

Delete 0's from cell upon entry

I want a macro so that when you enter a 0 into a particular cell/range of cells that it clears the cell.
I wrote a simple macro like this
Sub RemoveZeros()
'to remove 0 values that may be a result of a formula or direct entry.
For Each cell In Range("A1:D20")
If cell.Value = "0" Then cell.Clear
Next
End Sub
However, I have to run this after I have entered my values for it to clear. I would like the cell to clear if a 0 is entered. How do I do this?
I found a solution
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Target.Value = 0 Then Target.ClearContents
Application.EnableEvents = True
End Sub
Thanks

Excel VBA code to select all cells with data sometimes working

I once built a VBA button to automatically lock all cells with data in them. And it was working perfectly. Now I wanted to copy that button to another worksheet. So I created another button, copy and pasted the whole VBA over, then edited the worksheet names and range. And, it's only working like 5% of the time, the rest of the time, I'm getting an "Run-Time error '1004': No cells were found." I've tried a few fixed, changing Sheets to Worksheets, or adding a ", 23" to the specialcells argument. However, nothing is working right now. When I try stepping in, it sometimes say both rng and lckrng as empty, and sometimes only show lockrng as empty and not show rng at all. Problem is this used to be a working code, and now, it still works around 5% of time. Any idea why? Thank you very much!
Private Sub CommandButton1_Click()
Dim rng As Range
Dim lockrng As Range
Sheets("Uploading Checklist (M)").Unprotect Password:="signature"
Set rng = Range("A1:M14")
'Selecting hardcoded data and formulas
Set lockrng = Union(rng.SpecialCells(xlCellTypeConstants), rng.SpecialCells(xlCellTypeFormulas))
lockrng.Locked = True
Sheets("Uploading Checklist (M)").Protect Password:="signature"
End Sub
Maybe this is too simplistic, but it seems to do what you want. The animated .gif shows it working to "lock all cells with data in them". (I made the second button just for convenience). If nothing else it might be good to start from something like this that works and modify to suit your needs.
Dim cell As Range, sh As Worksheet
Sub Button4_Click()
Set sh = Worksheets("Sheet1")
sh.Unprotect Password:="s"
For Each cell In sh.UsedRange
If cell <> "" Then cell.Locked = True Else cell.Locked = False
Next
sh.Protect Password:="s"
End Sub
Sub Button5_Click()
Set sh = Worksheets("Sheet1")
sh.Unprotect Password:="s"
End Sub
The Union you are attempting will not work if either of the parameters is Nothing (i.e. you either have no constants in the range, or you have no formulas in the range).
Prior to doing the Union, you should check the parameters aren't Nothing but, once you start changing your code to do that, it would be just as simple to do the locking in two parts - so I recommend you rewrite the code as follows:
Private Sub CommandButton1_Click()
With Sheets("Uploading Checklist (M)")
.Unprotect Password:="signature"
With .Range("A1:M14")
'Lock any constants
If Not .SpecialCells(xlCellTypeConstants) Is Nothing Then
.SpecialCells(xlCellTypeConstants).Locked = True
End If
'Lock any formulas
If Not .SpecialCells(xlCellTypeFormulas) Is Nothing Then
.SpecialCells(xlCellTypeFormulas).Locked = True
End If
End With
.Protect Password:="signature"
End With
End Sub

Program excel to return a specific value

I have a spreadsheet that is going to be used in a survey.
How can I make the cells only to return "x" regardless of what the survey taker type in.
For instance, if I write a "w" in the cell, it should turn into an "x".
I have come to a point where I think there is an option when I protect the workbook or sheet. Because I can tell from another spreadsheet (which has this function) that it only works if the workbook is protected.
I tried to google it, but it seems as if I don't know the right keywords to find the answer.
Also, I have found a set of Vba code that I fiddle with, but I'm not sure this is correct. I don't want to attach the code as I don't want to confuse any response here.
Thank you for any help provided.
Put this code in the worksheet module and test it out, when you change a cell in column A (1) it will activate,
Where is the worksheet Module?
Copy and paste the code ,
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Intersect(Target, Range("A1,B1,C1,A4,B4,C4")) Is Nothing Then Exit Sub
Application.EnableEvents = 0
If Target <> "" Then Target = "X"
Application.EnableEvents = 1
End Sub
This should work for you (just change the range to the one you need) :
Option Explicit
Sub worksheet_Change(ByVal Target As Range)
On Error GoTo errorbutler 'error handler - important to have this in case your macro does a booboo
Application.Calculation = xlCalculationManual 'turn off automatic calculation to speed up the macro
Application.EnableEvents = False 'turn off events in order to prevent an endless loop
Dim LR, cell As Range 'Declare your variables
Set LR = Range("A1:b3") ' Select range of cells this macro would apply to
For Each cell In Target 'Loops through the cells that user have changed
If Union(cell, LR).Address = LR.Address Then 'Checks if the changed cell is part of your range
cell.Value="x" 'changes the value of that cell to x
End if
Next cell
Errorexit: 'part of error handling procedure
Application.EnableEvents = True 'Turn autocalc back on
Application.Calculation = xlCalculationAutomatic 'turn events back on
Exit Sub
Errorbutler: 'error handling procedure
Debug.Print Err.Number & vbNewLine & Err.Description
Resume Errorexit
End Sub
Oh yes, and this code should be put into the worksheet module - the same way as Dave has shown you

VBA Excel-How to restrict users not to paste on specific rows?

I have an Excel like shown below which is a sharedExcel.
Now i should not allow paste option for the rows which have backcolour as GRAY(These are not fixed at runtime any row may get GRAY colour). As it sharedExcel and i can't use the Lock property. Any help wouls be appreciated greatly.
Using a color as a property that is used to check true / false is bad behaviour.
You can get around this by for example adding a column (hidden if needed) with 0 / 1 or TRUE / FALSE which you make accessible by for example a combobox (then you can still adapt the color into gray by clicking this cbb box).
The you can check on a dynamically composed range via a Sheet event on_Change.
The basic syntax for the sheet event:
Private Sub Worksheet_Change(ByVal Target As Range)
'Set range dynamically instead of this hard coded example
If Not Intersect(Target, Thisworkbook.Sheets(1).Range("A1:A10")) Is Nothing Then
'Do something
End If
End Sub
After spending some time on this problem i have coded following lines. It work's fine. Here i have taken another spreadsheet called PasteSheet for coding purpose but i am not showing it to user at any moment.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Application.CutCopyMode Then
SelectedRow = ActiveCell.Row
With Sheets("PasteSheet")
.Activate
.Range("A1").PasteSpecial xlPasteValues
CR = Selection.Rows.Count
End With
Worksheets("ActualSheet").Activate
For k = SelectedRow To (SelectedRow + CR)
If Worksheets("ActualSheet").Cells(k, 30).Interior.Color = RGB(215, 215, 215) Then
Application.EnableEvents = False
MsgBox "Pasting is not allowed here!"
'Clearing data in PasteSheet
Worksheets("PasteSheet").Cells.ClearContents
Worksheets("ActualSheet").Activate
Application.EnableEvents = True
Exit Sub
End If
Next
End If
End Sub

Unlock cell on a condition from adjacent cell

I have two columns but the codition I would like is to be evaluated from one cell to another.
The first column has cells which have a drop down validation with names, and the second will activate only if a certain name from the adjacent cell is selected.
so far i only found this code but it does not seem to work:
Private Sub Worksheet_Change(ByVal Target As Range)
If Range("A1").Value = "Car" Then
Range("B1").Locked = False
Else
Range("B1").Locked = True
End If
End Sub
I would need this code go from (for example) A1:A10 and B1:B10.
I hope I am making sense. If there is a way to do it without VBA, that would be great.
Thanks for the help.
The Target parameter tells you the range that is being changed.
You need to do something like the following:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range
Set rng = Intersect(Range("A1:A10"), Target)
If rng Is Nothing Then
' Not updating the range we care about
Exit Sub
Else
rng.Offset(0, 1).Locked = ... whatever ...
End If
End Sub
Note that your target range can be more than one cell (e.g. when using copy/paste), so you need to handle and test this case.
Calling Intersect returns you the intersection of the target range and the range you are interested in testing (A1:A10 in this sample).
You can then access the corresponding adjacent cell(s) using .Offset(0,1)
That code snippet works perfectly for me.
Did you place that code in the proper WorkSheet object? It won't work if you just put it into a VBA module. When you are in the Visual Basic Editor, look for a directory on the left side of the screen labeled "Microsoft Excel Objects". In that directory should be a WorkSheet object for every sheet in your file. Double-click on one of these to edit the code for that WorkSheet. This is where your code snippet should go.
Private Sub Worksheet_Change(ByVal Target As Range)
If Range("A1").Value = "Car" Then
Range("B1").Locked = False
Me.Unprotect ("password")
Else
Range("B1").Locked = True
Me.Protect ("password")
End If
End Sub
Use Me.Protect so the .Locked method does something. You should probably unlock every other cell though.