XL 2010 Problème Listbox dans un Userform

chris

XLDnaute Barbatruc
Bonjour

J'ai voulu mettre une Lisbox dans un userform pour sélectionner un onglet dans la liste

La liste des onglets sélectionnable est issue d'une colonne de Tableau que je n'ai nommée.

Le UserForm permet également d'ajouter un onglet et donc d'allonger la liste .

Cela plante systématiquement dès que j'ajoute un item à la liste alors que si je sépare en 2 userforms l'ajout d'onglet et la listbox de navigation, tout fonctionne.

J'ai essayé d'ajouter une ligne de code après l'ajout dans la liste des onglets pour repréciser la source de la listbox mais j'ai l'impression que c'est le fait que le userform est affiché tandis que sa source évolue provoque le plantage.

Testé sur 2 versions de Windows (2010 et 365) avec le même problème.

Une idée ? Merci

Si besoin je posterai l'exemple
 

job75

XLDnaute Barbatruc
Bonjour chris, Dudu2, le forum,

Sur Excel 2019 je n'ai pas de problème en utilisant la propriété RowSource.

C'est intéressant : quoi qu'on fasse la sélection dans la ListBox impose l'onglet sélectionné.

Bonne journée.
 

Pièces jointes

  • Onglets(1).xlsm
    26 KB · Affichages: 11

chris

XLDnaute Barbatruc
Bonjour à tous

Merci job75

Mon cas est plus compliqué

Ci-joint
  • le classeur Onglets4b qui fonctionne (simplifié car je n'ai pas mis les divers contrôles notamment de non existance de l'onglet) mais qui ne met pas à jour la liste des onglets
  • le classeur Onglets7 qui plante systématiquement : j'ai tenté sans succès dans ce classeur
    de décharger le formulaire,
    de mettre la suite des opération dans un module standard,
    de ne pas mettre, comme conseillé par certains, le RowSource dans les propriétés de la listbox mais de la coder
Si je crées deux formulaires distincts cela fonctionne parfaitement.
C'est donc bien l'action sur la plage du RowSource de la listbox placée dans le même formulaire qui semble être le nœud du PB

J'y ai passé des heures sans trouver...

Merci d'avance
 

Pièces jointes

  • Onglets4b.xlsm
    41.7 KB · Affichages: 7
  • Onglets7.xlsm
    43 KB · Affichages: 8

_Thierry

XLDnaute Barbatruc
Bonsoir @chris , le fil

Je suis en train de regarder, en tout cas ca plante sur Office 2013 Pro Plus 32...
Et bien !!! LoL CTRL+ALT+SUP pour fermer Excel après une erreur d'automation...

Je continue à regarder mais je vais mettre mon masque LoL !
@+Thierry

Edit et ca prend du processor ton petit fichier
1588277796793.png
 

_Thierry

XLDnaute Barbatruc
Pourquoi tu as deux text box ?

Le Name Object et le Name Feuille ? Je ne capte pas pourquoi ? En tout cas à l'ouverture j'ai pu créer un onglet "Thierry" et je peux naviguer dessus et sur les autres onglets, j'avais tapé deux fois thierry, mais côté VBE ça n'a pas changer le nom d'object mais ça à mis à jour la Table...

1588278079334.png
1588278157208.png




Seconde tentative et là boum again :

1588278381545.png


Et ensuite plus rien ne fonctionne.....

1588278459683.png


Erreur sur Erreur pluis Excel plante , voilà pour ce qui se passe ....

Je ne comprends pas l'usage de cette Table et de "Liste" sinon ca ne plante pas avec le méthode AddItem

VB:
Private Sub UserForm_Initialize()
 Dim WS As Worksheet
 For Each WS In ThisWorkbook.Worksheets
    Me.List_Choix2.AddItem WS.Name
 Next WS
End Sub
C'est pour avoir "deux" noms possible ? je ne sais pas trop ?

@+Thierry
 

chris

XLDnaute Barbatruc
RE

C'est parce qu'à l'origine c'est le nom d'une association (nom à rallonge) qui apparait dans la listbox pour aller sur l'onglet dont le nom est juste le sigle de l'asso en 5 à 7 lettres sans espace ou autres caractère spécial

Pour poser le problème j'ai simplifié.

