Find multiple avec 2 combobox et doublons

Résolu
Morgan67700 Messages postés 30 Date d'inscription   Statut Membre Dernière intervention   -  
Morgan67700 Messages postés 30 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour le forum,

J'ai un petit soucis au niveau de la programmation VBA d'un userform. Je m'explique, j'aimerai bien pouvoir retrouver ou reprendre les informations que j'ai dans une base de données (onglet excel: Data_Pliage2) à l'aide de deux combobox "POSTE" et "AIDE" situé dans un userform. J'ai quelque fois le même poste (exemple du format: 0218) mais Avec et Sans aide donc OUI ou NON dans le combobox "AIDE". J'aimerai bien pouvoir tout d'abord choisir le poste puis l'option aide ou non qui affichera des informations différentes selon ces deux critères. Mais je suis un peu perdu: le mettre dans Sub POSTE_Change() ou Sub AIDE_Change() ou les deux et puis comment gérer les deux critères de choix avec doublons du coup ( Poste: 0218/Aide: OUI et Poste 0218/Aide: Non par exemple) pour lire les infos de la colonne dans mon cas. Je poste des screens pour un peu montrer l'environnement dans lequel je suis. (Userform et Base de donnée) et mon code userform. La liste du combobox POSTE s'établit bien en fonction de ce que j'ai dans la base mais la boucle de doublons dans POSTE_Change prends seuelement la première valeur trouvée et non la deuxième s'il y en a une. Et je ne vois aps comment intégrer le choix du deuxième combobox en fonction des doublons...

Private Sub POSTE_Change()

Dim adresse_poste As Range ' Déclaration des variables adresses, ligne et colonne
Dim colonne As Integer
Dim ligne_TP As Integer
Dim ligne_AIDE As Integer
Dim ligne_TOBTU As Integer
Dim ligne_TDROIT As Integer
Dim ligne_TAIGU As Integer


If UserForm5.POSTE.Value <> "" Then ' Vérification s'il y a une valeur dans combobox "Poste"


Set adresse_poste = Range("POSTE_PLAGE").Find(CDbl(UserForm5.POSTE.Value)) 'Cherche l'adresse de la cellule de poste concerné exemple format poste: 0218
    
If adresse_poste Is Nothing Then   ' Test si l'on trouve les données pour le poste selectionné

MsgBox ("Informations Poste incomplètes !!")

Else
        colonne = adresse_poste.Column   ' Colonne concerné par les infos que l'on veut ci-dessous
Do
Set adresse_poste = Range("POSTE_PLAGE").FindNext(adresse_poste)

Loop While Not adresse_poste Is Nothing And adresse_poste.Column <> colonne


        ligne_TP = Range("TP_PLAGE").Row   ' Ligne de plage des temps perdu
        ligne_AIDE = Range("AIDE_PLAGE").Row   ' Ligne de plage de l'aide
        ligne_TOBTU = Range("TOBTU_PLAGE").Row   ' Ligne de plage de TEMPS OBTU
        ligne_TDROIT = Range("TDROIT_PLAGE").Row   ' Ligne de plage de TEMPS DROIT
        ligne_TAIGU = Range("TAIGU_PLAGE").Row   ' Ligne de plage de TEMPS AIGU
     
With Sheets("Data_Pliage2")
     
    TP.Value = .Cells(ligne_TP, colonne).Value
    AIDE.Value = .Cells(ligne_AIDE, colonne).Value
    TOBTU.Value = .Cells(ligne_TOBTU, colonne).Value
    TDROIT.Value = .Cells(ligne_TDROIT, colonne).Value
    TAIGU.Value = .Cells(ligne_TAIGU, colonne).Value
    
End With

End If

Else
    
End If
        
End Sub


Private Sub UserForm_Initialize()

    MAJ.Enabled = False
    
       ' Reprends les valeurs précédentes pour ne pas les effacer
           
