Vlookup sur variable : Erreur 424

Résolu
Miss_marmotte Messages postés 1 Statut Membre -  
 Miss_marmotte -
Bonjour,
Je suis novice en VBA et j'ai beau chercher, je n'avance plus.
J'ai un onglet avec des lignes de détail de commandes et entre autres un montant associé, je veux donc créer un onglet qui me donne pour chaque numéro de commande son total (une ou plusieurs lignes de détail).
Je pensais utiliser Do While avec For each pour tenir compte de la possibilité (fréquente) de plusieurs lignes de détail pour une commande, mais je suis de toute façon restée bloquée à la phase antérieure. Qu'est-ce que je fais mal ?
Si quelqu'un peut m'aider, ce serait vraiment très sympa, merci d'avance

Voici mon code :
Option Explicit

Sub essai_totaux()

Application.DisplayAlerts = False

Dim Sh As Worksheet

Dim cdes As Range
Dim cde As Range

Set cdes = Worksheets("Récap").Range("a1").CurrentRegion.Resize(Worksheets("Récap").Range("a1").CurrentRegion.Rows.Count - 1, 1).Offset(1)
cde = Application.Min(Worksheets("Détails").Range("a:a")).Value

For Each Sh In Worksheets
    If Sh.Name = "Récap" Then
    Sh.Delete
    End If
Next

Sheets.Add(after:=Worksheets("Détails")).Name = ("Récap")

Worksheets("Détails").Activate
Columns("A:A").Copy Worksheets("Récap").Range("a1")
Worksheets("Récap").Range("a:a").RemoveDuplicates Columns:=1, Header:=xlYes
       
For Each cde In cdes

Worksheets("Récap").Cells(cde.Row, 2).Value = Application.VLookup(cde, Worksheets("Détails").Range("a:h"), 8, False)

Next cde

Application.DisplayAlerts = True

End Sub


EDIT : Ajout des balises de code.

