Mon code s'arrête après un Rows(i).insert

Résolu
Bonjour,

Je rencontre un problème que je ne comprend et donc je ne trouve pas la solution sur internet. Je me tourne donc vers vous en espérant que quelqu'un puisse m'apporter une solution. Je vous explique

Je suis entrain de coder une macro qui est capable d'ajouter une ligne dans un tableau et qui ensuite doit mettre a jour la suite du tableau en incrémentant les chiffre de la suite du tableau. Seulement voila mon code s’arrête juste après la ligne : Rows(i).Insert

Après avoir tester plusieurs solutions, toutes inefficaces je me dit que je vais tester les bases en testant un enregistrement de macro je fait donc un enregistrement qui insert une ligne et qui ajoute juste une nombre dans un cellule après et la pareil mon code s’arrête Je pense donc que le problème est lié a la feuille excel mais je ne voit pas quoi

Voici le code de la macro enregistrer qui s’arrête après le Insert :

Sub Macro1()
'
' Macro1 Macro
'

'
Rows("48:48").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Range("C49").Select
ActiveCell.FormulaR1C1 = "2"
Range("C50").Select
End Sub

Merci d'avance

12 réponses

  1. Bonjour a tous,

    Je ne vous avais pas oublié mais je me devais de tester la solution jusqu'au bout avant de confirmer qu'elle fonctionnait. Pour rappel, mon problème était un arrêt intempestif de mon code VBA, qui était exécuter dans un fichier XLA.

    La solution qui m'a permit de résoudre ce problème a été de retravailler tout mon code afin transférer des objets Workbook et Worksheet a mon XLA et retravailler mes instructions.(Amélioration de l'adressage)

    Par exemple :

    Sub MacroValeurCellule()

    cells(3,4).value = 4

    End Sub



    est devenue


    Sub MacroValeurCellule(feuille as Worksheet)

    feuille.cells(3,4).value = 4

    End Sub


    Merci encore a tout ceux qui m'ont aider a m'améliorer en VBA
    1. Rebonjour Pierre,

      Essaye ce code VBA (à adapter) :

      
      Option Explicit
      
      
      Function CheckNumberInput(windowInput) As Boolean
        
        CheckNumberInput = False ' to set default value
        
        If Not IsNumeric(windowInput) Then
          MsgBox "The input is not a number"
          Add_Line_window.Show
          Exit Function
        End If
        
        If windowInput > 19 And windowInput < 50 Then
          CheckNumberInput = True ' if number between 20 and 49
        Else
          MsgBox "It's not possible to add a line at this line"
        End If
      
      End Function
      
      
      Sub Add_Line_Table(lineNumber As Long)
      
        ' Ligne de débogage pour vérifier la valeur de lineNumber :
        
        MsgBox "lineNumber = " & lineNumber: Exit Sub
      
        ' Attention : ci-dessous, remplacer les 2 noms par leur nom réel !
      
        With Workbooks("Nom du Classeur").Worksheets("Nom de la Feuille")
      
          .Unprotect
          
          .Rows(lineNumber).Insert
          
          .Cells(lineNumber, 3) = .Cells(lineNumber - 1, 3) + 1
          .Cells(lineNumber, 3).Select
          
          While .ActiveCell.Row <> 50
            .ActiveCell = .ActiveCell.Offset(-1, 0) + 1
            .ActiveCell.Offset(1, 0).Select
          Wend
      
          .Protect
        
        End With
      
      End Sub
      
      
      Private Sub Button_OK_Click()
        
        Dim numberLine As Long
        
        Add_Line_window.Hide
        
        ' Bizarre : d'où provient ce NumberOfLine_Input ?
        ' (il devra avoir une valeur entre 20 et 49)
        
        If CheckNumberInput(NumberOfLine_Input.Value) Then
          numberLine = CLng(NumberOfLine_Input.Value)
          Add_Line_Table numberLine
        End If
      
      End Sub
      
      
      Private Sub Button_Cancel_Click()
        Add_Line_window.Hide
      End Sub
      
      

      ⚠  Ton code doit normalement contenir cette variable publique :
      Public NumberOfLine_Input As Long

      Si la feuille est toujours déprotégée, .Unprotect et .Protect sont inutiles ;
      mais en cas de doute (car ça dépend des utilisateurs), à laisser !

      Comme les .ActiveCell dépendent du Classeur et de la Feuille définis
      bien clairement par l'instruction With, je pense que ça ira.

      À te lire.
       
      1. Merci Jean, j'essayerai ton code demain et je te tiendrai au courant des résultats

        Bonne soirée
    2. Re,

      Le code du formulaire semble correct mais celui de Add_Line_Table ne l'est pas.

      Comme je t'ai dit dans un xla :
      1) Pas de déclaration implicite :
      C-à-d. pas de Rows(..., pas de Cells(...
      Mais Worbooks("xxx").Worksheets("yyy").Rows(....

      Parce que le xla est un classeur indépendant du classeur sur lequel la macro doit agir, il est donc indispensable d'écrire un code propre et complet.

      2) Pas de .Select (sauf si c'est vraiment indispensable et donc seulement pour la dernière instruction), pas d'ActiveCell (pour la même raison)

      PS: Il est fortement conseillé d'utiliser des variables objets

      Cordialement
      Patrice
      1. PS : Sans les tenants et aboutissants, il est difficile de t'écrire un code correct.

        - Comment lances-tu l'exécution de la macro ?
        - Comment t'assures-tu qu'elle travaille sur le bon fichier ?

        Une bonne piste serait de transférer à la procédure Add_Line_Table un objet range plutôt qu'un numéro de ligne. Ça limite le risque d'agir sur une mauvaise feuille, ça permet de se passer des ActiveCell qu'il faut absolument bannir !
      2. Merci pour toutes vos réponses cela me permettra d'améliorés grandement mes codes a l'avenir. Je vais essayer vos suggestions et je reviens vers vous pour vous tenir au courant.

        Au niveau des questions que vous m'avez posées
        Je lance ma macro en appuyant sur un bouton qui va rendre un UserForm visible en appelant la méthode Add_Line :

        Sub Add_Line()

        Add_Line_window.Show

        End Sub


        Cet UserForm propose une fenêtre de dialogue qui permet de rentrer un nombre via un TextBox que j'ai appelé NumberOfLine_Input. Cette UserForm possède deux bouton un cancel qui cache le UserForm et une autre qui exécute le code placé plus haut.

        Je suis sûr que le code travaille sur le bon fichier car le bouton se trouve sur la feuille ou les opérations doivent être effectuées. J'utilise les ActiveSheet pour travailler sur la feuille mais comme je crois comprendre il est important de récupérer les informations (Nom de feuille, Nom du classeur ...) dans le formulaire avant de les transmettre en parametres aux méthodes contenue dans le fichier XLA.

        PS : Je vous remercie pour les conseils que vous me donnez car j'ai appris le VBA par moi-même et un peu par itération et donc je manque certainement un peu de structure.
      3. @PierreVu qu'il s'agit d'un xla (ou xlam) je pensais que le bouton avait été ajouté à Excel (dans un menu ou dans le ruban selon la version).

        Vu qu'il est sur la feuille concerné, le plus simple est de transférer un objet Worksheet (en l’occurrence égal à l'Activesheet) dans les arguments d'une procédure du xla qui gère entièrement l’insertion de ligne. (inutile de transférer des noms de feuille et de classeur)

        C'est moins risqué que de "capter" l'Activesheet avec le formulaire
      4. Merci pour se"s information.

        La raison pour laquelle j'ai fait passer mon code en XLA est pour une raison de maintenance car un grand nombre de fichier doivent être utilisé avec la même macro. Mais le code n'est pas un "vrai" XLA.

        Bonne soirée

        Cordialement,

        Pierre
      5. @PierreVrai xla ou pas,le fait est qu'il s'agit d'un autre classeur donc les préconisation restent les mêmes
    3. Je viens d'essayer la solution que m'a proposé mais ça n'est toujours pas concluant. Je vais continuer de chercher
      1.  
        Bonjour Pierre,

        Si dans ton fichier original la feuille de calcul est protégée :

        
        Sub Macro1()
          Worksheets("Feuil1").Unprotect
          Rows(48).Insert: [C49] = 2: [C50].Select
          Worksheets("Feuil1").Protect
        End Sub
        
        

        Si le nom de ta feuille est autre que Feuil1, remplace "Feuil1"
        par le nom réel.

        Si tu lances toujours la macro à partir de la feuille où tu veux faire ce travail :

        
        Sub Macro1()
          ActiveSheet.Unprotect
          Rows(48).Insert: [C49] = 2: [C50].Select
          ActiveSheet.Protect
        End Sub
        
        

        Merci de me dire si ça a marché.

        Cordialement
         
      2. Merci pour ta réponse, Jean.

        Après avoir essayé ta solution, je rencontre toujours le même problème : La ligne s'insère mais le code s’arrête juste après sans effectuer les opérations suivantes

        Cordialement,

        Pierre
      3. @Pierre 
        Quel est le nom de la feuille où tu insères une ligne ? Est-ce toujours
        la feuille à partir de laquelle tu lances la macro ?

        La ligne s'insère : ok ; mais après, ça ne met pas 2 en cellule C49 ?
        S'il y a un message d'erreur, lequel est-ce ?

        [C50].Select est pour que la cellule active soit C50 ; donc après
        exécution de la macro, c'est C50 qui doit être sélectionnée ;
        cependant, si tu n'en n'a pas besoin, tu peux l'enlever :

        
        Sub Macro1()
          Worksheets("Feuil1").Unprotect
          Rows(48).Insert: [C49] = 2
          Worksheets("Feuil1").Protect
        End Sub
        
        

        À te lire.
         
      4. @jeanEn fait dans le programme total, le nom de la feuille n'est pas connu. Il n'est connu que par le fait qu'on pousse sur un bouton sur la feuille ou l'on désir ajouter une ligne. Je récupère le nom de la feuille via activeSheet.name.

        Pour essayer d'être le plus clair possible. Lorsque je me place en mode débogueur et que je regarde étape par étape ce que fait mon code (F8), tout se passe bien jusqu'a arriver à la ligne Rows(i).Insert. Un fois arriver la j'appuie sur F8 et la ligne jaune (celle qui indique ou le code c'est arrêté) disparaît comme si le programme c'était terminé. Je n'ai aucun message d'erreur. Je peux être encore ajouté que le i contenant la ligne a insérer est obtenu via un Userform, qu'il est vérifié comme étant bien un numéric puis converti en long avec Clng

        J'espère avoir été le plus clair possible.

        PS : J'aimerai pouvoir transmettre le code mais il s'agit d'une donnée confidentiel :/
      5. @PierreBonjour,

        Tout ça ressemble à un dialogue sourds !

        Et le xla, il est confidentiel ???
        Dans tous les cas, dans un xla, il faut être bien plus rigoureux que ce que vois :
        - oublier les déclaration implicites !
        - oublier aussi les Select, ActiveSheet, etc...

        PS : Tu pourrais aussi remplacer les données confidentielles par des valeurs anonymisées
    4. Merci pour ta réponse. Ma macro est dans un fichier XLA a part (Module a part). Je vais essayer ta solution et je te tiens au courant
      1. Une question : ta macro est elle dans le module de la feuille concernées ou dans un module général (Module 1 par exemple)
        Si elle est dans un module général essaies comme ceci
        Public Sub OK()
        With ActiveSheet
        .Rows(48).Insert
        .Range("C49").Value = 2
        .Range("C50").Select
        End With
        End Sub
        1. Bonjour,

          Je viens de créer un fichier "similaire" au fichier qui me pose problème et le problème disparu dans ce nouveau fichier. Je ne peux pas donner le fichier original car il est confidentiel :/

          Je te remercie pour ton aide mais je vais devoir essayer de résoudre le problème seul dans le fichier original

          Cordialement,

          Pierre
          1. Je suppose que c'est du a un problème sur mon fichier mais je ne voit pas lequel
            Moi non plus ;-)
            Peux tu envoyer un bout de ton fichier anonymisé, mais avec la même structure que l'original,sur cjoint.com et joindre le lien obtenu à ton prochain message. N'oublies pas d'y ajouter des explications et des exemples de résultat attendu
            1) Tu vas dans https://www.cjoint.com/
            2) Tu cliques sur [Parcourir] pour sélectionner ton fichier
            3) Tu descends en bas de la page pour cliquer sur [Créer le lien Cjoint]
            4) Au bout de quelques secondes la deuxième page s'affiche, avec le lien
            en bleu souligné ; tu le sélectionnes et tu fais "Copier"
            5) Tu reviens dans ta discussion sur CCM, et dans ton message de réponse tu fais "Coller".

            Cdlmnt
            1. Sur ton fichier la macro fonctionne, sur le mien elle ne fonctionne pas :/ Je suppose que c'est du a un problème sur mon fichier mais je ne voit pas lequel :/
              1. Je viens de tester le code mais j'ai toujours le même problème : la macro s'arrête après le Rows(48).Insert et n'effectue pas la suite du code
                Sur ton fichier ou sur le mien ?
                1. Bonjour,

                  Merci pour ta réponse

                  Je viens de tester le code mais j'ai toujours le même problème : la macro s'arrête après le Rows(48).Insert et n'effectue pas la suite du code

                  Cdlmnt,

                  Pierre
                  1. Bonjour

                    Ton code (un peu simplifié) fonctionne
                    Public Sub OK()
                    Rows(48).Insert
                    Range("C49").Value = 2
                    Range("C50").Select
                    End Sub

                    http://www.cjoint.com/c/GGrjJS0onRB

                    Cdlmnt