Dim i As Integer
Dim DernCol As Integer
Dim a As Integer
Dim b As Integer

    a = Range("DPOSTE1").Row  ' Ligne concernée
    b = Range("DPOSTE1").Column + 1 ' Colonne de départ pour la liste
    DernCol = Range("DPOSTE1").End(xlToRight).Column ' Colonne de fin pour la liste
    
    For i = b To DernCol                    'Prends les postes existants
        POSTE.AddItem Sheets("Data_Pliage2").Cells(a, i).Text
    Next i
        AIDE.AddItem "Oui"
        AIDE.AddItem "Non"
End Sub







A voir également:

4 réponses

pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761
 
Bonjour,

1- Pour une meilleure lisibilité de vos messages, merci d'utiliser la coloration syntaxique du code, comme je vous l'ai fait. Le mode d'emploi est ici : la coloration syntaxique

2- Des images, même jolies comme les votres ;-), ne nous servent à rien. Il vaut toujours mieux mettre un classeur exemple. Pour cela, il convient d'utiliser un site de pièce jointe comme cjoint. Mode d'emploi

Dans l'attente.
1
Morgan67700 Messages postés 30 Date d'inscription   Statut Membre Dernière intervention   1
 
Je te remercie, le code je ne savais pas comment faire :$ Le fichier est assez riche en infos sensibles du coup je vais faire un classeur exemple.
0
pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761 > Morgan67700 Messages postés 30 Date d'inscription   Statut Membre Dernière intervention  
 
Pour réaliser un classeur exemple, respecte surtout l'emplacement et le type des données, mais également les noms des feuilles, des objets etc...
0
Morgan67700 Messages postés 30 Date d'inscription   Statut Membre Dernière intervention   1
 
Le classeur exemple se trouve sur cjoint: http://www.cjoint.com/c/EFcmsZmomwF
Pour rappel, mon problème est que je n'arrive pas à faire une boucle avec les deux combobox de l'userform 1. Et cela pour lier les choix du poste (avec doublons) puis le choix de l'aide (oui ou non). C'est pour avoir un aperçu des données ajoutés précédemment et les modifier par la suite en les rajoutant dans une nouvelle colonne.
0
pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761
 
Bon.
Voici comment je vois les choses.

1- on remplit la combobox POSTE sans doublon.
Pour cela le code est à changer dans UserForm_Initialize.
Remplacer :
For i = b To DernCol   
  POSTE.AddItem Sheets("Data_Pliage2").Cells(a, i).Text
Next i

par :
For i = b To DernCol
  POSTE.Value = Sheets("Data_Pliage2").Cells(a, i).Text
  If POSTE.ListIndex = -1 Then POSTE.AddItem Sheets("Data_Pliage2").Cells(a, i).Text
Next i


2- Il ne faut pas choisir l'événement Change de la combobox POSTE. Change sert lorsque l'on saisit, pas lorsque l'on sélectionne.
Pour la sélection, il faut choisir l'événement Click.
Changer donc :
Private Sub POSTE_Change()

en :
Private Sub POSTE_Click()


3- Dans cette procédure, on va différencier deux cas supplémentaires : si doublon de poste ou pas.
Si doublon alors
===> On remplit AIDE de oui et non
===> On vide le reste des contrôles
Si pas doublon
===> on remplit tout comme tu le faisait.
Pour cela, deux codes :
l'événement Click de la combobox POSTE :
Private Sub POSTE_Click()
Application.ScreenUpdating = False
Dim adresse_poste As Range ' Déclaration des variables adresses, ligne et colonne
Dim colonne As Integer
Dim ligne_DATE As Integer
Dim ligne_TP As Integer
Dim ligne_AIDE As Integer
Dim ligne_TOBTU As Integer
Dim ligne_TDROIT As Integer
Dim ligne_TAIGU As Integer


