La macro que se ejecuta correctamente, después ya no hace nada más.

Resuelto
bassmart Mensajes publicados 281 Fecha de registro   Estado Miembro Última intervención   -  
bassmart Mensajes publicados 281 Fecha de registro   Estado Miembro Última intervención   -
Hola a todos!

Tengo un problema con mi archivo que contiene varias macros. Tengo una macro que se activa cuando se hace doble clic (Worksheet_BeforeDoubleClic) en la columna C de la hoja Coordenadas, para modificar el valor de esa celda. Tengo otra macro que pone todas las entradas de esa hoja en mayúsculas (UCase) también.

Se ejecuta muy bien la primera vez, pero cuando quiero modificar otro valor haciendo doble clic en la columna, ya no pasa nada y hasta las otras macros que se encuentran en esa hoja ya no funcionan.

¿Qué está pasando?

¿Qué puedo hacer para corregir la situación?

¡Gracias de antemano por vuestra ayuda!

Aquí están las macros que se encuentran directamente en mi hoja “Coordonnées”

Private dlig As Long Private PL As Range Public var As Variant Option Explicit Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Dim nValue As String Dim NewVal As String Dim f As Worksheet Dim sheetName As String Application.ScreenUpdating = False For Each f In ActiveWorkbook.Worksheets f.Unprotect Next nValue = ActiveCell.Value If Not Intersect(Target, Range("c5:c" & [a1048576].End(xlUp).Row + 1)) Is Nothing Then If MsgBox("Voulez-vous mofifier le numéro de ce sondage?", _ vbYesNo + vbQuestion, "MODIFER") = vbYes Then NewVal = UCase$(Application.InputBox("Nouveau numéro de sondage?", "MODIFICATION DE NUMÉRO", Type:=2)) ActiveCell = NewVal If InStr(1, nValue, "C") = 1 Or InStr(1, nValue, "M") = 1 Then sheetName = "CPTU" ElseIf InStr(1, nValue, "F") = 1 Then sheetName = "FORAGE" ElseIf InStr(1, nValue, "Z") = 1 Or InStr(1, nValue, "FZ") = 1 Then sheetName = "Piézomètres" ElseIf InStr(1, nValue, "I") = 1 Then sheetName = "Inclinomètres" Else sheetName = "" MsgBox "La valeur n'a pas été trouvé dans les autres feuilles! Mettre à jours les feuillets sur la page d'accueil!", vbCritical End If If Len(sheetName) > 0 Then Sheets(sheetName).Columns(1).Replace nValue, NewVal, LookAt:=xlWhole, SearchOrder:=xlByColumns End If If var <> Target Then var = Target.Value MsgBox "N'oubliez pas de changer le numéro dans la colonne ABRÉVIATION!", vbExclamation, "IMPORTANT" End If Else ActiveCell.Select End If End If For Each f In ActiveWorkbook.Worksheets f.Protect Next Application.ScreenUpdating = True ActiveCell.Offset(-1, 0).Select 'Range("B5").Select End Sub Private Sub Worksheet_Change(ByVal Target As Range) ActiveSheet.Unprotect If Target.Column >= 3 And Target.Column <= 5 Then 'desactive les evenements excel: eviter appel recurcif a la suite du passage en majuscule Application.EnableEvents = False Target = UCase(Target) End If 'active les evenements excel Application.EnableEvents = True If Target.Cells.Count > 1 Then Exit Sub If Target.Row < 5 Or Target.Column <> 5 Then Exit Sub If Target.Value = "" Then Cells(Target.Row, 1).ClearContents If Range("A5") <> "" Then dlig = Range("E5").End(xlDown).Row Set PL = Range("A5:A" & dlig) PL.Value = Range("a5").Value End If Dim T As Range, i& Set T = [TableauCoord] Application.EnableEvents = False On Error Resume Next 'sécurité If T.Rows.Count < 4 Then Application.Undo 'annulation Else '---suppression des lignes vides--- For i = T.Rows.Count - 1 To 4 Step -1 If T(i, 1) = "" Then T(i, 1).EntireRow.Delete Next '---ajout de ligne--- If T(T.Rows.Count, 1) <> "" Then Application.ScreenUpdating = False T(T.Rows.Count, 1).EntireRow.Insert T.Rows(T.Rows.Count - 1).FormulaR1C1 = T.Rows(T.Rows.Count).FormulaR1C1 T.Rows(T.Rows.Count) = "" Application.ScreenUpdating = True End If End If Application.EnableEvents = True ActiveSheet.Protect End Sub Private Sub worksheet_activate() Dim resultat As String Const Dossier As String = "6.02.06.MT.02." ActiveSheet.Unprotect If Range("a5") = 0 Then resultat = UCase(InputBox("Entrez le numéro du Bassin Versant!", "Bassin Versant")) If resultat <> "" Then dlig = Range("E5").End(xlDown).Row Set PL = Range("A5:A" & dlig) PL.Value = Dossier & resultat End If End If ActiveSheet.Protect Range("b5").Select End Sub 

