re
decaration abrégées
est l'equivalent deCode:dim toto&,titi%,fifi$,riri#
c'est des declarations a la ri(fifi..eu...kiki) de toto:mouarf:Code:dim toto as long,titi as integer,fifi as string,riri as double
;)
Version imprimable
re
bonjour qwazerty
sans doute a verifier
Merci pour tout vos code il sont tous très bien,
Je reviens vers Qwazerty pour m'assurer d'avoir bien compris son code.
Dans ton code le StrItemSelected prend l'ensemble des indices de la listbox en mémoire et transpose tout ses indice à Idel qui à travers la ligne
supprime dans le tableau l'indice +1 associer ?Code:ThisWorkbook.Worksheets(Feuille).ListObjects("List_" & Nom & Genre).ListRows(CLng(TabDel(iDel)) + 1).Delete
Est t'il possible que malgré la Rowsource qu'il y est un décalage d'indice et donc qu'il supprime la mauvaise ligne?
Ne serais t'il pas judicieux de faire une vérification sur le contenu avant de supprimé ? (Je me demande juste au cas ou je sais que tu gères bien ce genre de chose.)
Actuellement voici mon code pour ajouter et supprimer des lignes de ma listbox :
Pour ajouter :
Pour supprimerCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 Private Sub CommandButtonajoulist_Click() Dim LList As Object Set LList = CreateObject("Scripting.Dictionary") If Me.ListBoxList.ListCount <> 0 Then For Each Item In ListBoxList.list If Not LList.Exists(TextBoxAjouliste.Value) Then If Item <> "" Then LList.Add Item, Item End If End If Next Item If LList.Exists(TextBoxAjouliste.Value) Then MsgBox "Item déja présent dans la liste" Else LList.Add TextBoxAjouliste.Value, TextBoxAjouliste.Value Me.ListBoxList.RowSource = "" For Each Item In LList Me.ListBoxList.AddItem Item Next Item TextBoxAjouliste.Value = "" End If End If LList.RemoveAll End Sub
La ligne sert bien a figer l'actualisation de la listbox afin qu'aucun indice ne change ?Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 Private Sub CommandButtonSpprimer_Click() Dim iVal As Integer Dim iDel As Variant, TabDel As Variant Dim strItemSelected As String Dim Nom As String Dim LList As Object Dim Genre As String Feuille = ComboBoxTypeListes.Value Nom = ComboBoxNom.Value If ComboBoxNom.Value <> "" And ComboBoxTypeListes.Value <> "" Then If InStr(1, Feuille, "FT") <> 0 Then Genre = "FTS" ElseIf InStr(1, Feuille, "IT") <> 0 Then Genre = "IT" ElseIf InStr(1, Feuille, "DOS") <> 0 Then Genre = "DOS" Else Genre = "" End If End If 'Lorsqu'une ligne du tableau excel est supprimée, la listbox est immédiatement rafraichi et la sélection est perdue 'On fait donc une image à l'instant t des item à supprimer For iVal = 0 To ListBoxList.ListCount - 1 If ListBoxList.Selected(iVal) Then If strItemSelected <> "" Then strItemSelected = strItemSelected & "," strItemSelected = strItemSelected & CStr(iVal) End If Next If strItemSelected <> "" Then Application.ScreenUpdating = False 'On boucle sur les item à supprimer (toujours en sens inverse) TabDel = Split(strItemSelected, ",") For iDel = UBound(TabDel) To 0 Step -1 ThisWorkbook.Worksheets(Feuille).ListObjects("List_" & Nom & Genre).ListRows(CLng(TabDel(iDel)) + 1).Delete Next Application.ScreenUpdating = True End If End Sub
Cordialement,Code:Application.ScreenUpdating = xxx
Passepartout007
A ma connaissance non, le contenu du ListBox est à l'image exact du champs qui lui est lié. Pour s'en convaincre, il suffit de tester. Ajoutes un bouton CmdTri avec le code suivnat dans le fihcier transmis au dessus
Il change l'ordre de tri et la listbox est mise à jour immédiatement.Code:
1
2
3
4
5
6
7
8
9 Private Sub CmdTrier_Click() With Feuil1.ListObjects("Tab_Valeurs") 'On trie la colonne par orde alpha inverse .Sort.SortFields.Clear .Sort.SortFields.Add .ListColumns("Valeurs").DataBodyRange, xlSortOnValues, xlDescending .Sort.Apply End With End Sub
Pour le décalage de +1, c'est dû au fait que le ListBox travaille en Base 0 (sont 1er index est 0) alors que les tableau structuré travaille en base 1.
Utiliser un Dictionary pour tester si une valeur existe... c'est un peu comme utiliser un sabrelaser pour découper ses carrotes pour la soupe... ça fait riche ;)Citation:
Actuellement voici mon code pour ajouter et supprimer des lignes de ma listbox :
Pour ajouter :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 Private Sub CommandButtonajoulist_Click() Dim LList As Object Set LList = CreateObject("Scripting.Dictionary") If Me.ListBoxList.ListCount <> 0 Then For Each Item In ListBoxList.list If Not LList.Exists(TextBoxAjouliste.Value) Then If Item <> "" Then LList.Add Item, Item End If End If Next Item If LList.Exists(TextBoxAjouliste.Value) Then MsgBox "Item déja présent dans la liste" Else LList.Add TextBoxAjouliste.Value, TextBoxAjouliste.Value Me.ListBoxList.RowSource = "" For Each Item In LList Me.ListBoxList.AddItem Item Next Item TextBoxAjouliste.Value = "" End If End If LList.RemoveAll End Sub
Il existe moulte petits code sur le net pour rechercher une valeur dans une liste, ça sera tout aussi rapide.
Par contre ici ça n'est pas bon, tu dois garder le RowSource tel qu'il est, il suffit que tu mettes à jour le contenu de ton tableau sur ta feuille eXcel, le contenu du ListBox sera mis à jour tout seul par Excel.Citation:
Code:
1
2
3
4 Me.ListBoxList.RowSource = "" For Each Item In LList Me.ListBoxList.AddItem Item Next Item
Regarde dans le fichier au dessus le code du bouton Ajouter
Le code me semble OKCitation:
Pour supprimer
Si tu regardes dans l'aide Excel tu auras plus d'information sur l'utilisation de ScreenUpdating. On l'utilise pour figer le rafraichissement de la feuille Excel, pour que l'utilisateur ne voit pas les cellule changer de contenu les une après les autres, comme ça une fois mis à False, l'écran est rafraichi et toutes les modification s apparaissent d'un coup. C'est plus propre et beaucoup plus rapide lors de boucle importante car la rafraichissement prends beaucoup de temps.Citation:
La ligne sert bien a figer l'actualisation de la listbox afin qu'aucun indice ne change ?
Code:Application.ScreenUpdating = xxx
++
Qwaz
Bonjour,
Si tu avais mis un fichier, le pb serait déjà résolu.
Un exemple simple en PJ.
BoisgontierCode:
1
2
3 Private Sub B_enlève_Click() If Me.Dest.ListCount > 0 And Me.Dest.ListIndex <> -1 Then Me.Dest.RemoveItem Me.Dest.ListIndex End Sub
Bonjour,
J'ai pris en compte de tes conseil et j'ai donc retravailler sur le code et celui-ci semble fonctionner correctement.
L'ajout a la listbox :La suppression de la listbox :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 Private Sub CommandButtonajoulist_Click() Dim Nom As String Dim feuilles As String Dim Genre As String feuilles = ComboBoxTypeListes.Value Nom = ComboBoxNom.Value If ComboBoxNom.Value <> "" And ComboBoxTypeListes.Value <> "" Then If InStr(1, feuilles, "FT") <> 0 Then Genre = "FTS" ElseIf InStr(1, feuilles, "IT") <> 0 Then Genre = "IT" ElseIf InStr(1, feuilles, "DOS") <> 0 Then Genre = "DOS" Else Genre = "" End If End If Set Montablo = ThisWorkbook.Worksheets(feuilles).ListObjects("List_" & Nom & Genre) Dim LList As Object Set LList = CreateObject("Scripting.Dictionary") If Me.ListBoxList.ListCount <> 0 Then For Each Item In ListBoxList.list If Not LList.Exists(Item) Then If Item <> "" Then LList.Add Item, Item End If End If Next Item If LList.Exists(TextBoxAjouliste.Value) Then MsgBox "Item déja présent dans la liste" Else LList.Add TextBoxAjouliste.Value, TextBoxAjouliste.Value Range(Montablo).Columns(1).Resize(LList.Count) = Application.Transpose(LList.keys) End If End If LList.RemoveAll End Sub
Cela se passe merveilleusement bien, pendant la modification j'ai eu un cas ou je faisais apparaitre dans la liste deux fois FTS je n'ai pas compris pourquoi mais cela semble ne pas se répéter.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 Private Sub CommandButtonSpprimer_Click() Dim iVal As Integer Dim iDel As Variant, TabDel As Variant Dim strItemSelected As String Dim Nom As String Dim LList As Object Dim Genre As String Feuille = ComboBoxTypeListes.Value Nom = ComboBoxNom.Value If ComboBoxNom.Value <> "" And ComboBoxTypeListes.Value <> "" Then If InStr(1, Feuille, "FT") <> 0 Then Genre = "FTS" ElseIf InStr(1, Feuille, "IT") <> 0 Then Genre = "IT" ElseIf InStr(1, Feuille, "DOS") <> 0 Then Genre = "DOS" Else Genre = "" End If End If 'Lorsqu'une ligne du tableau excel est supprimée, la listbox est immédiatement rafraichi et la sélection est perdue 'On fait donc une image à l'instant t des item à supprimer For iVal = 0 To ListBoxList.ListCount - 1 If ListBoxList.Selected(iVal) Then If strItemSelected <> "" Then strItemSelected = strItemSelected & "," strItemSelected = strItemSelected & CStr(iVal) End If Next If strItemSelected <> "" Then Application.ScreenUpdating = False 'On boucle sur les item à supprimer (toujours en sens inverse) TabDel = Split(strItemSelected, ",") For iDel = UBound(TabDel) To 0 Step -1 ThisWorkbook.Worksheets(Feuille).ListObjects("List_" & Nom & Genre).ListRows(CLng(TabDel(iDel)) + 1).Delete Next End If Application.ScreenUpdating = True End Sub
Cordialement,
Passepartout007
Mon problème est résolut Grace a Qwazerty, je te remercie pour ta participation.
Il est demander dans l'édition du premier poste d'éviter d'introduire un fichier et d'expliquer clairement sont problèmes. C'est pour cela que je n'ais pas joint de fichier.
Cordialement,
Passepartout007
Penses à déclarer toutes tes variables (MonTablo ne l'est pas entre autre). Pour t'y obliger, place
Tout en haut de tes modulesCode:Option Explicit
[QUOTE=Passepartout007;10390332]
Attention ici tu ne précises pas la feuille dans laquelle tu places tes données.Code:
1
2 LList.Add TextBoxAjouliste.Value, TextBoxAjouliste.Value Range(Montablo).Columns(1).Resize(LList.Count) = Application.Transpose(LList.keys)
est compris par excel comme étantCode:Range(Montablo)
DoncCode:Range(Montablo.DataBodyRange.address)
Préfères plutot une écriture du styleCode:ActiveSheet.Range("A2:A11")
++Code:Montablo.ListColumns(1).resize(LList.count) = ...
Qwaz
Re Qwaz,
alors la variable Montablo est bien déclarée j'ai oublié effectivement de le préciser.
Concernant la feuille je précise bien dans la déclaration de mon tableau la feuille :Code:Public Montablo As ListObject
Cela correspond bien au bon tableau de la bonne feuille non ? Sauf si je doit encore le déclarer pour le Range.Code:Set Montablo = ThisWorkbook.Worksheets(feuilles).ListObjects("List_" & Nom & Genre)
Cordialement,
Passepartout007
Re Qwaz
Ta ligne de code me renvoi un erreur de type méthode non gérée par l'Object.
Re-EDIT
Apres quelque teste cela fonctionne correctement. Si tu pense qu'il y à vraiment un erreur avec Montablo je suis disposer à faire des testes supplémentaires.Citation:
Je viens de tester et mon code fonctionne correctement, il y a juste un problème d'actualisation de la Listbox quand je ne travail pas sur la page active effectivement je vais rechercher le problème tu a mis le doigt sur une erreur.
Je fais un retour des que j'ai trouver
Cordialement,
Passepartout007
Le soucis est lien à l'écriture Range(MonTablo) comme écrit au dessus, si la feuille active change, le code inscrira sur la nouvelle feuille active
essai
++Code:Montablo.ListColumns(1).Databodyrange.resize(LList.count) = ...
Qwaz
Je comprend bien ton explication mais à l'application quand j'ai une page active différente de celle ou je travail il copie les informations sur la bonne feuille et non sur la page active. Je ne l'explique pas mais cela a l'aire de fonctionner.
Cependant, ta ligne de code fonctionne aussi parfaitement, je vais donc l'utiliser pour éviter les erreurs futur.
Je marque le sujet comme résolu n'hésite pas si tu as d'autre points à aborder.
Cordialement,
Passepartout007
Salut
Autant pour moi, je viens de tester, mettre Range(Feuil1.range(...)) ne modifie pas le classeur/feuille parent tu as raison.
Ça fonctionne donc mais ça reste inutile ;) C'est comme si tu faisais
Pour testerCode:Range(ThisWorkbook.Sheets(...).Range("A1")).value
++Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 Sub test() Dim a As ListObject Dim b As Range Dim ws As Worksheet Dim wb As Workbook 'On pointe le tableau Set a = Feuil1.ListObjects("Tab_Valeurs") 'On pointe les données qu'il contient avec Range() Set b = Range(a) 'On regarde sur quelle feuille b pointe Set ws = b.Worksheet If ws Is Nothing Then MsgBox "Il n'existe pas de feuille précisée, le code utilisera donc la feuille active" Else MsgBox "On travaille sur la feuille " & ws.Name End If 'On regarde sur quel classeur Set wb = b.Worksheet.Parent If wb Is Nothing Then MsgBox "Il n'existe pas de classeur précisé, le code utilisera donc le classeur actif" Else MsgBox "On travaille sur le classeur " & wb.Name End If End Sub
Qwaz