Find multiple avec 2 combobox et doublons

Résolu
Morgan67700 Messages postés 30 Statut Membre -  
Morgan67700 Messages postés 30 Statut Membre -
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




4 réponses

  1. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
     
    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
    1. Morgan67700 Messages postés 30 Statut Membre 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
      1. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773 > Morgan67700 Messages postés 30 Statut Membre
         
        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
    2. Morgan67700 Messages postés 30 Statut Membre 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
  2. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
     
    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
  3. Morgan67700 Messages postés 30 Statut Membre 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
    1. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
       
      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
  4. Morgan67700 Messages postés 30 Statut Membre 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
    1. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
       
      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
    2. Morgan67700 Messages postés 30 Statut Membre 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
    3. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773 > Morgan67700 Messages postés 30 Statut Membre
       
      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
    4. Morgan67700 Messages postés 30 Statut Membre 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
    5. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773 > Morgan67700 Messages postés 30 Statut Membre
       
      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