If UserForm1.POSTE.Value <> "" Then ' Vérification s'il y a une valeur dans combobox "Poste"
   Set adresse_poste = Range("POSTE_PLAGE").Find(CDbl(UserForm1.POSTE.Value)) 'Cherche l'adresse de la cellule de poste concerné exemple format poste: 0218
   If adresse_poste Is Nothing Then   ' Test si l'on trouve les données pour le poste selectionné
      MsgBox ("Informations Poste incomplètes !!")
   Else
      colonne = adresse_poste.Column   ' Colonne concerné par les infos que l'on veut ci-dessous
      'Si POSTE est en doublon
      If WorksheetFunction.CountIf(POSTE_PLAGE, CDbl(UserForm1.POSTE.Value)) > 1 Then
         'sil y a doublon, on remplit uniquement AIDE par Oui et non
         AIDE.AddItem "oui"
         AIDE.AddItem "non"
         'on vide les autres contrôles
         JOUR.Value = ""
         TP.Value = ""
         AIDE.Value = ""
         TOBTU.Value = ""
         TDROIT.Value = ""
         TAIGU.Value = ""
      Else
         'Do
         '   Set adresse_poste = Range("POSTE_PLAGE").FindNext(adresse_poste)
         'Loop While Not adresse_poste Is Nothing And adresse_poste.Column <> colonne
         ligne_DATE = Range("DATE_PLAGE").Row ' Ligne de plage de la date
         ligne_TP = Range("TP_PLAGE").Row   ' Ligne de plage des temps perdu
         ligne_AIDE = Range("AIDE_PLAGE").Row   ' Ligne de plage de l'aide
         ligne_TOBTU = Range("TOBTU_PLAGE").Row   ' Ligne de plage de TEMPS OBTU
         ligne_TDROIT = Range("TDROIT_PLAGE").Row   ' Ligne de plage de TEMPS DROIT
         ligne_TAIGU = Range("TAIGU_PLAGE").Row   ' Ligne de plage de TEMPS AIGU
         With Sheets("Data_Pliage2")
            JOUR.Value = .Cells(ligne_DATE, colonne).Value
            TP.Value = .Cells(ligne_TP, colonne).Value
            AIDE.Value = .Cells(ligne_AIDE, colonne).Value
            TOBTU.Value = .Cells(ligne_TOBTU, colonne).Value
            TDROIT.Value = .Cells(ligne_TDROIT, colonne).Value
            TAIGU.Value = .Cells(ligne_TAIGU, colonne).Value
         End With
      End If
   End If
End If
Application.ScreenUpdating = True
End Sub


Il faut supprimer le remplissage de la combobox AIDE dans l'Userform_Initialize :
Private Sub UserForm_Initialize()
    MAJ.Enabled = False
   ' Reprends les valeurs précédentes pour ne pas les effacer
   If JOUR.Value = "" Then
      JOUR.Value = Date
   End If
Dim i, DernCol, a, b As Integer

    a = Range("POSTE").Row  ' Ligne concernée
    b = Range("POSTE").Column + 1 ' Colonne de départ pour la liste
    DernCol = Range("POSTE").End(xlToRight).Column ' Colonne de fin pour la liste
    
    For i = b To DernCol                    'Prends les postes existants
      POSTE.Value = Sheets("Data_Pliage2").Cells(a, i).Text
      If POSTE.ListIndex = -1 Then POSTE.AddItem Sheets("Data_Pliage2").Cells(a, i).Text
    Next i
    POSTE.ListIndex = -1
End Sub


4- Le chargement des données lors d'une sélection dans la combobox AIDE :
Il te faut ajouter, dans le module de l'userform, l'événement AIDE_Click, avec le code suivant :
Private Sub AIDE_Click()
Dim DernCol As Integer, a As Integer, b As Integer, c As Integer
'si les combobox AIDE et/ou POSTE sont vides => on quitte avec message sans rien faire.
If AIDE = "" Or POSTE = "" Then MsgBox ("Informations incomplètes !!"): Exit Sub
'Ici les 2 sont remplies
'on cherche la colonne qui répond aux deux critères :
DernCol = Range("POSTE").End(xlToRight).Column ' Colonne de fin pour la liste
a = Range("POSTE").Row
b = Range("POSTE").Column + 1
c = Range("AIDE").Row
For i = b To DernCol                    'Prends les postes existants
   If POSTE.Value = CStr(Sheets("Data_Pliage2").Cells(a, i).Text) And AIDE.Value = CStr(Sheets("Data_Pliage2").Cells(c, i).Text) Then
      'remplissage
      ligne_DATE = Range("DATE_PLAGE").Row ' Ligne de plage de la date
      ligne_TP = Range("TP_PLAGE").Row   ' Ligne de plage des temps perdu
      ligne_AIDE = Range("AIDE_PLAGE").Row   ' Ligne de plage de l'aide
      ligne_TOBTU = Range("TOBTU_PLAGE").Row   ' Ligne de plage de TEMPS OBTU
      ligne_TDROIT = Range("TDROIT_PLAGE").Row   ' Ligne de plage de TEMPS DROIT
      ligne_TAIGU = Range("TAIGU_PLAGE").Row   ' Ligne de plage de TEMPS AIGU
      With Sheets("Data_Pliage2")
         JOUR.Value = .Cells(ligne_DATE, i).Value
         TP.Value = .Cells(ligne_TP, i).Value
         AIDE.Value = .Cells(ligne_AIDE, i).Value
         TOBTU.Value = .Cells(ligne_TOBTU, i).Value
         TDROIT.Value = .Cells(ligne_TDROIT, i).Value
         TAIGU.Value = .Cells(ligne_TAIGU, i).Value
      End With
      Exit For
   End If