L'utilisateur utilise un bouton pour ouvrir le formulaire qui lui permet
  • soit de naviguer entre les divers onglets
  • soit d'ajouter une asso : le code doit dupliquer l'onglet modele, renommer la copie avec le sigle, inscrire le nom complet sur l'onglet, mettre à jour le tableau qui liste nom complet et nom d'onglet, classer le nouvel onglet alphabétiquement parmi les anciens.
Comme je l'ai dit, si je fait 2 boutons et deux formulaires différents tout marche impec, mais le fait d'avoir la listbox dont la source évolue sur le même formulaire que celui qui ajoute, ne plait pas du tout à Excel.
J'ai testé sur 2010 32bit et 365 64 bits, idem

Au début j'ai pensé à un souci dans le classeur posté par le demandeur mais en recréant un fichier de 0, tout simple pour ma demande, même PB...

Sur 2010 il me met "perte de connexion avec l'objet"...
Sur 365 reboot direct d'Excel... Et c'est toujours à la fin de l'écriture et tri du tableau
Si je mets ces étapes en commentaire no souci

Merci à toi d'avoir testé.
 

job75

XLDnaute Barbatruc
Bonjour chris, _Thierry, le forum,

Je n'ai toujours pas de problème, voyez ce fichier (2).

L'ajout d'une feuille se fait par ce code :
VB:
Private Sub CommandButton1_Click() 'Ajouter
Dim s As Object, nom As Variant
Set s = Sheets.Add(After:=Sheets(1))
MAJ
On Error Resume Next 'si le nom ne convient pas
Do
    Err = 0
    nom = Application.InputBox("Nom de la feuille :", "Ajouter une feuille", CStr(nom))
    If nom = False Then Application.DisplayAlerts = False: s.Delete: MAJ: Exit Sub
    s.Name = CStr(nom)
Loop While Err
Feuil1.[A3] = nom 'modifie la liste
End Sub

Sub MAJ()
ListBox1.RowSource = ""
ListBox1.RowSource = "Liste"
End Sub
Bien noter l'importance de la macro MAJ, voyez ce qui se passe si on ne s'en sert pas...

Bonne journée.
 

Pièces jointes

  • Onglets(2).xlsm
    33.1 KB · Affichages: 4

Hasco

XLDnaute Barbatruc
Bonjour le fil, chris,

Sur la base du fichier 'onglet7.xlsm' du post #4.
Ai modifié la Procédure MAJ dans laquelle vous déchargez UserForm2. en réinitialisant RowSource à vide :
VB:
UserForm2.List_Choix2.RowSource = ""
Unload UserForm2

Et tout semble fonctionner. Pas de plantage. Serait-ce dû à la rapidité d'exécution du code qui se poursuit avant le déchargement complet du userform non modal ???

Cordialement
 

Pièces jointes

  • Onglets7.xlsm
    54.3 KB · Affichages: 3

chris

XLDnaute Barbatruc
Bonjour

Merci à tous :) et particulièrement à

Roblochon :
Les 2 lignes permettent de garder le code initial et sa logique de mise à jour du tableau.

job75 : qui a aussi la même logique du RowSource = "" dans sa réponse

C'est bien là le nœud de la guerre !
"Dézinguer" le rowsource afin de bloquer son lien avec la source à ce moment là

Ouf !

Testé avec succès sur le fichier original
 

job75

XLDnaute Barbatruc
On peut utiliser la méthode .List pour remplir la ListBox, voyez ce fichier (3) :
VB:
Dim tablo$() 'mémorise la variable

Private Sub UserForm_Initialize()
Dim i%
ReDim tablo(Sheets.Count - 1)
For i = 0 To UBound(tablo) 'base 0
    tablo(i) = Sheets(i + 1).Name
Next
ListBox1.List = tablo
End Sub

Private Sub CommandButton1_Click() 'Ajouter
Dim s As Object, nom As Variant
Set s = Sheets.Add(After:=Sheets(1))
UserForm_Initialize 'mise à jour
On Error Resume Next 'si le nom ne convient pas
Do
    Err = 0
    nom = Application.InputBox("Nom de la feuille :", "Ajouter une feuille", CStr(nom))
    If nom = False Then Application.DisplayAlerts = False: s.Delete: ListBox1.RemoveItem 1: Exit Sub
    s.Name = CStr(nom)
