Protección de celdas excepto para el código VBA
Resuelto
lecrol
Mensajes publicados
224
Fecha de registro
Estado
Miembro
Última intervención
-
Le Pingou Mensajes publicados 12274 Fecha de registro Estado Colaborador Última intervención -
Le Pingou Mensajes publicados 12274 Fecha de registro Estado Colaborador Última intervención -
Hola a todos y todas,
Mi problema es sin duda “trivial”. De hecho he encontrado muchos mensajes sobre este mismo tema de la protección de celdas con o a través de VBA. Pero o bien es mucho más de lo que quiero hacer, o no responde exactamente a lo que necesito.
Una hoja de cálculo muy simple en la que quisiera proteger todas las celdas, salvo las de una única columna
eso por sí solo, es hyper fácil: bloqueo de celdas y protección de la hoja
Pero el problema es que tengo código VBA que muestra en la hoja, en varios lugares, valores o mensajes. Entonces, bajo VBA, mi hoja no debe estar protegida y ninguna celda bloqueada
He probado un Worksheets(1).Unprotect al inicio y un Worksheets(1).protect justo antes del end sub
Pero aun así me sale un error de VBA en el primer “Range”
¿Quién puede aclararme una solución simple sin contraseña ““?
De antemano, muchas gracias
Roland
Configuración: Windows 7 / Chrome 27.0.1453.94
Mi problema es sin duda “trivial”. De hecho he encontrado muchos mensajes sobre este mismo tema de la protección de celdas con o a través de VBA. Pero o bien es mucho más de lo que quiero hacer, o no responde exactamente a lo que necesito.
Una hoja de cálculo muy simple en la que quisiera proteger todas las celdas, salvo las de una única columna
eso por sí solo, es hyper fácil: bloqueo de celdas y protección de la hoja
Pero el problema es que tengo código VBA que muestra en la hoja, en varios lugares, valores o mensajes. Entonces, bajo VBA, mi hoja no debe estar protegida y ninguna celda bloqueada
He probado un Worksheets(1).Unprotect al inicio y un Worksheets(1).protect justo antes del end sub
Pero aun así me sale un error de VBA en el primer “Range”
¿Quién puede aclararme una solución simple sin contraseña ““?
De antemano, muchas gracias
Roland
Configuración: Windows 7 / Chrome 27.0.1453.94
15 respuestas
-
Hola Roland,
Intenté algo similar para verificar la protección y desprotección de las hojas durante la ejecución del procedimiento principal. Creé dos procedimientos, uno para desproteger y otro para proteger. Llamo al primero justo antes de la ejecución del programa y luego llamo al segundo después de la ejecución del procedimiento principal, todo en 3 procedimientos.
< Code >
'desproteger de la hoja3 a la antepenúltima página del libro
Sub Deproteger_doc()
Dim I
Application.ScreenUpdating = False
On Error Resume Next
For I = 3 To Sheets.Count - 1
Sheets(I).Activate
Range("D10").Select
ActiveSheet.Unprotect Password:="risks2"
Next I
Sheets("Feuille_principale").Select
Range("A1").Select
On Error GoTo 0
Application.ScreenUpdating = True
End Sub
< \Code >
puis
< Code >
'Protéger de la hoja3 a la antepenúltima página del libro
Sub Protege_Doc()
Dim I
Application.ScreenUpdating = False
On Error Resume Next
For I = 3 To Sheets.Count - 1
Sheets(I).Activate
Range("D10").Select
ActiveSheet.Protect Password:="risks2"
Next I
Sheets("Feuille_principale").Select
Range("A1").Select
On Error GoTo 0
Application.ScreenUpdating = True
End Sub
< \Code >
et enfin procédure principale
< Code >
Sub restriction_opened()
On Error Resume Next
Application.ScreenUpdating = False
Sheets("Feuille_principale").Activate
Range("BA2:BD23").ClearContents
Range("BA2").FormulaR1C1 = Application.UserName
'Lève les restrictions d'ouverture pour les noms inscrits dans la liste ci-dessous
Range("BB2").Select
ActiveCell.Offset(0, 0).Value = "utilisateur1"
ActiveCell.Offset(1, 0).Value = "utilisateur2"
ActiveCell.Offset(2, 0).Value = "utilisateur3"
ActiveCell.Offset(3, 0).Value = "utilisateur4"
ActiveCell.Offset(4, 0).Value = "utilisateur5"
Range("BB2").Activate
On Error Resume Next
For Each Cellule In Range("liste_noms")
If Cellule.Value = Application.UserName Then
Range("BD2").Value = Application.UserName
End If
Next
Application.ScreenUpdating = False
If Range("BA2").Value = Range("BD2").Value Then
Sheets("Feuille_principale").Activate
Range("A1").Select
Call Deprotege_DocU
Call CalculActions_TraiteNonTraite '<< Procédure principale !! >>
Application.ScreenUpdating = True
Else
Sheets("Feuille_principale").Activate
Range("A1").Select
Call Deprotege_DocU
Call CalculActions_TraiteNonTraite '<< Procédure principale !! >>
Call Protege_DocU
End If
Sheets("Feuille_principale").Select
Range("A1").Select
Application.ScreenUpdating = True
End Sub
< \Code >
En espérant que ces bouts de lignes de code t'aient éclairé un peu plus, pour ma part ce petit programme gère toutes les entrées et applique une lecture seule en permanence à tous les utilisateurs de ce fichier sauf 5 utilisateurs (de 0 à 4).
Bon courage et bonne chance
jiaco79 -
Gracias jiaco7 por acercarte a mi problema
He leído tu código y me surgen varias preguntas
**** ¿Es obligatorio asociar una contraseña con protect o with unprotect? Yo solo escribía ActiveSheet.Protect = True (o False)
Leyendo tu código se me ocurre otra idea
*** ¿Haría falta un select antes de protect (o unprotect) de la hoja?
Yo solo quiero proteger (o lo contrario) las dos áreas de mi hoja A1:G28 y I1:N28
Pero esa protección es solo para proteger mis fórmulas de cálculos de una entrada accidental por parte del usuario (mi nieta de 10 años)
No necesito otra seguridad, ni contraseña ni confidencialidad.
Pero es esa protección básica la que no logro obtener.
Gracias de nuevo
De mi lado, seguiré investigando y probando
Cordialmente
Roland -
Hola,
Solo para aclarar, ¿es posible ver el código de su procedimiento ... ?
Sería mejor para entender lo que ustedes desean al final ... !
--
Saludos.
Le Pingou -
Hola,
puedes proteger con:
sheets("Feuil1").Protect UserInterfaceOnly:=True
Solo el usuario estará bloqueado, las macros no necesitarán desproteger la hoja.
Lo pones en Workbook_BeforeClose para estar seguro de no olvidar.
eric
Nunca responderás a un mensaje privado no solicitado...
Bueno, ya está hecho. -
Gracias a todos,
Aquí abajo están las dos procedures que tengo en este dossier (sí, ya sé, podría haber hecho una bucle "for next" en la 1ª; Pero es solo un juego de cálculo para mi hija
La protección de la hoja no tiene por objeto impedirle escribir fuera de las únicas celdas H5:H24
Por otro lado, todas las demás deben estar disponibles para VBA, y bloqueadas para el usuario. Y es eso lo que no logro obtener
Gracias de nuevo por vuestra ayuda esclarecedora
Cordialement,
Roland
----------------------------------------------------------------------------
Private Sub CommandButton1_Click()
Dim img As Shape
For Each img In Worksheets("Feuil1").Shapes
If img.Name = "Bonus" Then ActiveSheet.Shapes("Bonus").Delete
Next img
'
For Each img In Worksheets("Feuil1").Shapes
If img.Name = "Cible" Then ActiveSheet.Shapes("Cible").Delete
Next img
'
Range("F5") = Int((8 * Rnd) + 2)
Range("F6") = Int((8 * Rnd) + 2)
Range("F7") = Int((8 * Rnd) + 2)
Range("F8") = Int((8 * Rnd) + 2)
Range("F9") = Int((8 * Rnd) + 2)
Range("F10") = Int((8 * Rnd) + 2)
Range("F11") = Int((8 * Rnd) + 2)
Range("F12") = Int((8 * Rnd) + 2)
Range("F13") = Int((8 * Rnd) + 2)
Range("F14") = Int((8 * Rnd) + 2)
Range("F15") = Int((8 * Rnd) + 2)
Range("F16") = Int((8 * Rnd) + 2)
Range("F17") = Int((8 * Rnd) + 2)
Range("F18") = Int((8 * Rnd) + 2)
Range("F19") = Int((8 * Rnd) + 2)
Range("F20") = Int((8 * Rnd) + 2)
Range("F21") = Int((8 * Rnd) + 2)
Range("F22") = Int((8 * Rnd) + 2)
Range("F23") = Int((8 * Rnd) + 2)
Range("F24") = Int((8 * Rnd) + 2)
'
Range("g5") = Int((8 * Rnd) + 2)
Range("g6") = Int((8 * Rnd) + 2)
Range("g7") = Int((8 * Rnd) + 2)
Range("g8") = Int((8 * Rnd) + 2)
Range("g9") = Int((8 * Rnd) + 2)
Range("g10") = Int((8 * Rnd) + 2)
Range("g11") = Int((8 * Rnd) + 2)
Range("g12") = Int((8 * Rnd) + 2)
Range("g13") = Int((8 * Rnd) + 2)
Range("g14") = Int((8 * Rnd) + 2)
Range("g15") = Int((8 * Rnd) + 2)
Range("g16") = Int((8 * Rnd) + 2)
Range("g17") = Int((8 * Rnd) + 2)
Range("g18") = Int((8 * Rnd) + 2)
Range("g19") = Int((8 * Rnd) + 2)
Range("g20") = Int((8 * Rnd) + 2)
Range("g21") = Int((8 * Rnd) + 2)
Range("g22") = Int((8 * Rnd) + 2)
Range("g23") = Int((8 * Rnd) + 2)
Range("g24") = Int((8 * Rnd) + 2)
'
Range("h5:h24") = ""
Range("E5:E24") = ""
Range("L5:M24") = "" '
Var = Time() '
Range("K4") = Var
End Sub
---------------------------------------------------------
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
'
Dim L As Integer
Dim img As Shape
Dim repi As String
Dim repc As String
Dim EL As String
Dim JL As String
Dim KL As String
Dim HL As String
Dim Hlsuit As String
Dim Ll As String
Dim ML As String
'
'
For L = 5 To 24
repi = "c:\Jeu calcul\Im" & CStr(L - 4) & ".jpg"
repc = "c:\Jeu calcul\Ct" & CStr(L - 4) & ".jpg"
EL = "E" & CStr(L)
HL = "H" & CStr(L)
Hlsuit = "H" & CStr(L + 1)
KL = "L" & CStr(L)
JL = "K" & CStr(L)
Ll = "L" & CStr(L)
ML = "M" & CStr(L)
'
If Range("H5") = " " Then GoTo Fin ' si pas encore joué
'
If Target.Column = 8 And Target.Row = L Then
If Range(JL) = 0 Then
For Each img In Worksheets("Feuil1").Shapes
If img.Name = "cible" Then ActiveSheet.Shapes("Cible").Delete
Next img
Range(EL) = Range(HL) 'Mise en réserve du nombre saisi
Range("N5").Select
ActiveSheet.Pictures.Insert(repi).Select
Selection.Name = "Cible"
If L < 24 Then Range(Hlsuit).Select
'
ElseIf Range(JL) = 1 Then
For Each img In Worksheets("Feuil1").Shapes
If img.Name = "Bonus" Then ActiveSheet.Shapes("Bonus").Delete
Next img
If Range(EL) = "" Then GoTo Exam 'si pas de calcul antérieur
Range(Ll) = "C'est trop tard !"
Range(ML) = 1
GoTo Suit
Exam:
Range(EL) = Range(HL) 'Mise en réserve du nombre saisi
Range("B5").Select
ActiveSheet.Pictures.Insert(repc).Select
Selection.Name = "Bonus"
If L < 24 Then Range(Hlsuit).Select
End If
End If
'
Suit:
Next L
'
Fin:
If Range("H27") = 20 Then
Range("P20").Select
ActiveSheet.Pictures.Insert("c:\Jeu calcul\Champion Medaille.jpg").Select
Selection.Name = "Bonus"
Range("B20").Select
ActiveSheet.Pictures.Insert("c:\Jeu calcul\Champion Vainqueur.jpg").Select
Selection.Name = "Bonus"
GoTo Sortie
End If
'
If Range("H24") = "" Then GoTo R1
If Range("H27") > 14 Then
Range("P20").Select
ActiveSheet.Pictures.Insert("c:\Jeu calcul\Champion_Coupe.jpg").Select
Selection.Name = "Bonus"
GoTo Sortie
End If
'
R1:
If Range("H24") = "" Then GoTo R2
If Range("H27") > 9 Then
Range("P20").Select
ActiveSheet.Pictures.Insert("c:\Jeu calcul\Moyen.jpg").Select
Selection.Name = "Bonus"
GoTo Sortie
End If
'
R2:
If Range("H24") = "" Then GoTo Sortie
If Range("H27") < 9 And Range("H27") >= 0 Then
Range("p20").Select
ActiveSheet.Pictures.Insert("c:\Jeu calcul\Non.jpg").Select
Selection.Name = "Bonus"
Range("B20").Select
ActiveSheet.Pictures.Insert("c:\Jeu calcul\Non_2.jpg").Select
Selection.Name = "Bonus"
End If
Sortie:
'
End Sub
----------------------------------------------
¿Has leído mi publicación 4?
-
Hola,
Síiii Eriiic, lo leí y lo probé de inmediato, pero me da un error de compilación. Esto es lo que escribí en el workbook:
Private Sub Workbook_BeforeClose()
Sheets("Feuil1").Protect UserInterfaceOnly:=True
End Sub
Y me da un error de compilación con: "La declaración de la rutina no coincide con la descripción del evento o procedimiento del mismo nombre".
¿Dónde está mi error?
Gracias a ti
Roland
PD En mi hoja bloqueo todas las celdas, salvo las únicas donde se puede ingresar H5:H24.
Pero no activo la protección ya que es VBA quien la hace. ¿Está bien así? -
-
-
Eric, eres muy amable por ayudarme
He colocado este código después de haber eliminado el otro, y ya no tengo error de compilación
Pero ¿no se necesita poner un "=false" en algún lugar y un "= True" en otro lugar?
Yo imaginaba desproteger la entrada de la macro VBA y reproteger la salida de la macro.
Con el código que he colocado (al abrir la carpeta, la protección está desactivada y por ello no obtengo el resultado deseado)
Gracias por tu paciencia
Atentamente
Roland-
¿Pero no me hace falta poner un ""=false"" en algún lugar y un ""= True"" en otro lugar?
no
UserInterfaceOnly : Argumento de tipo Variant opcional. Este argumento tiene el valor True para proteger la interfaz de usuario, pero no las macros. Si este argumento no se especifica, la protección se aplica tanto a las macros como a la interfaz de usuario.
Cierras tu libro.
Al abrirse, Hoja1 estará protegida para el usuario pero no para las macros que escriben sobre ella.
Vuelve a probar así y dime...
eric
-
-
He seguido tus instrucciones
1- En la hoja, activo la protección
2- En el libro, he colocado el siguiente código!
Private Sub Workbook_Open()
Sheets("Feuil1").Protect UserInterfaceOnly:=True
End Sub
Cierro mi libro y lo vuelvo a abrir.... y tengo un error en esta línea:
For Each img In Worksheets("Feuil1").Shapes
If img.Name = "Bonus" Then ActiveSheet.Shapes("Bonus").Delete
Next img
con el mensaje: Error 1004 Error definida por la aplicación o el objeto
Como indica mi código (que publiqué completamente en un post más arriba), mi VBA también coloca y borra imágenes en la hoja
¿Podría haber una “alergia” entre estas operaciones “shapes” y ese código UserInterfaceOnly que añadí al libro? Probablemente, porque sin ese código no tengo error (pero tampoco protección)
Gracias de antemano
Roland-
Es difícil responderte sin un archivo y ni el valor ni el tiempo para construir uno que se parezca al tuyo...
Pero se puede suponer, de hecho, que lo has hecho bien y que las shapes son insensibles a UserInterfaceOnly:=True
Por si acaso no te protejas a ti mismo y deja actuar a la macro, pero no creo que haga diferencia.
No sería la primera vez que una funcionalidad funciona correctamente solo en una parte.
Si es así, te esperan más líneas: quitar y volver a aplicar la protección como se propuso antes. Lamento en ese caso haberte hecho perder tiempo.
Cuando tenga 5 minutos lo probaré porque sería interesante confirmar.
eric -
Pero no, no me hiciste perder tiempo, ¡Eric!
Entonces, ¡no te disculpes de verdad! Eres muy amable, tú y todos los demás de este foro, al compartir así vuestros saberes y vuestros conocimientos!
¡De nuevo gracias y un gran aplauso! Este sitio es realmente de utilidad nacional. ¡Me gustaría poder dar siquiera una pequeña parte de lo que encuentro aquí, créeme!
Son efectivamente las shapes las que me plantean problemas al no dejarse "conocer" por el código VBA de "desprotección"
Pero te agradezco de nuevo tu amabilidad y tu paciencia
Cordialmente
Roland -
-
Acabo de probar, efectivamente la protección de los objetos permanece. Por lo tanto, sin contraseña, al inicio de cada sub cuando sea necesario: Sheets("Feuil1").Unprotect restaurarlo al final de cada sub: Sheets("Feuil1").Protect Si tienes varias hojas o subs, puedes agruparlos en 2 subs que llames cada vez que sea necesario. Si miras la ayuda sobre Protect verás que puedes aumentar los derechos del usuario sobre ciertas acciones. eric
-
-
Bonjour à tous,
Je ne sais pas si eriiic (salutations) cherche une solution, personnellement sans voir la configuration du fichier c'est presque impossible de trouver est le problème.
De plus cette instruction se retrouve dans les 2 procédures et vous ne précisez pas l'endroit précis ..... rien à faire .... !
Salutations.
Le Pingou-
Gracias, Le Pingou por brindarme un poco de tu tiempo. Mi "archivo", aquí, es una hoja en blanco. Simplemente 1- Mi procedimiento VBA "hoja" (con botón de comando) lo llena de números al azar, en columnas F5:G25. También borra el contenido de otras celdas modificadas por cálculos. 2- El usuario, un niño de 10 años, introduce el producto de los números en cada una de las 20 filas y lo hace en la columna H5:H25. 3- Mi otro procedimiento (en "workbooks") captura cada resultado ingresado. Y, según el caso (1 = correcto, 0 = falso), muestra imágenes llamadas "bonus" o "cible". Y el código VBA borra estas imágenes cada vez que es necesario, para que no se acumulen en la hoja; Es por esto que me gustaría (quería?) que el código VBA pueda hacer todo, imágenes y celdas, sin protección; Que, por el contrario, el usuario solo pueda acceder a las únicas celdas H5:H25. Voilà, eso es todo. Pero si quieres te envío con gusto el dossier completo. Cordialmente, Roland
-
-
Hola,
Gracias por la información, eso corresponde a lo que descubrí en parte en su código.
Sin embargo, como indicó eriiic y yo mismo, sin el archivo y estos [Shapes] es imposible hacer más, lo siento.
--
Saludos.
Le Pingou-
Hola, Pero ¿qué quieres que te envíe como precisiones adicionales? 1- estos "shapes" son imágenes .jpg cualquiera que nombro "objetivo" o "bonificación" al cargarlas (como te indica el código VBA). Es según el código 0 o 1, "falso" o "cierto", que VBA lee en la hoja de Excel. 2- Del directorio no hay. La hoja ("feuil1") es una hoja alimentada desde el inicio por VBA, a partir de un botón de comando. Mi único problema ahora es colocar imágenes cualquiera (o borrarlas) en una hoja de Excel cualquiera pero que está protegida para el usuario. Dime si puedo decirte más para entender mejor mi problema. Eric me ha ayudado amablemente a desproteger VBA de todas las operaciones tipo celdas (Range o Select, por ejemplo). Pero al parecer, eso sería incompatible con las instrucciones de tipo shape().delete. Gracias otra vez. Cordialmente, Roland
-
-
Hola,
Eso será todo para mí porque eriiic os ha propuesto una buena solución (poste 19) que apoyo ya que también la he probado en un archivo ficticio y funciona.
Que tengas buen porvenir.
--
Saludos.
Le Pingou -
Y da igual si no funciona en Excel 2003 y exactamente con el código que he publicado aquí
¡Pero gracias de todos modos!
Roland -
Hola,
Acabo de volver a hacer una prueba en un archivo construido según su código, incluida la introducción de imagen (jpg) y funciona sin ningún problema y sin utilizar la propuesta de eriiic (punto 19).
Ningún mensaje de error debido a [Shapes].
--
Saludos.
Le Pingou -
Reconecto mi propuesta que parece haber quedado demasiado perdida en el hilo:
Acabo de probar, efectivamente la protección de los objetos permanece.
Así que sin contraseña, al inicio de cada sub (cuando lo necesites):
Sheets("Feuil1").Unprotect
restáuralo al final de cada sub:
Sheets("Feuil1").Protect
Si tienes varias hojas o subs, puedes agruparlos en 2 subs que llamas donde sea necesario.
Si miras la ayuda sobre Protect verás que puedes aumentar los derechos del usuario sobre ciertas acciones.
eric
--
jamás responderás a un mp no solicitado...
Bien, eso ya está hecho. -
¡Aleluya! Gracias, Eric, por tu paciencia y amabilidad
Acabo de verificar que todo funciona, efectivamente.
Mi error, muy probablemente, fue no conservar el código anterior:
Private Sub Workbook_Open()
Sheets("Feuil1").Protect UserInterfaceOnly:=True
End Sub
al cambiar el código a Sheets("Feuil1").Unprotect y .Protect
Pensé (estúpidamente) que el segundo sustituía al primero, haciéndolo inútil.
Ahora he colocado ambos códigos, el primero en el libro (workbooks) y el segundo al inicio y al final de mis 2 procedimientos.
¡Y todo funciona bien!
Una vez más, gracias. Gracias a ti y a Le Pingou. Siento no haberme explicado con suficiente claridad y de haberos quitado tanto tiempo.
Pero ahí, voy a poder hacer que sus tablas de multiplicar trabajen por fin para mi hija de 12 años (su bachillerato aún está lejos)
Gracias de nuevo a ambos y ¡felicitaciones por este foro!
Roland -
Hola lecrol,
Contento/a por ustedes.
Sólo por qué, su hija de 12 años va a obtener el bachillerato mucho más rápido de lo que ustedes piensan si en 2 días ella toma 2 años .....(mi nieta de 10 años / publica 3)... !
Buena semana.
--
Saludos.
El Pingou