4 réponses

  1. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830
     
    Bonjour,
    Je n'ai pas testé ton code.. mais déjà il me semble que tu as omis : WorkSheetFunction devant ton Vlookup

    Application.WorksheetFunction.VLookup(cde.value, Worksheets("Détails").Range("a:h"), 8, False)
    

    0
    1. Miss_marmotte
       
      Merci beaucoup de me répondre.
      Je croyais que le Worksheetfunction n'était pas obligatoire.
      Je l'ai ajouté mais ça ne change rien...
      Merci pour la "remise en forme de mon code", je n'ai pas compris comment faire quand j'ai posté ma question.
      0
      1. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830 > Miss_marmotte
         
        Tu as mis le .value sur cde (comme moi ) ?
        Une autre possibilité. .. change ton range de recherche sur une plage définie au leu des deux colonnes.
        Range ("a1:h5000")
        
        0
      2. Miss_marmotte > jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention  
         
        Bonjour Jordane,

        J'imagine que tu voulais dire ça :

        Worksheets("Récap").Cells(cde.Row, 2).Value = Application.VLookup(cde, Worksheets("Détails").Range("Plage_recherche"), 8, False)

        Ça ne change rien.

        Question idiote sans doute mais j'ai beau chercher, je ne trouve pas comment mettre le code en forme comme toi...
        Merci de ton aide.
        0
  2. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
     
    Bonjour Marmotte, Jordane45,

    Oula!
    Pas mal d'erreurs.

    Commençons par le début :
    Tu déclares
    Cde As Range
    et après tu cherches à lui attribuer une valeur numérique avec la fonction Min...
    Pas bon!

    La ligne :
    cde = Application.Min(Worksheets("Détails").Range("a:a")).Value

    ne te sers à rien???
    Si oui, supprimes là.

    En plus elle est totalement fausse et ne te renverra qu'un message d'erreur.

    Ensuite, plutôt que d'utiliser Application.WorkSheetFunction(blablabla), je te recommande l'utilisation de la méthode Evaluate en VBA. Plus simple, super maniable, beaucoup plus compréhensible.

    Par exemple, pour calculer la minimum de la colonne A :

    Dim monMini As Double
    monMini = Evaluate("MIN(A:A)")


    Difficile de faire plus simple...
    Ah si! En utilisant une autre écriture de la méthode Evaluate, les crochets :

    Dim monMini As Double
    monMini = [MIN(A:A)]


    Nota : lorsque l'on écrit la méthode Evaluate dans sa syntaxe complète (Evaluate("blabla")), son argument doit être de type String. Pas dans son écriture simplifiée. D'où l'absence des guillemets dans
    monMini = [MIN(A:A)]
    et leur présence dans
    Evaluate("MIN(A:A)")
    ...
    0
    1. Miss_marmotte
       
      Bonjour Pijaku,

      Merci à toi aussi de ton aide.
      Je croyais qu'il fallait initialiser la variable et c'est ce que j'ai tenté de faire avec la fonction Min.
      Peux-tu en revanche me dire pourquoi elle est totalement fausse ?
      J'avoue que je patauge complètement avec mes variables et je ne sais plus ce que je dois déclarer et comment pour faire ce que je voudrais faire.
      Merci beaucoup pour le tip pour Evaluate, je ne connaissais pas.
      Bien cordialement
      0
    2. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773 > Miss_marmotte
       
      1- Question idiote sans doute mais j'ai beau chercher, je ne trouve pas comment mettre le code en forme comme toi...
      Le mode d'emploi (au cas ou) est ICI.


      2- Reprenons ton code partie par partie.

      Option Explicit
      
      Sub essai_totaux()
      
      Application.DisplayAlerts = False
      

      Application.DisplayAlerts = False sert uniquement, dans ton cas, à ne pas voir le message en cas de suppression de feuille "récap".

      Dim Sh As Worksheet
      Dim cdes As Range
      Dim cde As Range

      Déclaration des variables. Ok.

      Jusqu'ici tout va bien.

      Set cdes = Worksheets("Récap").Range("a1").CurrentRegion.Resize(Worksheets("Récap").Range("a1").CurrentRegion.Rows.Count - 1, 1).Offset(1)

      Tu attribues, à ta variable Range cdes, un objet Range. Ok, tout va bien.
      Bon pour être honnête, la syntaxe utilisant les CurrentRegion et resize est pour le moins complexe. On pourrait simplifier si tu nous disais de quel Range il s'agit. Exemple : toute la colonne C...


      cde = Application.Min(Worksheets("Détails").Range("a:a")).Value

      te sers à "initialiser" ta variable cde...
      cde étant déclarée comme Range, cette ligne te renvoie une erreur.
      De plus, dans le reste du code, tu utilises cde dans une boucle For Each. Il n'y a donc pas besoin de l'initialiser.
      Donc... supprimes cette ligne!

      For Each Sh In Worksheets
          If Sh.Name = "Récap" Then
          Sh.Delete
          End If
      Next

      Te sers à supprimer une éventuelle "Récap" déjà faite.
      Bon, il y a plus simple et plus rapide pour supprimer une éventuelle feuille :
      On Error Resume Next 'désactive le gestionnaire d'erreurs
      'si elle n'existe pas, pas de message d'erreur car gestionnaire désactivé 
      Sheets("Récap").Delete 'supprime la feuille
      On Error Goto 0 'réactive le gestionnaire d'erreurs



      Sheets.Add(after:=Worksheets("Détails")).Name = ("Récap")
      Worksheets("Détails").Activate
      Columns("A:A").Copy Worksheets("Récap").Range("a1")
      Worksheets("Récap").Range("a:a").RemoveDuplicates Columns:=1, Header:=xlYes

      Ici, pas de souci, tu crées une nouvelle feuille Récap et tu y colles les données de la feuille Détails colonne A...

      For Each cde In cdes
          Worksheets("Récap").Cells(cde.Row, 2).Value = Application.VLookup(cde, Worksheets("Détails").Range("a:h"), 8, False)
      Next cde

      Ici tu boucle sur toutes les cellules de ta plage définie (cdes) pour appliquer tes RECHERCHEV (VLookUp).
      Attention aux remarques de Jordane45, sur
      Application.WorksheetFunction.VLookup


      Pour la fin, pas de souci :
      Application.DisplayAlerts = True
      End Sub


      Donc, ta macro pourrait s'écrire :
      Option Explicit
      
      Sub essai_totaux()
      Dim cdes As Range
      Dim cde As Range
      
      Application.DisplayAlerts = False
      Set cdes = Worksheets("Récap").Range("a1").CurrentRegion.Resize(Worksheets("Récap").Range("a1").CurrentRegion.Rows.Count - 1, 1).Offset(1)
      
      On Error Resume Next
      Sheets("Récap").Delete
      On Error Goto 0
      
      Sheets.Add(after:=Worksheets("Détails")).Name = ("Récap")
      
      Worksheets("Détails").Activate
      Columns("A:A").Copy Worksheets("Récap").Range("a1")
      Worksheets("Récap").Range("a:a").RemoveDuplicates Columns:=1, Header:=xlYes
             
      For Each cde In cdes
          Worksheets("Récap").Cells(cde.Row, 2).Value = Application.WorksheetFunction.VLookup(cde.value, Worksheets("Détails").Range("a:h"), 8, False)
      Next cde
      Application.DisplayAlerts = True
      End Sub
      0
    3. Miss_marmotte > pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention  
       
      Bonjour Pijaku,

      Je te remercie pour toutes tes précieuses indications.
      Malheureusement, avec mon code modifié ou le tien, ça ne fonctionne pas (la partie vlookup) je reçois toujours le message d'erreur 424.
      Je ne comprends pas pourquoi...
      Bien cordialement
      0
    4. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
       
      Bonjour,

      Il nous faut le classeur alors...
      Pour transmettre un fichier, il faut passer par un site de pièce jointe tel que cjoint.com

      Va sur ce site : https://www.cjoint.com/
      Clic sur parcourir,
      Cherche ton fichier,
      clic sur ouvrir,
      Clic sur "Créer le lien cjoint",
      Copier le lien,
      Revenir ici le coller dans une réponse...
      0
    5. Miss_marmotte > pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention  
       
      Bonjour Pijaku,

      Merci pour ta réponse et désolée du délai.
      Voici donc mon fichier en suivant tes constructions :
      http://cjoint.com/?0Lrnp5rgj3R
      Je souhaite donc à partir de l'onglet Détails pouvoir créer un onglet Récap qui affiche le total de chacune des commandes, celles-ci pouvant comporter plusieurs lignes de détail.
      Ma macro s'appelle essai_totaux et se trouve dans le module 2.
      J'espère que je suis assez claire.
      Et encore un grand merci pour ton aide.
      Bien cordialement
      0
  3. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
     
    Bon, je supposes que les réponses à mon dernier commentaires sont oui...

    Tout simplement, avec VLookup, tu étais hyper mal partie.
    Pour réaliser ta récap, rien de mieux qu'un objet dictionnary.
    Utilisé comme ceci :

    Sub Calcul_Toto()
    Dim myDico As Object, Tb(), i As Long
    'création de la feuille Récap
    Application.DisplayAlerts = False
    On Error Resume Next
    Sheets("Récap").Delete
    On Error GoTo 0
    Sheets.Add(after:=Worksheets("Détails")).Name = ("Récap")
    Application.DisplayAlerts = True
    'entêtes de colonnes de la feuille Récap
    With Sheets("Détails")
        .Range("A1").Copy Sheets("Récap").Range("A1")
        .Range("H1").Copy Sheets("Récap").Range("B1")
        'récolte des données
        Set myDico = CreateObject("Scripting.Dictionary")
        Tb = .Range("A2:H" & .Range("A" & Rows.Count).End(xlUp).Row).Value
    End With
    'calculs sous totaux
    For i = LBound(Tb, 1) To UBound(Tb, 1)
        myDico(Tb(i, 1)) = myDico(Tb(i, 1)) + Tb(i, 8)
    Next i
    'Restitution dans la feuille Récap
    With Sheets("Récap")
        .[A2].Resize(myDico.Count, 1) = Application.Transpose(myDico.keys)
        .[B2].Resize(myDico.Count, 1) = Application.Transpose(myDico.items)
    End With
    End Sub
    


    🎼 Cordialement,
    Franck 🎶
    0
  4. Miss_marmotte
     
    Bonjour Pijaku,

    Désolée, je ne reçois plus les alertes indiquant un nouveau message et je n'ai donc pas vu ta question.
    Je viens de faire tourner ton code et c'est effectivement exactement cela que je voulais. Je t'en remercie infiniment.
    En revanche, je t'avoue que je ne comprends pas grand chose pour l'instant à la nouvelle partie de code, n'ayant jamais entendu d'un objet dictionary notamment.
    Je vais donc travailler tout ça et je me permettrai de revenir vers toi si j'ai encore des questions.
    Aurais-tu un manuel ou un site à m'indiquer pour approfondir mes connaissances sur Excel VBA ?
    Merci encore.
    Bien cordialement
    0
    1. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
       
      De rien.
      En ce qui concerne l'objet dictionnary, tu trouveras un tuto ici :
      http://boisgontierjacques.free.fr/pages_site/Dictionnaire.htm

      Pour des liens vers des cours et tutos VBA, il y a ce forum, bien sur, mais également :
      - http://boisgontierjacques.free.fr/index2.htm
      - https://silkyroad.developpez.com/
      - https://www.excel-pratique.com/fr/vba.php
      etc...

      A++
      0
      1. Miss_marmotte > pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention  
         
        Merci pour ces liens.
        Ce n'est pas encore limpide mais je commence à mieux comprendre.
        Et ce dictionary est une vraie découverte !
        0