Probleme USF, Excel 2016 plante
Bonjour à tous,
Etant amateur sur Excel, j'ai assemblé des codes par-ci par-là pour la gestion des livraisons, via un userform.
Tout fonctionnait bien jusque là, j'ai beaucoup été aidé grâce au forum et j'en profite pour remercier excel-pratique et tous ses contributeurs pour tout ça
...
Sauf que, je suis presque arrivé à la fin et... je suis confronté à un bug inexplicable.
...
C'est un userform qui ajoute / modifie / supprime des lignes issu d'un tableau structuré.
Dans ce même userform je fais appel à d'autres références : "consos" et "clients". Il y a donc 3 Ref en tout. Ces 3 refs font toutes appel à des tableaux structurés ("Suivi", "clients" et "consos")
Lorsque je clique sur l'userform : j'ai enregistré une macro pour qu'il affiche les livraisons en premiere place, du plus récent au plus ancien.
Lorsque je décharge l'urserform, une macro pour retrier par date.
Concrètement : je choisis une opération et quand je clique sur "Ajouter", excel 2016 plante (pas 2019... ca va être pratique
J'ai à peine le temps de voir le code d'erreur, Excel plante au bout de qqsec, mais j'ai fini par comprendre que le bug arrive à cause des segments qui sont dans l'onglet "Synthese".
L'idée des segments c'est de pouvoir filtrer les clients, le type de consommable, par date. Ca me plaisait bien comme ça et je suis triste de voir que ca bug à ce niveau.
Il est possible que le problème vienne du code, car lorsque je charge l'USF, que je modifie une opération (via le bouton Modifier..) , et qu'ensuite je clique sur "Ajouter une opération", pas de problèmes..
Donc en résumé, le bug ne se produit pas lorsque :
- Je supprime les segments de l'onglet Synthèse
- Je modifie d'abord une ligne via l'userform
Fichier original anonymisé
Ce fichier je le travaille un peu au boulot (Excel 2016), un peu chez moi (Excel 2019).. l'un plante, l'autre non. Incompréhensible à mon niveau
Je pense que j'ai transmis toutes les informations à ma connaissance.
Je vous remercie par avance pour toute aide / réflexion / amélioration.
Cordialement,
Bonjour,
code pas indenté, pas agréable à lire...
Etant sur 2019 je ne peux faire que faire des suggestions.
Teste en insérant une tempo avant le Unload pour voir ce que ça donne...
Application.Wait DateAdd("s", 1, Now())Tu n'as pas ligne de l'erreur ?
eric
Bonjour Eric,
Désolé
Alors ton idée est intéressante, je l'ai essayé un peu partout dans le module pour afficher le Userform.
Jusqu'à localiser plus précisément où le bug apparait : c'est finalement les macros de tri, lorsque je charge et décharge l'userform. Donc rien à voir avec les segments on dirait.
J'ai utilisé l'enregistreur de macro, qu'est-ce qui peut bien clocher ?
Sub Bouton1_Cliquer()
Range("A2").Select 'pour se placer dans le tableau "suivi"
'tri du type et de la date du plus récent au plus ancien :
ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort.SortFields.Add _
Key:=Range("Suivi[Type]"), SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort.SortFields.Add _
Key:=Range("Suivi[Date]"), SortOn:=xlSortOnValues, Order:=xlDescending, _
DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Load Userform1 'charger l'USF
Userform1.Show
'tri de la date uniquement, du plus récent au plus ancien :
ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort.SortFields.Add _
Key:=Range("Suivi[[#All],[Date]]"), SortOn:=xlSortOnValues, Order:= _
xlDescending, DataOption:=xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("A1").Select
End SubLa temporisation entre chaque étape ne permet pas d’empêcher le bug malheureusement.
Merci beaucoup,
Cordialement
Bonjour,
met un Stop en début de macro et juste après le .Show puis fait en pas à pas avec F8 pour essayer d'avoir la ligne en erreur.
Bien qu'en théorie ça ne soit pas nécessaire, Suivi est-elle la feuille active à ce moment là ? Essaie avec un Worksheets("Suivi").Select au début.
A quoi te servent les .Select ?
eric
Sub Bouton1_Cliquer()
Stop
Worksheets("Suivi").Select 'pour se placer dans le tableau "suivi"
'tri des livraisons en 1ere position, du plus récent au plus ancien
ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort.SortFields.Add _
Key:=Range("Suivi[Type]"), SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort.SortFields.Add _
Key:=Range("Suivi[Date]"), SortOn:=xlSortOnValues, Order:=xlDescending, _
DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort
.Header = xlYes
.MatchCase = FALSE
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Load Userform1 'charger l'USF
Userform1.Show
Stop
'à la sortie de l'useform, retri général du plus récent au plus ancien
ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort.SortFields.Add _
Key:=Range("Suivi[[#All],[Date]]"), SortOn:=xlSortOnValues, Order:= _
xlDescending, DataOption:=xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("Suivi").ListObjects("Suivi").Sort
.Header = xlYes
.MatchCase = FALSE
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("A1").Select
End SubJ'ai appliqué ce code, mais je n'ai aucun message d'erreur en faisant F8 (j'arrive sur l'Userform Initialize et ça boucle)
Merci :)
Cordialement
Edit : Je confirme : le .Select permettait de se placer dans le tableau "Suivi" (afin que les tris se fassent bien dans ce tableau), le dernier c'est juste pour se mettre en dehors
Pas d'erreur non plus en pas à pas après le UserForm ?
Et plus d'erreur non plus en marche normale avec l'ajout de Worksheets("Suivi").Select ?
Pas d'erreurs du tout en faisant le pas à pas avec F8, je suis allé vraiment jusqu'à la fin de la macro.
Et l'ajout de Worksheets("Suivi").Select ne permet pas de résoudre le problème en marche normale.
Bonsoir,
Je suis sur excel 2016 et je n'ai pas de bug
Par contre il y a un truc bizarre. Pourquoi vous mettez deux fois le tri dans le code bouton1_cliquez.
Là vous avez le code Bouton1_cliquez qui est en suspend jusqu'à ce que vous fermiez votre USF.
J'aurais plutôt fait ceci :
1. Ouverture USF
Sub Bouton1_Cliquer()
With ThisWorkbook.Worksheets("Suivi").ListObjects("Suivi")
'Range("A2").Select 'pour se placer dans le tableau "suivi"
.Sort.SortFields.Clear
.Sort.SortFields.Add Key:=Range("Suivi[Type]"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add Key:=Range("Suivi[Date]"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With .Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
Load Userform1 'charger l'USF
Userform1.Show
End Sub2. code de sortie USF
Private Sub CommandButton2_Click()
Unload Me
Call trier_sortie
End Sub3. dans le module userform_show (peut être renommer ce module ...), le code tri sortie
Sub trier_sortie()
'à la sortie de l'useform, retri général du plus récent au plus ancien
With ThisWorkbook.Worksheets("Suivi")
With .ListObjects("Suivi").Sort
.SortFields.Clear
.SortFields.Add Key:=Range("Suivi[[#All],[Date]]"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortTextAsNumbers
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
.select
.Range("A1").Select
End With
End SubNB : un plus, serait de bloquer la fermeture de l'USF par la croix. Du coup, cela oblige à passer par le bouton Fermeture et le code Trier_sortie
Cordialement
Bonjour,
Je suis sur excel 2016 et je n'ai pas de bug
Par contre il y a un truc bizarre. Pourquoi vous mettez deux fois le tri dans le code bouton1_cliquez.
Parce que je suis une quiche
Mais votre idée est meilleure, c'est plus logique. Je l'ai donc appliquée, mais malheureusement ça n'a pas résolu le plantage d'Excel.
J'insiste quand même sur une chose : lorsque je démarre l'USF et que je modifie une ligne, là je peux ajouter librement autant de lignes que je veux...
Il y a quelque chose qui est en conflit entre le fait de trier les données du tableau et d'ajouter une ligne dans le tableau, via l'USF. Mais quoi ?
J'ai cherché à contourner le problème en ne triant pas les données du tableau, mais en affichant uniquement les données de type "Livraison" , via le code Ref_Change... Je ne trouve rien pour l'instant.
Merci pour votre aide!
Cordialement,
Bonjour
J'insiste quand même sur une chose : lorsque je démarre l'USF et que je modifie une ligne, là je peux ajouter librement autant de lignes que je veux...
C'est un peu curieux sachant que les deux macros sont plus ou moins identiques
Pas sûr que cela va solutionner le souci mais essayez en remplaçant le code Ajouter2 par celui ci-dessous :
Private Sub Ajouter2_Click()
Dim ligne As Long
Dim tb As ListObject
Set tb = Sheets("Suivi").ListObjects("Suivi")
With tb
If .ListRows.Count = 0 Then
.ListRows.Add: ligne = 1
Else: .ListRows.Add: ligne = .ListRows.Count 'insérer à la dernière ligne
End If
With .DataBodyRange
.Item(ligne, 1) = CDate(TextBox1.Value)
.Item(ligne, 2) = op_type.Value
.Item(ligne, 3) = Ref2.Value
.Item(ligne, 4) = Ref3.Value
.Item(ligne, 5) = conso_condi.Value
.Item(ligne, 6) = conso_fam.Value
.Item(ligne, 7) = op_fam.Value
Select Case op_type.Value
Case Is = "Livraison"
.Item(ligne, 8) = op_qte.Value
.Item(ligne, 9) = (Val(Replace(Me.conso_puht, ",", ".")) * Val(Replace(Me.op_qte, ",", ".")))
Case Is = "Vente"
.Item(ligne, 10) = op_qte.Value
.Item(ligne, 11) = op_cout.Value
End Select
End With
End With
MsgBox "Opération ajoutée."
Unload Me 'permet de réactualiser la fenêtre UserForm
Call Bouton1_Cliquer
End SubCoridalement
Merci beaucoup !! La solution fonctionne ! Félicitations, par contre j'ai rien compris
J'ai trouvé un code sur le net, afin que la croix rouge de l'USF exécute le code de sortie (CommandButton2_Click) :
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
' how was the form closed?
' vbFormControlMenu = X in corner of title bar
If CloseMode = vbFormControlMenu Then
' cancel normal X button behavior
Cancel = True
' run code for click of Cancel button
CommandButton2_Click
End If
End SubPar contre j'ai du modifier la commande CommandButton2_Click, j'ai du mettre un Me.Hide en remplacement de Unload Me, sinon l'USF ne se fermait pas.
J'ignore la différence entre les deux, en tout cas ça n'a pas l'air de poser soucis.
Merci encore pour votre aide
Cordialement,
content que ce soit résolu !
Par contre j'ai du modifier la commande CommandButton2_Click, j'ai du mettre un Me.Hide en remplacement de Unload Me, sinon l'USF ne se fermait pas
Votre code comme ceci plutôt
Private Sub CommandButton2_Click()
Call trier_sortie
Unload Me
End SubFaite le tri avant de fermer l'USF
J'ignore la différence entre les deux, en tout cas ça n'a pas l'air de poser soucis.
HIDE : c'est pour masquer l'USF. Avec cette instruction votre USF reste active et est à l'arrière plan. Cette instruction n'est utile que si, par exemple, vous avez deux USF et que vous ne voulez pas voir l'USF1 lorsque vous êtes sur l'USF2. Une fois terminé vous pouvez réafficher sur l'USF1 en utilisant l'instruction SHOW.
Si vous en avez terminé avec une USF, UNLOAD est la bonne instruction à utiliser.
Cordialement
Votre code comme ceci plutôt
Private Sub CommandButton2_Click() Call trier_sortie Unload Me End Sub
C'est le code que j'ai utilisé au départ, mais la croix ne ferme pas l'userform, le tri fonctionne mais il reste affiché... Pas chez vous ?
Le fichier ...segment3.... ne servait pas. On peut le supprimer
C'est le code que j'ai utilisé au départ, mais la croix ne ferme pas l'userform,
Pas compris là. Il est normal que la croix ne ferme pas l'USF puisque vous avez mis un code pour l'éviter. Le but de code étant d'obliger l'utilisateur à fermer l'userform via le bouton fermeture formulaire. Du coup, le tri sera toujours effectué.
Dans le code Private Sub UserForm_QueryClose, vous devez donc enlever la ligne "CommandButton2_Click"
Désolé j'aurais dû vous le préciser
Crdlt
C'est peut être moi qui me suis mal exprimé : en fait, je cherche à faire en sorte que le clique sur la croix exécute le code CommandButton2_Click , ce qui revient à cliquer sur "Fermer la fenêtre", c'est mieux que d’empêcher l'utilisateur de cliquer sur la croix.
Et donc j'ai besoin de faire appel à CommandButton2_Click(dans Private Sub UserForm_QueryClose) , sauf qu'avec Me.Hide : l'USF est caché, mais Unload Me : l'USF ne se décharge pas. C'est en tout cas ce que ça fait chez moi avec le fichier segment3.
Merci,
Cordialement
Edit : cela dit, je me contenterais bien de Me.Hide, si ça ne pose pas de soucis à long terme ?
Après plusieurs essais, je me rendu compte que Me.Hide n'était pas bien du tout. J'ai finis par trouver la solution, j'ai simplement enlevé Cancel = True.
Encore merci pour toute cette aide.
Bonjour,
en fait, je cherche à faire en sorte que le clique sur la croix exécute le code CommandButton2_Click , ...
Et donc j'ai besoin de faire appel à CommandButton2_Click(dans Private Sub UserForm_QueryClose) ,
C'est rare cela ! En général, les utilisateurs demandent plutôt d'éviter la fermeture par la croix... De ma mémoire je n'ai pas encore vu une demande dans ce sens.
Donc tout de même pour répondre à votre question :
1. Fermeture via la croix. Votre code simplifié comme ceci :
Private Sub Userform_QueryClose(Cancel As Integer, CloseMode As Integer)
CommandButton2_Click
End Sub2. Interdiction de fermeture par la croix. Votre code comme ceci :
Private Sub Userform_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then MsgBox "Pour quitter veuillez cliquer sur le bouton Fermer la fenêtre", vbCritical, "Information"
Cancel = CloseMode = 0
End SubDans le cas point 2, l'utilisateur recevra un message l'informant qu'il doit quitter via le bouton "Ferme la fenêtre"
Cordialement