Loop While Err
ListBox1.List(1) = nom 'modifie la liste
End Sub

Private Sub ListBox1_Click()
Sheets(ListBox1.Value).Activate
End Sub
Plus besoin de créer une liste dans la feuille de calcul.
 

Pièces jointes

  • Onglets(3).xlsm
    27.2 KB · Affichages: 9

job75

XLDnaute Barbatruc
Bonjour chris, le forum,
Merci
Mais le tableau (structuré) a d'autre usages et j'ai donc besoin et du nom long et de l'onglet correspondant...
Voici une solution assez élaborée dans ce fichier (4), le code de l'USF :
VB:
Const mdp$ = "chris" 'mot de passe à adapter

Private Sub UserForm_Initialize()
ListBox1.List = [Tableau1].Value 'à adapter
End Sub

Private Sub CommandButton1_Click() 'Ajouter
Dim s As Object, nom As Variant, ref As Variant
With [Tableau1] 'à adapter
    .Parent.Protect mdp, UserInterfaceOnly:=True
    .Parent.Parent.Unprotect mdp
    Application.ScreenUpdating = False
    Set s = Sheets.Add(After:=Sheets(1)) 'ajout d'une feuille
    .Parent.Select
    Application.ScreenUpdating = True
    nom = s.Name
    .Rows(2).Insert xlDown
    .Cells(2, 1) = nom
    ListBox1.List = .Value 'mise à jour
    On Error Resume Next 'si le nom ne convient pas
    Do
        nom = Application.InputBox("Nom de la feuille :", "Ajouter une feuille", CStr(nom))
        If nom = False Then Application.DisplayAlerts = False: s.Delete: ListBox1.RemoveItem 1: .Rows(2).Delete xlUp: GoTo 1
        s.Name = CStr(nom)
    Loop While s.Name <> CStr(nom)
    ListBox1.List(1) = nom 'modifie la liste
    .Cells(2, 1) = nom
    Do
        ref = Application.InputBox("Référence :", "Ajouter une feuille")
        If ref = False Then GoTo 1
    Loop While ref = ""
    ListBox1.List(1, 1) = ref 'modifie la liste
    .Cells(2, 2) = ref
    .EntireColumn.AutoFit 'ajustement largeur
1   .Parent.Parent.Protect mdp, True
End With
End Sub

Private Sub CommandButton2_Click() 'Supprimer
Dim i&
With ListBox1
    i = .ListIndex
    If i = -1 Then Exit Sub
    If i = 0 Then MsgBox "Suppression non autorisée...", 16, "Supprimer une feuille": Exit Sub
    If MsgBox("Supprimer '" & .Value & "' ?", 36, "Supprimer une feuille") = 7 Then Exit Sub
    .RemoveItem i
End With
With [Tableau1] 'à adapter
    .Parent.Protect mdp, UserInterfaceOnly:=True
    .Parent.Parent.Unprotect mdp
    Application.DisplayAlerts = False
    Sheets(CStr(.Cells(i + 1, 1))).Delete 'supprime la feuille sélectionnée
    .Rows(i + 1).Delete xlUp
    .EntireColumn.AutoFit 'ajustement largeur
    .Parent.Parent.Protect mdp, True
    .Parent.Select
End With
End Sub

Private Sub ListBox1_Click()
Sheets(ListBox1.Value).Activate
End Sub
A+
 

Pièces jointes

  • Onglets(4).xlsm
    30.8 KB · Affichages: 10
Dernière édition:

chris

XLDnaute Barbatruc
Bonjour

Merci, je vais regarder pour ma culture VBA

Mais la solution du RowSource="" ajouté à mon code a réglé problème.
Si tu regardes le fichier Onglets7 que j'avais posté, on trie le tableau et on déplace le nouvel onglet en fonction du tri.
Ce code était allégé par rapport au cas réel.
En ajoutant RowSource="" avant la ligne Unload UserForm2 (il est prévu qu'il se ferme dans mon cas)
tout marche dans le fichier réel.

Mais je garde ton code précieusement car il peut me resservir dans d'autres cas.
 

Statistiques des forums

Discussions
290 833
Messages
1 910 790
Membres
176 869
dernier inscrit
veusavoir
Haut Bas