Protect cells in excel but should be able to copy them - vba

If I use this code to protect a worksheet, how can I make it so that the user still can copy the cells? And can you specify certain cells that should NOT be protected, or at least the user should be able to edit them?
Worksheets("EKONOMI").Protect UserInterfaceOnly:=True

You can define if user is allowed to select cells in protected sheet by using
Worksheets("EKONOMI").EnableSelection = xlNoRestrictions 'worksheet has to be protected for this to take effect
To make user able to edit certain cells you have to unlock the cells before the protection. For instance you can use the following to make Range C3 as unlocked cell
ActiveSheet.Range("C3").Select
Selection.Locked = False

Sheets("EKONOMI").Activate
ActiveSheet.Unprotect Password:="123"
'ActiveSheet.Protection.AllowEditRanges(1).Delete
ActiveSheet.Protection.AllowEditRanges.Add Title:="Range1", Range:=Range("A1:A10")
ActiveSheet.Protect Password:="123"
Please find the above code to protect sheet by allowing user to edit patricular range of cells.
ActiveSheet.Protection.AllowEditRanges.Add Title:="Range1", Range:=Range("A1:A10")
Mention the range name and range size for the user to edit.

Related

VBA code for protecing range of cells (user intervention)

I want VBA code for protecting a range of cells(manually selected by user) in excel and rest of the cells will be locked. Ideally, I don't need to restrict the code for a specific range, it should allow a user to select a range of cell and lock those cells.
Please help me.
In Change of a the worksheet, lock the cells you selected and then, protect the worksheet.
something like :
with thisworkbook.worksheets("the name of the worksheet")
.unprotect
Target.locked=true
.protect
end with

Macro to copy whatever is currently in a cell, not a hard-coded reference

I would like the macro to copy the cell address listed in a designated cell and copy it into a "go to" box to activate that cell.
I tried recording this macro but instead of copying and pasting whatever is in the designated cell it hard-codes the cell address. This cell address will change periodically so I need it to be more dynamic.
Here is the code:
Range("D52").Select
Selection.Copy
Application.Goto Reference:="R3C33"
Instead of the hard-coded reference (R3C33) I want whatever is currently in D52. Further, if D52 is located in a separate sheet that is not currently activated how would I need to let the macro know to pull it from D52 from a different tab?
If D52 contains a cell address then:
Sub ytrewq()
Range(Range("D52").Text).Select
End Sub
will go there.
For example:
EDIT#1:
If D52 contains something like:
This this will first get to the proper worksheet and then to the proper cell:
Sub ytrewq()
Dim s As String
s = Range("D52").Text
Range(s).Parent.Activate
Range(s).Select
End Sub
Please try as below
Application.Goto Reference:=Range(Range("D52").Value)

Paste after unprotecting worksheet not working

I have two sheets "Request" and "Changes" both protected by same password. Password has been stored as a constant in another module. I have tested this code when "Changes" sheet in unprotected and it works, however for some reason, if I have to unprotect the sheet before pasting it won't paste.
I am simplifying trying to keep a record of what was deleted in the workbook by placing the info in a protected sheet "Changes" that is hidden.
Sub PODelete()
Dim rng As Range, ws As Worksheet, ws1 As Worksheet, lr As Integer
Set ws = Sheets("Request")
Set ws1 = Sheets("Changes")
lr = ws1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row 'Last non-blank row for column A
On Error Resume Next
Set rng = Application.InputBox("Select a range", Type:=8)
If Not rng Is Nothing Then
' Checks to see if column A is selected
If rng.Cells.Column = 1 Then
' Checks to see that only 1 cell is selected
If rng.Cells.Count > 1 Then
MsgBox "Select only one P.O. Number to remove"
Else
' Select entire row
rng.EntireRow.Copy
' Activate sheet and pastes values
Sheets("Changes").Activate
ws1.Unprotect Password:=worksheetpassword
Cells(lr, 1).EntireRow.Select
Selection.PasteSpecial Paste:=xlPasteValues
ws1.Protect Password:=worksheetpassword, DrawingObjects:=True, Contents:=True, Scenarios:=True
' Deletes range
ws.Activate
ws.Unprotect Password:=worksheetpassword
rng.EntireRow.Delete
ws.Protect Password:=worksheetpassword, DrawingObjects:=True, Contents:=True, Scenarios:=True
End If
Else
MsgBox "Select P.O. Number to remove"
End If
Else
Exit Sub
End If
End Sub
Once again, if I run this macro with the "Changes" sheet unlocked it will work.
The real answer to this is actually not to unprotect the Worksheet at all. Protect it with a different password that isn't stored in the file anywhere, but set the parameter UserInterfaceOnly:=True. This will allow the macro to make changes to the worksheet, and even if the user find the hidden sheet they won't be able to find the password.
Speaking of hiding it, you should really hide it. As far as I know this is only possible through VBA, but you can set the Worksheet to xlSheetVeryHidden, either through the VBE...
...or in code:
Worksheets("Changes").Visible = xlSheetVeryHidden
Then password protect the VBA project with the same password as the Worksheet, and nobody is going to find it but you unless they know the name of the sheet and manually type it into a cell formula:
=Changes!A1
If you want to avoid that possibility, just name the Worksheet something non-obvious or even total gibberish. The likelihood of an unsuspecting user typing this into a cell...
=kusidkeshlkiehas!A1
...is virtually zero.
I have found that occasionally doing an Unprotect on the active sheet will change the active sheet to a different sheet. I haven’t figured out under what circumstances this occurs or why the particular sheet that ends up selected gets selected. Could this be your problem? I solved this problem by having one routine that is called to do all Unprotects. In that routine I save the active sheet name before doing the Unprotect and then re-select the saved sheet. I haven't seen this problem with Protecting a sheet but just to be safeI have done the same thing with a Protect routine.
I tried to copy a range from one work book(selection.copy only once and keeping the workbook open) and through "for loop", to many other work books(ActiveSheet.Unprotect "password", ActiveSheet.Paste).
This works fine during 1st trial but fails during subsequent trials on the same file with a message "Error 1004 Paste Method of Worksheet Failed" suggested by Mr Darrel Dixon and various other solutions of "UserInterfaceOnly:=True" etc but the error is repeating. The sheet appears UNPROTECTED at that stage and copy from source workbook and paste into destination workbook MANUALLY works fine but through VBA macro, it fails.
Finally, I tried repeating "selection.copy" from source workbook after "ActiveSheet.Unprotect" on each destination workbook/each iteration of for loop.
Even though this appears to be inefficient code, this alone solved the problem of PASTE failure after UNPROTECTING a worksheet.