Next
End Sub


Ton fichier exemple

A noter :
Toute variable DOIT être déclarée. Tu ne le fais pas.
Toutes les macros pourraient être raccourcies en nombre de lignes de code. Je ne te l'ai pas fait pour que tu gardes la maitrise et la compréhension de ton code.
1
Morgan67700 Messages postés 30 Date d'inscription   Statut Membre Dernière intervention   1
 
Je te remercie pour ta réponse et le code réalisé. J'ai effectivement un code assez lourd et non simpliste je pense, vu que je suis débutant dans le VBA. Et c'est vrai que les variables n'étaient soit pas déclarées soit mal déclarées .
Cependant j'ai un problème au niveau du poste 0214 par exemple. Il n'y a pas de doublon et donc quand je clique sur le combobox "Aide" et qu'après je clique autre part, il me met: "Valeur de propriété non valide". Je pense que c'est parce qu'il n'y a rien dans son additem étant donné que c'est seulement le contenu qu'il recopie. J'ai essayé de lui administrer la valeur qu'il recopie dans son additem mais je n'y suis pas arrivé. Il compile x termes dans le additem du combobox "Aide" quand je regarde la liste des choix il y a des "oui" et des "non" qui se rajoutent.

Ensuite je l'ai modifié pour avoir en plus la date à choisir avec un troisième combobox pour pouvoir maîtriser et garder les anciennes valeur, mais je suis toujours et encore bloqué car il faut que la colonne de donnée corresponde au choix du poste, de l'aide et de la date.

Mon fichier exemple: http://www.cjoint.com/c/EFdjVgo22zF
0
pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761
 
On ne peut pas, en programmation, ajouter des rustines à des rustines... Il faut que tu penses le projet dans sa globalité, que tu en écrives un cahier des charges avec ce que tu veux faire et le moyen d'y parvenir.
Sans cela, chaque changement induit tellement de variation dans les codes qu'il faut systématiquement tout recommencer.
Ici tu ajoutes encore un critère "date", ce qui fait que tout est à refaire...

A ce stade, il faut refaire la quasi-totalité du code de ton Userform.
Alors :
1- décris moi ton fichier ou envoie un extrait plus complet que celui fournit,
2- décris moi exactement ce que tu veux faire...
0
Morgan67700 Messages postés 30 Date d'inscription   Statut Membre Dernière intervention   1
 
Ce n'est pas évident à expliquer mais c'est vrai que je n'ai pas bien définit ce que je voulais, je vais donc essayer d'être plus clair et de te décrire au maximum le résultat attendu.

L'onglet "Data_Pliage2" est une base qui doit recueillir un ensemble de données qu'on saisit dans l'userform 1. Ici vient la rectification que j'ai faite pour l'userform2: lorsqu'on a un nouveau poste à créer ou un temps perdu à renseigner ou modifier, on clique sur le bouton "Modifications postes", on rentre son numéro de poste et son temps perdu dans l'userform 2. Le bouton "Ajouter" si c'est un nouveau poste et un bouton "Modifier" pour modifier le temps perdu du poste déjà existant. Les postes et leur temps perdu ainsi crées vont se rajouter/modifier dans la feuille Data_Pliage2 et dans la plage POSTE et TP où on y retrouve que les numéros des postes et leur temps perdu.

