Signaler

Mon code s'arrête après un Rows(i).insert [Résolu]

Posez votre question Pierre - Dernière réponse le 25 juil. 2017 à 11:30 par Pierre
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

Utile
+0
plus moins
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
Donnez votre avis
Utile
+0
plus moins
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 ?
Donnez votre avis
Utile
+0
plus moins
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 :/
Donnez votre avis
Utile
+0
plus moins
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 http://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
Donnez votre avis
Utile
+0
plus moins
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
Donnez votre avis
Utile
+0
plus moins
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
Donnez votre avis
Utile
+0
plus moins
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
Donnez votre avis
Utile
+0
plus moins
Je viens d'essayer la solution que m'a proposé mais ça n'est toujours pas concluant. Je vais continuer de chercher
Pierre- 17 juil. 2017 à 13:53
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
Répondre
jean- 17 juil. 2017 à 14:05
 
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.
 
Répondre
Pierre- 17 juil. 2017 à 14:14
En 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 :/
Répondre
Patrice33740 6130Messages postés dimanche 13 juin 2010Date d'inscription 14 septembre 2017 Dernière intervention - 17 juil. 2017 à 14:53
Bonjour,

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
Répondre
Pierre- 17 juil. 2017 à 15:08
Bonjour Patrice,

Je ne sais pas si j'arrive a bien me faire comprend :/. Je vais transmettre la partie du code qui pose problème et qui ne doit pas poser des problème de confidentialité :

Voici le code qui récupère le numéro de la ligne a ajouter


Private Sub Button_Cancel_Click()

Add_Line_window.Hide

End Sub

Private Sub Button_OK_Click()

Dim numberLine As Long

Add_Line_window.Hide

If CheckNumberInput(NumberOfLine_Input.Value) = True Then

numberLine = CLng(NumberOfLine_Input.Value)

Call Add_Line_Table(numberLine)
End If

End Sub

Function CheckNumberInput(windowInput) As Boolean


If IsNumeric(windowInput) = False Then
MsgBox "The input is not a number"
CheckNumberInput = False
Add_Line_window.Show
Exit Function
End If

If windowInput < 50 And windowInput > 19 Then
CheckNumberInput = True
Else
MsgBox "It's not possible to add a line at this line"
CheckNumberInput = False
End If

End Function



et le code qui permet d'ajouter et de modifier la suite du tableau



Sub Add_Line_Table(lineNumber As Long)


'Not work
'Rows(lineNumber).Insert

Cells(lineNumber, 3).Value = Cells(lineNumber - 1, 3).Value + 1
Cells(lineNumber, 3).Select

While ActiveCell.Row <> 50
ActiveCell.Value = ActiveCell.Offset(-1, 0).Value + 1
ActiveCell.Offset(1, 0).Select
Wend


End Sub



Voila j'espère que cela est plus clair
Répondre
Donnez votre avis
Utile
+0
plus moins
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
Patrice33740 6130Messages postés dimanche 13 juin 2010Date d'inscription 14 septembre 2017 Dernière intervention - 17 juil. 2017 à 17:21
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 !
Répondre
Pierre- 17 juil. 2017 à 17:47
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.
Répondre
Patrice33740 6130Messages postés dimanche 13 juin 2010Date d'inscription 14 septembre 2017 Dernière intervention - 17 juil. 2017 à 18:46
Vu 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
Répondre
Pierre- 17 juil. 2017 à 19:08
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
Répondre
Patrice33740 6130Messages postés dimanche 13 juin 2010Date d'inscription 14 septembre 2017 Dernière intervention - 17 juil. 2017 à 19:12
Vrai xla ou pas,le fait est qu'il s'agit d'un autre classeur donc les préconisation restent les mêmes
Répondre
Donnez votre avis
Utile
+0
plus moins
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.
 
Pierre- 17 juil. 2017 à 19:06
Merci Jean, j'essayerai ton code demain et je te tiendrai au courant des résultats

Bonne soirée
Répondre
Donnez votre avis
Utile
+0
plus moins
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
Donnez votre avis
Utile
-1
plus moins
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
Donnez votre avis

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !