Problème code VBA

Bonjour,

Je sollicite votre aide car je dois coder en VBA mais je suis une novice.

Alors j'ai deux classeurs (fichier ordo et fichier expe) : l'objectif est de rechercher chaque numéro de commande situé à la colonne K du fichier expe dans la colonne 3 du fichier ordo.

Si le numéro est trouvé dans la colonne 3, alors on va regarder une cellule correspondant à la quantité commandé (fichier ordo) et on revérifie que cette quantité est la même dans le fichier expe.

Si tous ces paramètres sont respectés alors on retourne dans le fichier ordo à la ligne correspondante et on rajoute un "OK" dans la colonne situation commande.

J'ai donc rédigé un code mais celui-ci ne fonctionne pas:

Public Sub Bouton_maj_Click()
'Cette macro compare les numéros de commandes du fichier ORDO et du fichier expédition

Dim fichier_expe_wk As Workbook: Dim fichier_ordo_wk As Workbook
Dim fichier_expe_ws As Worksheet: Dim fichier_ordo_ws As Worksheet

Dim plage_cmd_expe As Range: Dim Cell As Range
Dim cel_cmd_ordo As Range: Dim cel_cmd_expe As Range
Dim cel_situ_ordo As Range
Dim cel_qtity_ordo As Range: Dim cel_qtity_expe As Range

Set fichier_ordo_wk = ActiveWorkbook
Set fichier_ordo_ws = fichier_ordo_wk.Sheets("Cmdes modif")


Set fichier_expe_wk = Application.Workbooks.Open("D:\Users\Administrateur\Desktop\Projet pilotage de la ligne BB\sortie camion ordo.xlsx")
Set fichier_expe_ws = fichier_expe_wk.Worksheets(1)

With fichier_expe_ws
    'défini la plage à parcourir (ici la colonne des numéros de commande dans le fichier expé)
    Set plage_cmd_expe = Columns(11)
    
    'Pour chaque cellule de la colonne choisie on récupère la valeur du numéro de commande
    For Each Cell In plage_cmd_expe
        Set cel_cmd_expe = Cell
    
        'On se décale juqu'à la colonne quantité du fichier expédition
        Set cel_qtity_expe = cel_cmd_expe.Offset(0, -6)
        'Et on recherche ce numéro dans la colonne des commandes du fichier ordo
        
        Set cel_cmd_ordo = fichier_ordo_ws.Columns(3).Cells.Find(cel_cmd_expe.Value, LookAt:=xlWhole)
        MsgBox cel_cmd_ordo.Address
    
        'On sélectionne la cellule correspondante au numéro de commande dans ordo
        If cel_cmd_ordo Is Nothing Then
            MsgBox "La mise à jour n'a pas pu être effectuée"
        Else
            cel_cmd_ordo.Select
            'On se décale jusqu'à la colonne quantité du fichier ordo
            Set cel_qtity_ordo = cel_cmd_ordo.Offset(0, 8)
        
            'Comparaison entre la quantité dans ordo et dans expe
            If cel_qtity_expe.Value = cel_qtity_ordo.Value Then
                'On se décale jusqu'à la colonne situation commande afin de rentrer OK
                Set cel_situ_ordo = ActiveCell.Offset(0, 12).Activate
                cel_situ_ordo = "OK"
            Else
                cel_situ_ordo = ""
            End If
        End If
    Next Cell
End With
End Sub


Merci d'avance pour votre aide

EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ici : ICI

Merci d'y penser dans tes prochains messages.

7 réponses

  1. Re,

    Sans les fichier, il est difficile d'essayer le code.

    A la lecture (sans essai), il y a une erreur sur la ligne :
      Set plage_cmd_expe = Columns(11)
    
    Pour faire référence au fichier_expe_ws, il manque le point :
    With fichier_expe_ws
      Set plage_cmd_expe = .Columns(11)
      '[...]
    End With
    
    Mais comme le With n'est utilisé que dans cette instruction, à la place des 3 lignes, il est plus simple d'écrire :
    Set plage_cmd_expe = fichier_expe_ws.Columns(11)

    D'autre part, en VBA, il faut absolument éviter d'utiliser .Select
    Au lieu de :
    cel_cmd_ordo.Select
    '[...]
    Set cel_situ_ordo = ActiveCell.Offset(0, 12).Activate
    
    Ecrire :
    Set cel_situ_ordo = cel_cmd_ordo.Offset(0, 12)

    Et plus, je te déconseille vivement de faire référence aux objets actifs, c'est un source de problèmes très fréquents. Outre l'
    ActiveCell
    ci-dessus, au lieu de :
    Set fichier_ordo_wk = ActiveWorkbook
    
    Si le fichier contient la macro, Il vaut mieux :
    Set fichier_ordo_wk = ThisWorkbook
    
    et sinon :
    Set fichier_ordo_wk = Workbooks("NomDuFichier")


    1
    1. Contributeur
      bonjour, je suggère également d'expliciter "celui-ci ne fonctionne pas": message d'erreur, comportement inattendu, ...?
      0
  2. Bonjour,

    Quand tu postes du code sur le forum ...
    Utilises les balises de code avec indication du langage (=coloration syntaxique)
    Explications disponibles ici : Comment utiliser les balises de code
    Exemple :
    Sub UtiliserLesBalises()
      MsgBox "Merci d'utiliser les balises de code"
    End Sub

    0
    1. Bonjour,

      Je sollicite votre aide car je dois coder en VBA mais je suis une novice.

      Alors j'ai deux classeurs (fichier ordo et fichier expe) : l'objectif est de rechercher chaque numéro de commande situé à la colonne K du fichier expe dans la colonne 3 du fichier ordo.

      Si le numéro est trouvé dans la colonne 3, alors on va regarder une cellule correspondant à la quantité commandé (fichier ordo) et on revérifie que cette quantité est la même dans le fichier expe.

      Si tous ces paramètres sont respectés alors on retourne dans le fichier ordo à la ligne correspondante et on rajoute un "OK" dans la colonne situation commande.

      J'ai donc rédigé un code mais celui-ci ne fonctionne pas:

      Public Sub Bouton_maj_Click() 
      'Cette macro compare les numéros de commandes du fichier ORDO et du fichier expédition 
      
      Dim fichier_expe_wk As Workbook: Dim fichier_ordo_wk As Workbook 
      Dim fichier_expe_ws As Worksheet: Dim fichier_ordo_ws As Worksheet 
      
      Dim plage_cmd_expe As Range: Dim Cell As Range 
      Dim cel_cmd_ordo As Range: Dim cel_cmd_expe As Range 
      Dim cel_situ_ordo As Range 
      Dim cel_qtity_ordo As Range: Dim cel_qtity_expe As Range 
      
      Set fichier_ordo_wk = ActiveWorkbook 
      Set fichier_ordo_ws = fichier_ordo_wk.Sheets("Cmdes modif") 
      
      
      Set fichier_expe_wk = Application.Workbooks.Open("D:\Users\Administrateur\Desktop\Projet pilotage de la ligne BB\sortie camion ordo.xlsx") 
      Set fichier_expe_ws = fichier_expe_wk.Worksheets(1) 
      
      With fichier_expe_ws 
      'défini la plage à parcourir ici la colonne des numéros de commande dans le fichier expé
      Set plage_cmd_expe = Columns(11) 
      
      'Pour chaque cellule de la colonne choisie on récupère la valeur du numéro de commande 
      For Each Cell In plage_cmd_expe 
      Set cel_cmd_expe = Cell 
      
      'On se décale juquà la colonne quantité du fichier expédition 
      Set cel_qtity_expe = cel_cmd_expe.Offset(0, -6) 
      'Et on recherche ce numéro dans la colonne des commandes du fichier ordo 
      
      Set cel_cmd_ordo = fichier_ordo_ws.Columns(3).Cells.Find(cel_cmd_expe.Value, LookAt:=xlWhole) 
      MsgBox cel_cmd_ordo.Address 
      
      'On sélectionne la cellule correspondante au numéro de commande dans ordo 
      If cel_cmd_ordo Is Nothing Then 
      MsgBox "La mise à jour n'a pas pu être effectuée" 
      Else 
      cel_cmd_ordo.Select 
      'On se décale jusquà la colonne quantité du fichier ordo 
      Set cel_qtity_ordo = cel_cmd_ordo.Offset(0, 8) 
      
      'Comparaison entre la quantité dans ordo et dans expe 
      If cel_qtity_expe.Value = cel_qtity_ordo.Value Then 
      'On se décale jusquà la colonne situation commande afin de rentrer OK 
      Set cel_situ_ordo = ActiveCell.Offset(0, 12).Activate 
      cel_situ_ordo = "OK" 
      Else 
      cel_situ_ordo = "" 
      End If 
      End If 
      Next Cell 
      End With 
      End Sub 
      


      Merci d'avance pour votre aide
      0
      1. Public Sub Bouton_maj_Click() 
        'Cette macro compare les numéros de commandes du fichier ORDO et du fichier expédition 
        
        Dim fichier_expe_wk As Workbook: Dim fichier_ordo_wk As Workbook 
        Dim fichier_expe_ws As Worksheet: Dim fichier_ordo_ws As Worksheet 
        
        Dim plage_cmd_expe As Range: Dim Cell As Range 
        Dim cel_cmd_ordo As Range: Dim cel_cmd_expe As Range 
        Dim cel_situ_ordo As Range 
        Dim cel_qtity_ordo As Range: Dim cel_qtity_expe As Range 
        
        Set fichier_ordo_wk = ActiveWorkbook 
        Set fichier_ordo_ws = fichier_ordo_wk.Sheets("Cmdes modif") 
        
        
        Set fichier_expe_wk = Application.Workbooks.Open("D:\Users\Administrateur\Desktop\Projet pilotage de la ligne BB\sortie camion ordo.xlsx") 
        Set fichier_expe_ws = fichier_expe_wk.Worksheets(1) 
        
        With fichier_expe_ws 
        'défini la plage à parcourir ici la colonne des numéros de commande dans le fichier expé
        Set plage_cmd_expe = Columns(11) 
        
        'Pour chaque cellule de la colonne choisie on récupère la valeur du numéro de commande 
        For Each Cell In plage_cmd_expe 
        Set cel_cmd_expe = Cell 
        
        'On se décale juquà la colonne quantité du fichier expédition 
        Set cel_qtity_expe = cel_cmd_expe.Offset(0, -6) 
        'Et on recherche ce numéro dans la colonne des commandes du fichier ordo 
        
        Set cel_cmd_ordo = fichier_ordo_ws.Columns(3).Cells.Find(cel_cmd_expe.Value, LookAt:=xlWhole) 
        MsgBox cel_cmd_ordo.Address 
        
        'On sélectionne la cellule correspondante au numéro de commande dans ordo 
        If cel_cmd_ordo Is Nothing Then 
        MsgBox "La mise à jour n'a pas pu être effectuée" 
        Else 
        cel_cmd_ordo.Select 
        'On se décale jusquà la colonne quantité du fichier ordo 
        Set cel_qtity_ordo = cel_cmd_ordo.Offset(0, 8) 
        
        'Comparaison entre la quantité dans ordo et dans expe 
        If cel_qtity_expe.Value = cel_qtity_ordo.Value Then 
        'On se décale jusquà la colonne situation commande afin de rentrer OK 
        Set cel_situ_ordo = ActiveCell.Offset(0, 12).Activate 
        cel_situ_ordo = "OK" 
        Else 
        cel_situ_ordo = "" 
        End If 
        End If 
        Next Cell 
        End With 
        End Sub 
        <code basic>
        0
        1. Désolé pour le cafouillage du code !
          0
      2. Bonjour

        Merci pour vos conseils. Je reviens vers vous pour expliciter mes erreurs :

        Le code me renvoit une erreur 13 imcompatibilité de type sur la ligne avec la fonction find.

        Cel_cmd_expe est un Range et j'ai écris:

        Set cel_cmd_ordo = fichier_ordo_ws.Columns(3).Cells.Find(cel_cmd_expe.Value, LookAt:=xlWhole)
        0
        1. Contributeur
          et ainsi:
          Set cel_cmd_ordo = fichier_ordo_ws.Columns(3).Cells.Find(cel_cmd_expe.Value, , , xlWhole) 
          0
        2. Contributeur
          pour déterminer d'où vient l'erreur, essaie des variantes, ou décompose la ligne en plusieurs parties:
          Set cel_cmd_ordo = fichier_ordo_ws.Columns(3).Cells.Find(cel_cmd_expe.Value) 

          ou
          dim v, rs as range
          v=cel_cmd_expe.Value
          Set rg  = fichier_ordo_ws.Columns(3).Cells
          set cel_cmd_ordo = rg.Find(v, LookAt:=xlWhole)

          cela t'aidera à déterminer quelle partie d'une ligne complexe pose problème.
          0
        3. <code csharp>
          For Each Cell In plage_cmd_expe
          Set cel_cmd_expe = Cell
          MsgBox cel_cmd_expe.Address
              
          'On se décale juqu'à la colonne quantité du fichier expédition
          Set cel_qtity_expe = cel_cmd_expe.Offset(0, -6)
          MsgBox cel_qtity_expe.Address
          'Et on recherche ce numéro dans la colonne des commandes du fichier ordo
                  
          v = cel_cmd_expe.Value
          Set rg = fichier_ordo_ws.Columns(3).Cells
          
          Set cel_cmd_ordo = rg.Find(v, LookAt:=xlWhole)
          MsgBox cel_cmd_ordo.Address
              
              'On sélectionne la cellule correspondante au numéro de commande dans ordo
              If cel_cmd_ordo Is Nothing Then
                  MsgBox "La mise à jour n'a pas pu être effectuée"
              Else
                  'On se décale jusqu'à la colonne quantité du fichier ordo
                  Set cel_qtity_ordo = cel_cmd_ordo.Offset(0, 8)
                  MsgBox cel_qtity_ordo.Address
                  
                  'Comparaison entre la quantité dans ordo et dans expe
                  If cel_qtity_expe.Value = cel_qtity_ordo.Value Then
                          'On se décale jusqu'à la colonne situation commande afin de rentrer OK
                          Set cel_situ_ordo = cel_cmd_ordo.Offset(0, 13)
                          MsgBox cel_situ_ordo.Address
                          cel_situ_ordo.Value = "ok"
                      Else
                          cel_situ_ordo.Value = " "
                  End If
                  MsgBox cel_situ_ordo.Value
              End If
          Next Cell
          <code basic>


          Le code fonctionne sauf qu'il n'écrit que dans la dernière cel_situ_ordo visitée : ais-je mal positionné le if ?

          Savez vous comment parcourir toute la colonne K sans l'entête et ce jusqu'à la dernière ligne remplie ?

          J'imaginais chercher la dernière ligne remplie du fichier expe avec (xlUp).Row mais bon ce n'est qu"une idée
          0
        4. Contributeur
          @Anonyma23donc plus d'erreur 13?
          0
        5. Contributeur
          @Anonyma23tu écris "le if": duquel parles-tu?
          à quelle ligne de code veux-tu parcourir la colonne K?
          0
      3. J'essaie d'envoyer deux fichiers tests (expe et ordo) mais je n'arrive pas à les insérer . Savez vous comment insérer des fichiers excels sur le forum ?
        0
        1. Bonne nouvelle ! Mon code fonctionne.
          J'aurais une dernière question : sauriez vous comment convertir une date yymmdd en date ddmmyy ?

          Je le mets ci-dessous si besoin .

          <code csharp>
          Public Sub Bouton_maj_Click()
          'Cette macro compare les numéros de commandes du fichier ORDO et du fichier expédition
          'Description des variables
          Dim fichier_expe_wk As Workbook: Dim fichier_ordo_wk As Workbook
          Dim fichier_expe_ws As Worksheet: Dim fichier_ordo_ws As Worksheet
          Dim Nom_fichier_expe As Variant
          
          Dim plage_cmd_expe As Range: Dim Cell As Range
          Dim cel_cmd_ordo As Range: Dim cel_cmd_expe As Range
          Dim cel_situ_ordo As Range
          Dim cel_qtity_ordo As Range: Dim cel_qtity_expe As Range
          Dim cel_date_expe As Range: Dim cel_del_usine As Range
          Dim dernière_ligne_utilisée As Long
          
          Set fichier_ordo_wk = ThisWorkbook
          Set fichier_ordo_ws = fichier_ordo_wk.Sheets("Cmdes modif")
          
          Nom_fichier_expe = Application.GetOpenFilename("Classeurs Excel(*.xlsx),*.xlsx,Macros complémentaires(*.xls),*.xls")
          Set fichier_expe_wk = Application.Workbooks.Open(Nom_fichier_expe)
          Set fichier_expe_ws = fichier_expe_wk.Worksheets(1)
          'Chercher la dernière ligne non vide du fichier expedition
          dernière_ligne_utilisée = fichier_expe_ws.Range("K" & Rows.Count).End(xlUp).Row
          
          'défini la plage à parcourir (ici la colonne des numéros de commande dans le fichier expé)
          Set plage_cmd_expe = fichier_expe_ws.Range("K2:K" & dernière_ligne_utilisée)
              
          'Pour chaque cellule de la colonne choisie on récupère la valeur du numéro de commande
          For Each Cell In plage_cmd_expe
          Set cel_cmd_expe = Cell
          
          'On se décale juqu'à la colonne quantité du fichier expédition
          Set cel_qtity_expe = cel_cmd_expe.Offset(0, -6)
          'On se décale jusqu'à la colonne date chargement du fichier expédition
          Set cel_date_expe = cel_cmd_expe.Offset(0, 5)
          
          'Et on recherche ce numéro dans la colonne des commandes du fichier ordo
          Set cel_cmd_ordo = fichier_ordo_ws.Columns(3).Cells.Find(cel_cmd_expe.Value, LookAt:=xlWhole)
              
              'On sélectionne la cellule correspondante au numéro de commande dans ordo
              If cel_cmd_ordo Is Nothing Then
                  MsgBox "La mise à jour n'a pas pu être effectuée"
              Else
                  'On se décale jusqu'à la colonne quantité du fichier ordo
                  Set cel_qtity_ordo = cel_cmd_ordo.Offset(0, 8)
                  'On se decale jusquà la colonne del_usi du fichier ordo
                  Set cel_del_usine = cel_cmd_ordo.Offset(0, 9)
                  
                  'Comparaison entre la quantité et la date del_usine et expe dans ordo et dans expe
                  If cel_qtity_expe.Value = cel_qtity_ordo.Value And cel_date_expe.Value = cel_del_usine.Value Then
                      'On se décale jusqu'à la colonne situation commande afin de rentrer OK
                      Set cel_situ_ordo = cel_cmd_ordo.Offset(0, 13)
                      cel_situ_ordo.Value = "ok"
                  Else
                      Set cel_situ_ordo = cel_cmd_ordo.Offset(0, 13)
                      cel_situ_ordo.Value = " "
                  End If
              End If
          Next Cell
          MsgBox "La mise à jour est terminée"
          End Sub
          <code basic>
          0
          1. Contributeur
            où se trouve la date à convertir?
            0
          2. @yg_beLa date serait cel_date_expe à la ligne 35 du code.

            Dans le fichier excel expedition la valeur écrite est 261118 mais le fichier excel le traduit comme 18/11/2026 alors que cela devrait être 26/11/18.
            0
          3. Contributeur
            @Anonyma23suggestion pour obtenir une date:
            Dim cel_date_expe As Range, date_expe As Date
            Dim val As Long
            val = cel_date_expe.Value
            date_expe = DateSerial(2000 + val \ 10000, (val Mod 10000) \ 100, val Mod 100)
            0
          4. @yg_beCette fonction ne me renvoit pas d'erreur mais j'obtiens la date 26/10/2006 au lieu de 26/11/2018
            0
          5. Contributeur
            @Anonyma23
            Dim cel_date_expe As Range, date_expe As Date
            Dim val As Long
            val = cel_date_expe.Value
            date_expe = DateSerial(2000 + val Mod 100 , (val Mod 10000) \ 100,   val \ 10000)
            0