I have a protected worksheet that users would like to copy and paste into. I have no control over the workbook they are copying from.
The protected worksheet has some rows that are available for data entry, and other rows that are locked and greyed out to the user. The users would like to be able to paste over the top of the entire worksheet from another random workbook and have all the cells available for data entry filled in, while the locked cells are undisturbed. In the current state, the user gets an error when they try to paste, because it cannot paste over the locked cells.
Example:
Worksheet 1:
Act1 100 100 100
Act2 100 100 100
Act3 100 100 100
Worksheet 2: (The second row is locked)
Act1 300 300 300
Act2 200 200 200
Act3 100 100 100
After copying/pasting Worksheet 2 should look like this:
Act1 100 100 100
Act2 200 200 200
Act3 100 100 100
The values from worksheet 1 are populated and the locked rows are undisturbed.
Requirements:
Method:
I referred to Jan Karel's Catch Paste sample for reference. You might want to add all the ways he is catching paste operations.
In the ThisWorkbook module add below code
Private mdNextTimeCatchPaste As Double
Private Sub Workbook_Activate()
REM Add Paste event handler
CatchPaste
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
REM Restore Paste event handler
StopCatchPaste
mdNextTimeCatchPaste = Now
Application.OnTime mdNextTimeCatchPaste, "'" & ThisWorkbook.Name & "'!UnProtectPasteToSheet"
End Sub
Private Sub Workbook_Deactivate()
REM Restore Paste event handler
StopCatchPaste
On Error Resume Next
REM Cancel scheduled macroREM s,
REM because we might be closing the file
Application.OnTime mdNextTimeCatchPaste, "'" & ThisWorkbook.Name & "'!UnProtectPasteToSheet", , False
End Sub
Private Sub Workbook_Open()
REM Add Paste event handler
CatchPaste
End Sub
Add a new Module and add below code
REM Add Paste event handler
Public Sub CatchPaste()
REM these are the ways you can Paste in to Excel
REM refer to http://www.jkp-ads.com/articles/catchpaste.asp for more details
Application.OnKey "^v", "UnProtectPasteToSheet"
Application.OnKey "^{Insert}", "UnProtectPasteToSheet"
Application.OnKey "+{Insert}", "UnProtectPasteToSheet"
Application.OnKey "~", "UnProtectPasteToSheet"
Application.OnKey "{Enter}", "UnProtectPasteToSheet"
End Sub
REM restore all default events
Public Sub StopCatchPaste()
Application.OnKey "^v", ""
Application.OnKey "^{Insert}", ""
Application.OnKey "+{Insert}", ""
Application.OnKey "~", ""
Application.OnKey "{Enter}", ""
End Sub
REM Here we will check the sheet is protected, if it is then paste to a temp sheet,
REM unprotect main sheet, paste the values, and restore locked cells
Private Sub UnProtectPasteToSheet()
On Error GoTo ErrHandler
Dim bProtected As Boolean, oSheet As Worksheet, oTempSheet As Worksheet, sPasteLocation As String
Dim oCell As Range, oCollAddress As New Collection, oCollValue As New Collection, iCount As Integer
REM check protection status
If Not ThisWorkbook.ActiveSheet.ProtectContents Then
Selection.PasteSpecial Paste:=xlAll
Else
bProtected = True
Set oSheet = ThisWorkbook.ActiveSheet
REM save paste location
sPasteLocation = Selection.Address
REM unprotecting clears Clipboard in Excel!! strange but true..
REM So paste it to a new sheet before unprotecting
Set oTempSheet = ThisWorkbook.Worksheets.Add
REM oSheet.Visible = xlSheetVeryHidden
oTempSheet.Paste
REM unprotect the sheet
oSheet.Unprotect
REM make a note of all locked cells
For Each oCell In oSheet.UsedRange
If oCell.Locked Then
oCollAddress.Add oCell.Address
oCollValue.Add oCell.Value
End If
Next
REM paste
oTempSheet.UsedRange.Copy
oSheet.Activate
oSheet.Range(sPasteLocation).Select
REM you need to paste only values since pasting format will lock all those cells
REM since in Excel default status is "Locked"
Selection.PasteSpecial xlValues
REM remove temp sheet
Application.DisplayAlerts = False
oTempSheet.Delete
Application.DisplayAlerts = True
REM restore locked cells
For iCount = 1 To oCollAddress.Count
Range(oCollAddress.Item(iCount)) = oCollValue.Item(iCount)
Next
REM restore protection
oSheet.Protect
End If
Exit Sub
ErrHandler:
Debug.Print Err.Description
If bProtected Then
ThisWorkbook.ActiveSheet.Protect
End If
End Sub
Note: I am adding REM instead of ' to keep the Stackoverflow formatter happy.
Give it a try and let me know how it goes..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With