¿Quiero proteger una celda pero también permitir que un usuario seleccione opciones de la lista desplegable?
Leí la siguiente pregunta que no proporciona una respuesta.
Proteger una celda, pero permitir que funcione la lista desplegable
Desproteger la celda no es lo que quiero hacer, ya que un usuario podría simplemente pegar sobre la celda y la validación de datos desaparecerá.
¿Hay alguna manera de tener una CELDA bloqueada y tener activada la protección de la hoja pero aún así permitir que se seleccionen las opciones de la lista de validación de datos?
Probaré cualquier opción, incluido VBA.
Respuesta1
Puede que haya una mejor manera de hacerlo, pero tuve una idea y parece funcionar bien con mis pruebas hasta ahora.
Entonces uso Worksheet_SelectionChange
para monitorear lo que el usuario está haciendo con la lista.
Simplemente desbloqueo la hoja cuando se selecciona la celda y la bloqueo nuevamente cuando se selecciona otra cosa:
Tenga en cuenta que mi lista está en N26
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("N26")) Is Nothing Then
ActiveSheet.Unprotect
Else
ActiveSheet.Protect
End If
End Sub
El problema con esto es obviamente que deberías poder seleccionar la celda y luego pegar lo que sea.
Entonces necesitamos verificar si el usuario está pegando algo, y encontré algunas cosas interesantes aquí:https://stackoverflow.com/questions/27818152/excel-vba-how-to-detect-if-something-wasted-in-a-worksheet
Entonces con esto podemos comprobar si se ha pegado algo y deshacerlo.
Los junté, lo modifiqué y así el usuario puede pegar cualquier celda desbloqueada, pero no en N26
.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("N26")) Is Nothing Then 'Data validation list adress
ActiveSheet.Unprotect
Else
ActiveSheet.Protect
End If
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("N26")) Is Nothing Then
Dim UndoList As String
'~~> Get the undo List to capture the last action performed by user
UndoList = Application.CommandBars("Standard").Controls("&Undo").List(1)
'~~> Check if the last action was not a paste nor an autofill
If Left(UndoList, 5) = "Paste" Then
With Application
.EnableEvents = False
.Undo 'Undo paste
.EnableEvents = True
End With
End If
End If
End Sub
Tenga en cuenta que algunos de estos valores pueden cambiar si no está utilizando una versión en inglés de Excel. Tuve que cambiar "&Undo"
y (UndoList, 5) = "Paste"
a mi idioma.
Supongo que también podrías usar esto para tu próxima pregunta. Si permite pegar nuevamente, pero luego verifica cada cambio para pegar, y si es cierto, ejecute IsNumeric(Target.value)
verificar y deshacer si falla.