Copier coller cellules sous conditions avec VBA
Bonjour la communauté Excel-Pratique,
Je sais que cette question revient souvent, mais même en lisant dans les autres sujets, je n'ai pas réussi à avoir ma réponse.
Je suis assez débutant sur VBA et je voudrais savoir comment résoudre ce problème SVP.
- 2 Feuilles de données et 2 Feuilles de résultats
- Dans les feuilles de résultat, on retrouve un équipement avec un état.
- Dans les feuilles de données, on retrouve les mêmes équipements (Pas en ordre) avec deux autres colonnes ( 6000- Changement ) + un compteur
Le but c'est de pouvoir, grâce à l'état dans les feuilles de résultats remplir les feuilles de données suivant la logique suivante :
- Etat = 1 ou 2 ou 3 : Case 6000 pour l'équipement en question reçoit la cellule du compteur, cellule changement ne reçoit rien.
-Etat = X : case changement reçoit le compteur (Eventuellement, pas obligatoire pour l'instant case 6000 reçoit le même compteur)
-Etat = Vide : Garder la même valeur.
PS : J'ai essayé avec la formule SI et ça marche, sauf que :
- en commettant une erreur, on ne peut plus faire marche arrière alors que grâce au VBA on aura possibilité de vérifier avant de mettre à jour.
- Je dois le faire manuellement alors qu'avec VBA j'espère que le code permettra de chercher la correspondance de l'équipement qui est présent à la fois dans la feuille données et résultats.
Je vous joins le fichier pour permettre une meilleure compréhension.
J'espère avoir été assez clair sur le sujet, sur ce je vous remercie d'avance pour toute aide.
Bonjour Nadir96,
Je te propose le code suivant :
Option Explicit
Dim dblCompteur1 As Double, dblCompteur2 As Double
Sub maj()
Dim oCell As Range
'On initialise les variables locales avec les valeurs de 2 compteurs
Set oCell = ThisWorkbook.Names("compteur1").RefersToRange
dblCompteur1 = oCell.Value
Set oCell = ThisWorkbook.Names("compteur2").RefersToRange
dblCompteur2 = oCell.Value
Dim oSheetResults As Worksheet, oSheetDonnees As Worksheet
Dim oLOResults As ListObject, oLODonnees As ListObject
'On affecte les variables worksheet et listobjects sur "Resul1" et "Donnees1"
Set oSheetResults = ThisWorkbook.Worksheets("Resul1")
Set oLOResults = oSheetResults.ListObjects("Tableau2")
Set oSheetDonnees = ThisWorkbook.Worksheets("DONNEES1")
Set oLODonnees = oSheetDonnees.ListObjects("Tableau6")
'On efface les données1
RAZDonnees oLODonnees
'On traite le tableau Resul1
processResults oLOResults, oLODonnees, dblCompteur1
'On affecte les variables worksheet et listobjects sur "Resul2" et "Donnees2"
Set oSheetResults = ThisWorkbook.Worksheets("Resul2")
Set oLOResults = oSheetResults.ListObjects("Tableau24")
Set oSheetDonnees = ThisWorkbook.Worksheets("DONNES2")
Set oLODonnees = oSheetDonnees.ListObjects("Tableau5")
'On efface les données2
RAZDonnees oLODonnees
'On traite le tableau Resul2
processResults oLOResults, oLODonnees, dblCompteur2
'On fait le ménage
Set oSheetResults = Nothing
Set oSheetDonnees = Nothing
Set oLOResults = Nothing
Set oLODonnees = Nothing
End Sub
'Traitement d'un tableau resul
Sub processResults(zLOResults As ListObject, zLODonnees As ListObject, zCompteur As Double)
Dim oRangeSel As Range
Dim oCellSel As Range
Dim oCellTo As Range
Dim aCollection() As Variant, i As Long
'On charge les valeurs contenues dans la colonne "Equip" des données dans une collection
aCollection() = zLODonnees.ListColumns("Equip").DataBodyRange.Value
'On affecte la plage de cellules de la colonne "etat" du tableau "Resul"
Set oRangeSel = zLOResults.ListColumns("etat").DataBodyRange
'On parcourt toutes les cellules de la plage
For Each oCellSel In oRangeSel
'On sélectionne suivant la valeur de la cellule
Select Case oCellSel.Value
Case 1, 2, 3
'Dans ce cas, on doit alimenter la colonne "CONTROL 6000"
'On recherche la ligne du tableau Données correspondant à l'équipement du tableau resul
For i = 1 To UBound(aCollection)
If aCollection(i, 1) = oCellSel.Offset(, -1).Value Then
'Lorsque l'on trouve une correspondance, on alimente la colonne "CONTROL 6000" et on sort de la boucle
Set oCellTo = zLODonnees.DataBodyRange.Cells(i, 3)
oCellTo.Value = zCompteur
Exit For
End If
Next
Case "X"
'Dans ce cas, on doit alimenter la colonne "Changement"
'On recherche la ligne du tableau Données correspondant à l'équipement du tableau resul
For i = 1 To UBound(aCollection)
If aCollection(i, 1) = oCellSel.Offset(, -1).Value Then
'Lorsque l'on trouve une correspondance, on alimente la colonne "Changement" et on sort de la boucle
Set oCellTo = zLODonnees.DataBodyRange.Cells(i, 4)
oCellTo.Value = zCompteur
Exit For
End If
Next
End Select
Next
'On fait le ménage
Set oRangeSel = Nothing
Set oCellSel = Nothing
Set oCellTo = Nothing
End Sub
Sub RAZDonnees(zLODonnees As ListObject)
Dim oRange As Range
'On affecte la plage correspondant à la colonne "CONTROL 6000" du tableau des "Donnees"
Set oRange = zLODonnees.ListColumns("CONTROL 6000").DataBodyRange
'On vide le contenu des cellules de la plage
oRange.ClearContents
'On affecte la plage correspondant à la colonne "Changement" du tableau des "Donnees"
Set oRange = zLODonnees.ListColumns("Changement").DataBodyRange
'On vide le contenu des cellules de la plage
oRange.ClearContents
'On fait le ménage
Set oRange = Nothing
End SubJe joins le classeur qui m'a servi pour les tests :
Par rapport à ton propre classeur, j'ai ajouté :
- 2 noms : "compteur1" et "compteur2" pointant sur les 2 cellules "compteur"
- un bouton "MAJ" dans la feuille "DONNEES1" pour lancer l'exécution de la macro "maj".
Bonjour Gérard,
Très bien fait, le code matche effectivement mon besoin, je t'en remercie.
J'avais réussi à me débrouiller en utilisant des formules SI.Conditions avec des ET/OU mais je me mettrai plus sur le tien. Ca me prendra un peu de temps pour tout repasser en VBA surtout que j'ai ajouté de nouvelles conditions pour le remplissage.
Cordialement