Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

VBA - Excel Combo box liées

faenor86

XLDnaute Nouveau
Bonjour à tous,

Je suis en train de réaliser des tests avant d'implémenter un formulaire dans classeur excel avec Macro.

Dans les grandes lignes voici le fonctionnement du formulaire :
J'ai 2 ComboBox :
1) La premier qui invite l'utilisateur à renseigner une AFFECTATION
2) La deuxième propose les comptes disponibles en fonction de l'affectation précédemment choisie

J'ai également deux étiquettes (type "Labels") qui afficheront des numéros de comptes en fonction du choisi dans la deuxième ComboBox.
En sachant que :
- l'essentiel de mes données sont inclus dans un onglet à part
- je récupère le contenu des valeurs de cet onglet répondant à un "code AFFECTATION" précédemment généré par l'utilisation de la ComboBox1

VB:
Option Explicit
Option Base 1


Sub Lancement()

Form_Saisie.Show

End Sub


Sub PopulateComboBoxSaisie1()

Dim TabCpt1() As String
Dim n, i As Integer

Form_Saisie.ComboBox1.Clear
n = Range("AFFECTATIONS").Rows.Count
ReDim TabCpt1(n) As String
For i = 1 To n
    TabCpt1(i) = Range("AFFECTATIONS").Cells(i, 1)
    Form_Saisie.ComboBox1.AddItem TabCpt1(i)
Next i
Form_Saisie.ComboBox1.Text = TabCpt1(1)

End Sub


Sub PopulateComboBoxSaisie2()
Dim NbLigne, NbCol, AffectType, i, j, CompteurOccurance As Integer

Form_Saisie.ComboBox2.Clear
AffectType = Form_Saisie.ComboBox1.ListIndex + 1
MsgBox (AffectType)
NbLigne = Range("PLAN_DE_COMPTES").End(xlDown).Row - 1
NbCol = 5
ReDim TabCptFull(NbLigne, NbCol) As Variant

For i = 1 To NbLigne
    If Range("PLAN_DE_COMPTES").Cells(i, 2) = AffectType Then
        For j = 1 To NbCol
            TabCptFull(i, j) = Range("PLAN_DE_COMPTES").Cells(i, j)
        Next j
        Form_Saisie.ComboBox2.AddItem Range("PLAN_DE_COMPTES").Cells(i, 3)
    End If
Next i


End Sub

Sub RecupCodeComptable()

'Dim NumOccur As Integer -> publiques
'Dim CompteGen, CompteAux As String -> en variables publiques

NumOccur = Form_Saisie.ComboBox2.ListIndex + 1
CompteGen = TabCptFull(NumOccur, 4)
CompteAux = TabCptFull(NumOccur, 5)
Form_Saisie.Label13.Caption = CompteAux
Form_Saisie.Label16.Caption = CompteGen

End Sub


Mes problèmes sont les suivants :
- Je n'arrive pas à afficher les comptes pour tous les choix
- J'ai de temps en temps une erreur d'exécution 9 - "l'indice n'appartient pas à la sélection" car j'ai l'impression qu'un listIndex d'une des ComboBox passe à -1 ! ce qui me parait étrange vu qu'il est censé commencer à 0....

ci-joint le fichier complet le cas échéant

Merci d'avance pour votre aide ! Cela fait quelques soirs que je patine...
 

Pièces jointes

  • COMBOBOX_test.xlsm
    43.1 KB · Affichages: 20

Dranreb

XLDnaute Barbatruc
Bonsoir.
Compte tenu du titre de la discussion je ne peux que vous proposer ce classeur conçu pour à s'installer en complément Excel et dont la référence au projet CBxL doit être ensuite cochée dans le projet VBA de votre classeur d'application.
L'objet ComboBoxLiées gère automatiquement les listes et les choix des ComboBox dont on lui confie la charge et s'appuyant sur différentes colonnes d'une même plage.

Ce simple et seul code dans votre UFm Form_Saisie suffit à assurer son fonctionnement :
VB:
Option Explicit
Private WithEvents CL As ComboBoxLiées, LCou As Long, TVL()
Private Sub UserForm_Initialize()
   Set CL = CBxL.Création.ComboBoxLiées
   CL.Plage Feuil4.[A2:F2], True
   CL.Add ComboBox1, 1
   CL.Add ComboBox2, 4
   CL.CouleurSympa
   CL.Actualiser
   End Sub
Après il reste plein de petites procédures à écrire pour exploiter son travail, effacer tout, afficher les info associées quand une seule ligne est trouvé, ajouter une nouvelle ligne, modifier ou supprimer celle trouvée. Mettez des TextBox pour les infos associées. L'autre UserForm ne sert à rien à priori.
Les premières procédures à suivre par exemple :
VB:
Private Sub CBnEffacer_Click()
   CL.Nettoyer
   End Sub
Private Sub CL_Change(ByVal Complet As Boolean, ByVal NbrLgn As Long)
   If NbrLgn = 1 Then Exit Sub
   LCou = 0
   ReDim TVL(1 To 1, 1 To CL.PlgTablo.Columns.Count)
   GarnirAutresContrôles
   End Sub
Private Sub CL_Résultat(Lignes() As Long)
   If UBound(Lignes) > 1 Then Exit Sub
   LCou = Lignes(1)
   TVL = CL.PlgTablo.Rows(LCou).Value
   GarnirAutresContrôles
   End Sub
Private Sub GarnirAutresContrôles()
   TBxLibellé.Text = TVL(1, 3)
   End Sub
(Avec un CommandButton nommé CBnEffacer et une TextBox TBxLibellé ajoutés)
 

Pièces jointes

  • CBxL.xlsm
    116.1 KB · Affichages: 26
Dernière édition:

faenor86

XLDnaute Nouveau
Bonsoir Dranreb,

Merci pour ton message. Je vais étudier ton fichier.
ça m'a l'air d'être une approche de codeur très confirmé !

Sinon, est-ce que quelqu'un aurait vu une bizzarerie dans mon code ? Ma méthode avec des tableaux dimensionnelles est certes plus rudimentaire mais en théorie elle devrait pouvoir marcher également....
 
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…