Secure Timestamp - VBA

I want to create a secure timestamp on my Excel sheet. The VBA I am using will automatically add the current users user name, the time, and the date when a user puts information into column A. So if the users puts something into cell A1 then B1 automatically gets filled with their username and C1 gets filled with the time and date. The only problem is that this method isn’t secure because the user could alter the information after it is automatically populated. I would like to add code to this VBA so it will lock all three cells after the information is populated.
I was planning on using the Protect Sheet feature and only allowing users to “Select unlocked cells” So if the VBA could auto lock the cells then the users would not be able to alter the information.
Moreover I have used Me.Unprotect before changing cells and Me.Protect after that still it is not working
Any help would be much appreciated!
Assume that we start with all the cells on the worksheet unlocked and the sheet password-protected with the password:
6LgSdHjc2uOssv0e1LDI
The following Event Macro will:
unprotect the workbook
detect entries in column A
place the username in column B and the date/timestamp in column C
lock the entries in columns A,B,C
re-protect the worksheet.
This goes in the Worksheet code area:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim A As Range, MyPass As String, sh As Worksheet
Dim unit As Range
Set A = Range("A:A")
MyPass = "6LgSdHjc2uOssv0e1LDI"
Set sh = ActiveSheet
If Intersect(Target, A) Is Nothing Then Exit Sub
Set unit = Union(Target, Target.Offset(0, 1), Target.Offset(0, 2))
Application.EnableEvents = False
sh.Unprotect (MyPass)
unit.Locked = False
Target.Offset(0, 1) = Environ("Username")
Target.Offset(0, 2) = Now()
unit.Locked = True
sh.Protect (MyPass)
Application.EnableEvents = True
End Sub
Because it is worksheet code, it is very easy to install and automatic to use:
right-click the tab name near the bottom of the Excel window
select View Code - this brings up a VBE window
paste the stuff in and close the VBE window
If you have any concerns, first try it on a trial worksheet.
If you save the workbook, the macro will be saved with it.
If you are using a version of Excel later then 2003, you must save
the file as .xlsm rather than .xlsx
To remove the macro:
bring up the VBE windows as above
clear the code out
close the VBE window
To learn more about macros in general, see:
http://www.mvps.org/dmcritchie/excel/getstarted.htm
and
http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx
To learn more about Event Macros (worksheet code), see:
http://www.mvps.org/dmcritchie/excel/event.htm
Macros must be enabled for this to work!

How do I dynamically update the name of a worksheet in Excel?

I have an Excel spreadsheet which is being used to specify filesystem build information for our Unix team.
This worksheet would have different information depending on the system to be built. For example, a production system would have many filesystems, whereas a development system only one or two.
So based on user input, we would populate one or other of the two input worksheet formats ("dev","prod") but the destination worksheet will be always be the same. Only one of the dev or prod worksheets would be visible and active for users to input data at any given time.
How do we tell Excel to use a particular input worksheet to calculate another output worksheet?
My initial idea was that, for simplicity's sake, the "output" worksheet would take its data from an "input" worksheet, and that we would dynamically make either the "dev" or "prod" template become the "input" worksheet. Is this the right way to do this, or is there some better method?
There's a few ways depending on the complexity of the sheet:
If you only have a few worksheets, and users would just select "Production" or "Test", you could set up the conditional logic in the formulas. For example: =if(A1="Test",TestSheet!A1 + TestSheet!A2, ProdSheet!A1 + ProdSheet!A2)
You could utilize the same type of idea as above, but add more complexity using vlookup tables
Your VBA code could create the entire Excel spreadsheet dynamically based on the user input
if you can use VBA code as LuckyLindy suggests, you can do pretty much anything. What I used to do is record macros for various operations, for example adding or renaming sheets and take the generated code and adapt it to do exactly what was required.
An example of simple macro code:
Sub Macro1()
'
' Macro1 Macro
'
'
Sheets("Sheet1").Select
Sheets("Sheet1").Name = "My Sheet"
Sheets.Add After:=Sheets(Sheets.Count)
Sheets("Sheet5").Select
Sheets("Sheet5").Name = "My Sheet 2"
End Sub
You can record very complex operations and manipulate the generated code and place it behind specific events. So if you wanted the code to fire on worksheet load or activation of a sheet, you can insert it in the relevant block: i.e.
'in Sheet1 - code behind (alt+F11 shortcut)
Private Sub Worksheet_Activate()
Sheets("Sheet1").Select
Sheets("Sheet1").Name = "My Sheet"
Sheets.Add After:=Sheets(Sheets.Count)
Sheets("Sheet5").Select
Sheets("Sheet5").Name = "My Sheet 2"
End Sub
HTH
Another way would be to use the INDIRECT formula.
Say you have in cell A1 the name of the sheet you want to look up input from, then the following will look up the value of cell B7 from that sheet:
=INDIRECT($A$1,"!B7")