Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Application.Match & WorksheetFunction.Index "Erreur 2042"


Sujet :

Macros et VBA Excel

  1. #1
    Membre habitué
    Application.Match & WorksheetFunction.Index "Erreur 2042"
    Bonjour à tous et cordiales salutations,

    J'ai une feuille pour saisir les données qui vont alimenter et est complétée une base sur une autre page via un bouton et là erreur 2042 quand je clic sur celui-ci.

    Le problème vient de la recherche de position de la colonne "Nom" et la colonne "Type produit" de la feuille BDD.

    Quand le nom et le prénom n'existent pas, la variable contient "Erreur 2042" à la place de la ligne où se trouve l'information.

    Malgré mes recherches je n'ai pas trouvé comment coder pour intercepter cette erreur ?

    Voici ma procédure qui ne fonctionne pas :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Sub ChercheNomClientTypeProduit()
        Dim ValDésignation, ValConditionnement, ValeurCherchée, fe1, fe2, RéfProd, c
        Set fe1 = Sheets("Saisie")
        Set fe2 = Sheets("BDD")
        For Each c In fe1.Range("ZoneSaisie[Type produit producteur]") 'boucle colonne Type produit producteur
            ValDésignation = Application.Match(c, fe2.Range("Designation3"), 0)
            ValConditionnement = Application.Match("Type produit", fe2.Range("Conditionnement3"), 0)
            ValeurCherchée = WorksheetFunction.Index(fe2.Range("Prix3"), ValDésignation, ValConditionnement)
            If ValeurCherchée …. Then
                MsgBox "Ligne " & c.Row & " Type produit : " & Format(c, "000000") & " client : " & fe1.Range("type_doc_nom_client") & " n'existe pas !"
            Else
                MsgBox "Ligne " & c.Row & " Type produit : " & Format(c, "000000") & " client : " & fe1.Range("type_doc_nom_client") & " existe !"
            End If
        Next
    End Sub

    La question est "Que faire si les nom et prénom ne sont pas existants dans la feuille BDD" ?

    Est-ce que quelqu'un aurait une solution à pour cette situation ?

    Merci d'avance.

  2. #2
    Expert éminent
    Bonjour,

    il faut tester si la variable est une erreur

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    If IsError(MaVariable) Then 
        Msgbox "Pas Trouvé" 
    Else 
        Msgbox "Trouvé"
    End if

  3. #3
    Membre habitué
    Bonjour joe.levrai,

    Merci pour votre réponse, j'ai testé mais ça fonctionne pas.

  4. #4
    Responsable
    Office & Excel

    Salut.

    Et pourtant, Joe a raison .

    il faut placer le test au bon endroit et sur la bonne variable. Ce qui est susceptible de déclencher l'erreur, c'est le Match. C'est donc la variable récupérée par Match qui doit être testée.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Sub ChercheNomClientTypeProduit()
      Dim ValDésignation, ValConditionnement, ValeurCherchée, fe1, fe2, RéfProd, c
     
      Set fe1 = Sheets("Saisie")
      Set fe2 = Sheets("BDD")
      For Each c In fe1.Range("ZoneSaisie[Type produit producteur]") 'boucle colonne Type produit producteur
        ValDésignation = Application.Match(c, fe2.Range("Designation3"), 0)
        ValConditionnement = Application.Match("Type produit", fe2.Range("Conditionnement3"), 0)
        If IsError(valconditionnmen) Then
          MsgBox "Ligne " & c.Row & " Type produit : " & Format(c, "000000") & " client : " & fe1.Range("type_doc_nom_client") & " n'existe pas !"
        Else
          ValeurCherchée = WorksheetFunction.Index(fe2.Range("Prix3"), ValDésignation, ValConditionnement)
          MsgBox "Ligne " & c.Row & " Type produit : " & Format(c, "000000") & " client : " & fe1.Range("type_doc_nom_client") & " existe !"
      End If
      Next
    End Sub
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    Vous avez apprécié la réponse? =>
    ---------------

  5. #5
    Membre habitué
    Bonjour,

    Pierre Fauconnier merci pour votre réponse.

    J'ai testé avec :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    If IsError(ValConditionnement) Then


    Ça bug à la ligne :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    ValeurCherchée = WorksheetFunction.Index(fe2.Range("Prix3"), ValDésignation, ValConditionnement)

    Si je teste avec :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    If IsError(ValDésignation) Then

    Ça boucle sur la colonne "Type produit producteur" du tableau "Zone saisie" => réponse pour chaque chaque cellule : "Ligne x Type produit : ... Client ... n'existe pas !"

  6. #6
    Responsable
    Office & Excel

    Je ne peux que te donner une direction vers une solution, qu'il faut comprendre et adapter...

    MATCH est susceptible de renvoyer une erreur de type #N/A! (comme le ferait EQUIV côté Excel). Il faut donc tester les deux valeurs récupérées par MATCH, à savoir valconditionnment ET ValDésignation

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    If IsError(valconditionnment) Or IsError(ValDésignation) Then
      ...
    Else
     ...
    End If
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    Vous avez apprécié la réponse? =>
    ---------------

  7. #7
    Membre habitué
    Bonsoir le forum,

    De retour sur cette discussion et je persiste.

    J'ai essayé plusieurs possibilités :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    If IsError(ValDésignation) Then
        If IsError(ValConditionnement) Then
        If IsError(ValeurCherchée) Then
        If IsError(ValConditionnement) Or IsError(ValDésignation) Then
        If IsError(ValDésignation) And ValConditionnement > 0 Then

    Ça veut pas, je piétine et ne trouve pas de solution.

    Au demeurant avec la fonction Find ou VLookup cela ne fonctionne pas non plus.

    Pour mieux cerner le problème ci-joint 2 images synthétiques.

    Feuille "Saisie"


    Feuille "BDD"


    Dans le principe : suite au clic d'un bouton, rechercher le n° OP et le type de produit correspondant, si il existe il ne se passe rien, sinon il est ajouté à la BDD.

    En espérant avoir une réponse, cordiales salutations.

  8. #8
    Responsable
    Office & Excel

    Je ne comprends pas dans quel sens tu veux aller...

    Tu veux aller de la BDD vers la feuille de saisie ou l'inverse? De ce que je comprends, tu veux aller de BDD à Saisie. Mais les données de la feuille Saisie ne correspondent pas à ce qu'on voit dans la feuille BDD...
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    Vous avez apprécié la réponse? =>
    ---------------

  9. #9
    Membre habitué
    Je veux aller de la feuille de saisie vers la feuille BDD.

    Dans l'exemple que je présente, les Réf 002002 - 009008 - 010008 et le N° OP existe dans la BDD, mais la Réf 002001 et le N° OP n'existe pas dans la BDD je veux l'ajouter.

    Je sui navré j'ai fait trop rapidement l'exemple de saisie il y manque quelques champs que j'ai ajouté dans l'exemple corrigé ci-joint.

    Feuille Saisie



    Sur clic d'un bouton, si Réf 002001 et le N° OP n'existe pas dans la BDD, je souhaiterai ajouter une ligne au tableau avec les données : N° OP, date OP, ID client, Nom client, Prénom client, Réf et Type produit de la feuille Saisie.

    J'espère que c'est plus claire.

    @+

  10. #10
    Responsable
    Office & Excel

    L'idée est de travailler avec une formule EQUIV matricielle en VBA. Pour ce faire, on va utiliser EVALUATE qui permet de récupérer la valeur évaluée de la formule qu'on lui passe en paramètre. Je montre EQUIV dans Excel et elle est exprimée de façon générique dans le code au niveau de la constante GenericFormula (Attention, formule matricielle qui doit être validée avec SHIFT+CTRL+ENTER pour les versions antérieures à XL365/2019).





    Conception:

    • 1 tableau structuré de saisie t_Saisie;
    • 1 tableau structuré pour les données t_Base;
    • Quelques plages nommées pour faciliter les modifs de code qui contiendront les valeurs du "formulaire de paramètres".


    Les deux lignes entourées sont manquantes dans la DB et doivent être ajoutées




    Le déroulement du code:
    On boucle sur les lignes de saisie et on recherche la ligne correspondant à l'opération et au produit (ce sont les deux données clé de la ligne dans t_Base). Si on ne la trouve pas, on l'ajoute en créant un array avec les 7 données que l'on pousse sur la nouvelle ligne créée. Pour faciliter la rédaction de la formule qui doit contenir des données variables, on crée la formule générique avec des blocs de texte que l'on remplacera par les valeurs ({op} et {prod}).


    Le code
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Sub Test()
      Const GenericFormula As String = "match(1,(t_base[N°Op]=""{op}"")*(t_Base[Réf Produit]=""{prod}""),0)"
      Dim formula As String
      Dim r As ListRow
      Dim i
      Dim Target As Range, Values
     
      For Each r In Range("t_Saisie").ListObject.ListRows
        formula = Replace(GenericFormula, "{op}", Range("SaisieOp"))
        formula = Replace(formula, "{prod}", r.Range(1).Value)
        i = Evaluate(formula)
        If IsError(i) Then
          Set Target = Range("t_Base").ListObject.ListRows.Add().Range
          Values = Array(Range("SaisieOp").Value, Range("SaisieDate").Value, Range("SaisieID").Value, _
            Range("SaisiePrénom").Value, Range("SaisieNom").Value, r.Range(1).Value, r.Range(2).Value)
          Target.Value = Values
        End If
      Next r
    End Sub



    Le classeur



    A toi d'adapter. Le fait d'utiliser les plages nommées permet de coupler le plus faiblement possible le code à la structure de ton classeur. Ici, on ne peut pas modifier l'ordre des colonnes dans les tableaux, mais tu peux déplacer tes données où tu veux dans ton classeur grâce à l'utilisation des références structurées en VBA.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    Vous avez apprécié la réponse? =>
    ---------------

  11. #11
    Membre habitué
    Bonjour M. Pierre FAUCONNIER,

    Merci encore pour votre réponse, je suis absent jusqu'en fin d'après midi et je testerai dès mon retour.

    @+++

###raw>template_hook.ano_emploi###