3 respuestas

  1. PlacageGranby Mensajes publicados 402 Estado Miembro 26
     
    Hola,

    Lamentablemente no tengo tiempo de sumergirme en tu código.
    Pero, la mejor manera de encontrar el problema es con una traza paso a paso.

    Vamos al editor de VBA, y hacemos clic en la margen izquierda para colocar un punto de interrupción.

    Luego, hacer doble clic y mirar qué hace el código. Verás.
    1 - si la macro se ejecuta o no con el doble clic.
    Si no se ejecuta, es un problema relacionado con el evento. El código no está en el evento correcto.

    2- si la macro se ejecuta, entonces pulsas F8 para seguir paso a paso su ejecución para encontrar por qué no actúa como se espera.

    Buena suerte.
    0
    1. bassmart Mensajes publicados 281 Fecha de registro   Estado Miembro Última intervención   1
       
      Mil gracias PlacageGranby!

      Lo que he notado es que cuando modifico el valor de una celda haciendo doble clic, va después de la línea
      Activecell = NewVal
      , en la macro que se encuentra justo después de Worksheet_Change.

      Y luego regresa después de la línea
      If Target.Row < 5 Or Target.Column <> 5 Then Exit [/contents/446-fichier-sub Sub]
      en mi macro BeforeDoubleClic, en la línea
      If [/contents/1169-vbscript-les-fonctions-de-chaines-de-caracteres InStr](1, nValue, "C") = 1 Or InStr(1, nValue, "M") = 1 Then
      .

      Entonces, lo que entiendo es que es un cambio de valor. Entonces, va a la macro que corresponde Worksheet_Change.

      En ese momento, tengo una macro que hace que todas las entradas de datos se pongan en mayúsculas, así como una macro que agrega filas al final de mi tabla cuando está llena.

      Cuando hago doble clic de nuevo en una nueva celda, ya no pasa nada, me quedo en la línea 1 de la macro BeforeDoubleClic!

      ¿Es eso mi problema, no estoy muy seguro?
      0
    2. PlacageGranby Mensajes publicados 402 Estado Miembro 26
       
      Comienzas con una asignación
      nValue = ActiveCell.Value

      Luego, ingresas la nueva información
      NewVal = UCase$(Application.InputBox("Nouveau numéro de sondage?", "MODIFICATION DE NUMÉRO", Type:=2))

      Y cambias la activecell
      ActiveCell = NewVal

      Pero utilizas
      If InStr(1, nValue, "C") = 1 Or InStr(1, nValue, "M") = 1 Then

      nValue es una variable que se ha asignado una sola vez, por lo que aún equivale a su antiguo valor. Pasas NewVall a ActiveCell, pero nunca a nValue.

      ¿Fue esto intencionado?
      0
      1. bassmart Mensajes publicados 281 Fecha de registro   Estado Miembro Última intervención   1 > PlacageGranby Mensajes publicados 402 Estado Miembro
         
        Hola PlacageGranby!

        ¡Sí, es normal! Por ahora funciona bien!

        Uso nValue para buscar dónde se ubica el valor seleccionado en mis otras hojas. Luego con mi inputbox, le asigno un nuevo valor que se convierte en mi NewVal y que uso para reemplazar el valor antiguo por el nuevo.

        ¡Quizá mi código no esté muy bien escrito, pero funciona! ¡Soy principiante en VBA!

        ¡Gracias!
        0
  2. ThauTheme Mensajes publicados 1564 Estado Miembro 160
     
    No me gusta Application.EnableEvents = False. Si en tu código hay una salida en la que olvidaste devolver a True, o si falla antes de volver a True, ¡las macros de eventos dejan de funcionar!
    Uso una booleana como en este ejemplo:

    Private TEST As Boolean Private Sub Worksheet_Change(ByVal Target As Range) If TEST = True Then Exit Sub TEST = True 'el código... TEST = False 'a colocar en todos los lugares de salida If/Redo/Exit For/Exit sub/etc. End Sub

    En tu código del Clic Doble modificas la pestaña Coordenadas pero también otras pestañas que cada una contiene el evento Change con Application.EnableEvents = False. Por lo tanto, debes revisar tu código en todas las pestañas. Creo que ahí está el problema...

    La ventaja de la booleana es que los demás eventos siguen funcionando aunque Test no se haya puesto a False...

    Otro problema: declaras una variable pública en el componente Hoja2(Corrdonnées).

    Public var As Variant

    O, las variables públicas deben declararse al inicio de un módulo estándar, (Module1 por ejemplo).

    Para evitar desproteger y volver a proteger tus pestañas a cada rato, te recomiendo este pequeño fragmento de código del componente ThisWorkbook :

    Private Sub Workbook_Open() Dim O As Object 'declara la variable O (Hoja) For Each O In Sheets 'bucle sobre todas las pestañas del libro O.Protect UserInterfaceOnly:=True 'protege la pestaña dejando que las macros actúen Next O Sheets("Accueil").Select End Sub


    El argumento UserInterfaceOnly permite la modificación por macro pero no manual...

    --
    À plus,
    ThauTheme
    0
    1. bassmart Mensajes publicados 281 Fecha de registro   Estado Miembro Última intervención   1
       
      Gracias ThauTheme por la respuesta!

      Primero, entiendo lo que dices con respecto a
      Application.EnableEvents=False
      pero ¿cómo modificar mi código con tu propuesta?

      Ahora mismo estoy un poco perdida. ¿Simplemente añado las líneas de código tal como están?

      Para el
      Public var As Variant
      . Se encuentra en la parte superior de la hoja de Coordenadas. Lo encontré en un foro; quería que cuando modificara una celda me mostrara un mensaje del tipo "No olvides cambiar el número en la columna X" en la pantalla. Pero no funciona, incluso si vuelvo a introducir el mismo valor, me muestra el mensaje.

      ¿Qué problema podría haber con el hecho de que no esté declarado en un módulo?

      Y para tu propuesta de protección, ¡funciona muy bien! Pero solo para la primera modificación que realizo en mi hoja de Coordenadas. Después aparece un mensaje de error porque ¡mi hoja está bloqueada! Se detiene en la línea ActiveCell en el código siguiente:
      If var <> Target Then var = Target.Value MsgBox "N'oubliez pas de changer le numéro dans la colonne ABRÉVIATION!", vbExclamation, "IMPORTANT" ActiveCell.Offset(-1, 0).Select End If


      ¡Muchas gracias!
      0
      1. bassmart Mensajes publicados 281 Fecha de registro   Estado Miembro Última intervención   1 > bassmart Mensajes publicados 281 Fecha de registro   Estado Miembro Última intervención  
         
        ¡Hola a todos!

        ¡Problema solucionado!

        Efectivamente, el problema venía de
        Application.EnableEvents=False
        . añadí una expresión
        Application.EnableEvents=true
        al final de mi macro y eso corrigió mi problema.

        Y para el código propuesto por thautheme para la protección de las hojas, ¡eso funciona muy bien! ¡Era de nuevo mi problema de
        Application.EnableEvents=False
        que hacía que todo fallara!

        ¡Aquí está mi código final!:
        Private dlig As Long Private PL As Range Option Explicit Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Dim nvalue As String Dim NewVal As Variant Dim f As Worksheet Dim valueRange As Range Dim Cpt As Integer Application.ScreenUpdating = False nvalue = ActiveCell.Value If Not Intersect(Target, Range("c5:c" & [a1048576].End(xlUp).Row + 1)) Is Nothing Then If MsgBox("Voulez-vous mofifier le numéro de ce sondage?", _ vbYesNo + vbQuestion, "MODIFER") = vbYes Then NewVal = UCase(InputBox("Nouveau numéro de sondage?", "MODIFICATION DE NUMÉRO")) If NewVal = "" Then ActiveCell.Offset(-1, 0).Select Exit Sub Else ActiveCell = NewVal End If If InStr(1, nvalue, "C") = 1 Or InStr(1, nvalue, "M") = 1 Then Set valueRange = Sheets("CPTU").Columns(1) ElseIf InStr(1, nvalue, "F") = 1 Then Set valueRange = Sheets("FORAGE").Columns(1) ElseIf InStr(1, nvalue, "Z") = 1 Or InStr(1, nvalue, "FZ") = 1 Then Set valueRange = Sheets("Piézomètres").Columns(2) ElseIf InStr(1, nvalue, "I") = 1 Then Set valueRange = Sheets("Inclinomètres").Columns(2) Else Set valueRange = Nothing MsgBox "La valeur n'a pas été trouvé dans les autres feuilles! Mettre à jours les feuillets sur la page d'accueil!", vbCritical End If If Not valueRange Is Nothing Then valueRange.Replace nvalue, NewVal, lookat:=xlWhole, searchorder:=xlByColumns End If If NewVal <> nvalue Then MsgBox "N'oubliez pas de changer le numéro dans la colonne ABRÉVIATION!", vbExclamation, "IMPORTANT" ActiveCell.Offset(-1, 0).Select End If Else ActiveCell.Offset(-1, 0).Select End If End If Application.ScreenUpdating = True Application.EnableEvents = True End Sub
        0