Ensuite dans l'userform 1 lorsqu'il n'y pas pas de données pour le poste selectionné (existants), j'aimerai bien lui administrer le critère Aide (oui ou non), la date du jour et ses temps de processus "temps pli obtu, droit et aigu" lorsqu'on met à jour.
(Je laisserai la vision du temps perdu pour garder un oeil dessus et la modification sera bloquée dans le texbox TP).
Lorsque le combobox Poste sélectionne un Poste et ne trouve aucune Date et aucun critère Aide, le combobox JOUR prend la date du jour et les textbox sont à 0 et il faut donc compléter les données.

Lorsque des infos sont déjà enregistrées dans la base, j'aimerai bien pouvoir les revoir à l'aide des combobox POSTE, JOUR et AIDE (oui ou non) pour simplement les vérifier ou bien les modifier.

A chaque fois qu'on clique sur Mettre à jour on rajoute une colonne avec les modifications et la date du jour.
Faut-il mettre une autre base temporelle en place (horaire par exemple) pour pouvoir sélectionner les modifications du même jour? Car sans cela la boucle trouvera des doublons de même numéro de poste, même critère d'aide et de même date, non?
Merci

http://www.cjoint.com/c/EFdoux4RxgL
0
pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761
 
Bonjour,

Ce qu'il me faudrait c'est une idée plus précise de la base réelle.
Là, dans ton exemple, je ne comprends pas l'utilité d'un userform, ta base fait 10 colonnes sur 8 lignes... Autant la remplir à la main.

Si j'ai bien saisi, de plus, tu ajoutes des données en colonne. Combien de colonnes au final?
Je te demande cela parce que ce serait certainement plus gérable en lignes...
Faut-il mettre une autre base temporelle en place (horaire par exemple) pour pouvoir sélectionner les modifications du même jour?
Essaye de remplacer
Date
par
Now
dans le code, tu verras une différence notable... Et de cette manière pas la peine d'ajouter un champ, chaque enregistrement sera unique du point de vue de sa "date".
0
Morgan67700 Messages postés 30 Date d'inscription   Statut Membre Dernière intervention   1
 
En vrai ma base fait 100/200 colonnes et 40/50lignes. Je ne mets pas tout pour éviter de s'embêter avec toutes les textbox et combobox et leurs adresses. Du coup les colonnes m'arrangent beaucoup et je ne dépasserais pas la capacité en colonne en principe. Merci je vais essayer de mettre
Now 
à la place de
Date
.
0
pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761 > Morgan67700 Messages postés 30 Date d'inscription   Statut Membre Dernière intervention  
 
En vrai ma base fait 100/200 colonnes et 40/50lignes. Je ne mets pas tout pour éviter de s'embêter
C'est la seconde meilleure façon (après "ne pas bien définir ce que l'on souhaite") pour que celui qui souhaite t'aider soit obligé de tout recommencer...encore.
Donc, passe nous, stp, un fichier conforme à la réalité
0
Morgan67700 Messages postés 30 Date d'inscription   Statut Membre Dernière intervention   1
 
C'est inutile de tout envoyer car se sont seulement des textbox's supplémentaires qui permettent de lire et ajouter les données en place ou non quand on met à jour bouton "mettre à jour". Les colonnes servent de capacité pour enregistrer les données, du coup les plages sont plus grandes, c'est pas un soucis ça normalement. Il me faudrait juste le code idéal pour lire les données en fonction de ses trois combobox: Poste, Jour et Aide. Ce sont les seuls variables qui pourront permettent de retrouver les données déjà enregistrées. Si le fichier exemple marche, la mise en place dans mon fichier ne se fera sans trop de mal, je suis assez confiant là-dessus.

http://www.cjoint.com/c/EFeiVE4u4fF
0
pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761 > Morgan67700 Messages postés 30 Date d'inscription   Statut Membre Dernière intervention  
 
Il te faut déterminer un ordre dans tes 3 choix :
1- Choix dans poste => remplit la combo date / choix dans date => remplit la combo aide
2- choix dans poste => remplit la combo aide / choix dans aide => remplit la combo date
3- autre choix...
0