comparaison et copie de cellules excel avec macro

  • Initiateur de la discussion Initiateur de la discussion elijea
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

elijea

XLDnaute Nouveau
bonjour, j'aimerai avec une macro pouvoir comparer des cellules et faire ressortir un résultat sur une autre feuille
dans mon exemple l'idée est que une même personne ne peut pas avoir a la fois "oui" et "non" ni "oui" et "jamais" donc dans quand ça arrive les lignes ou le cas se présente doivent être copiée dans une autre feuille ou un autre classeur (et pas sur la même feuille comme dans mon image)
merci de votre aide, j'ai un peu de mal , pourtant cela semble assez simple
merci encore
6d5a2fbaae5360f454842c24433a58db.jpg
[/url][/IMG]
 
Re : comparaison et copie de cellules excel avec macro

Bonjour à toutes et à tous,

Bienvenue sur XLD, elijea 🙂 !

Pourrait-on avoir une copie, sans données confidentielles, du fichier de travail ?

A bientôt.

bonjour
merci pour la bienvenue et la réponse, voici la pièce jointe
 

Pièces jointes

  • tableau excel.jpg
    tableau excel.jpg
    28.8 KB · Affichages: 120
  • tableau excel.jpg
    tableau excel.jpg
    28.8 KB · Affichages: 135
  • tableau excel.jpg
    tableau excel.jpg
    28.8 KB · Affichages: 138
Re : comparaison et copie de cellules excel avec macro

bonjour
merci beaucoup, en lisant la macro c'est plus compliqué que ce que je pensais, c'est presque ça mais sur la deuxième feuille ne doivent apparaitre que les lignes ou la condition est respectée (ceux qui cumulent oui et non et oui et jamais) donc dans mon exemple que les 4 lignes colonne E et F
merci je vais essayer de faire de mon coté aussi
 
Re : comparaison et copie de cellules excel avec macro

Bonsoir le forum, elijea
Salut DoubleZero 🙂

Essaie ceci : le résultat s'affiche en Feuil2 .

Y a sûrement plus simple que les 2 if imbriqués dans la boucle Do Loop While 😛
VB:
Sub test1()
Derlig = 1
Set Cel = Sheets("Feuil1").Columns(2).Find("oui", after:=Range("B65536").End(xlUp), LookIn:=xlValues)
If Not Cel Is Nothing Then
  firstAddress = Cel.Address
    Do
      If Cel.Offset(1, 0) = "non" Or Cel.Offset(1, 0) = "jamais" Then
        If Cel.Offset(0, -1) = Cel.Offset(1, -1) Then
          Sheets("Feuil2").Cells(Derlig, 1).Resize(2, 2) = Sheets("Feuil1").Range("A" & Cel.Offset(0, 1).Row & ":B" & Cel.Offset(1, 1).Row).Value
          Derlig = Sheets("Feuil2").Range("A" & Sheets("Feuil2").Rows.Count).End(xlUp).Row + 1
        End If
      End If
      Set Cel = Sheets("Feuil1").Columns(2).FindNext(Cel)
    Loop While Not Cel Is Nothing And Cel.Address <> firstAddress
End If
End Sub
Une variante :
VB:
Sub test2()
Dim tablo1() As Variant
Derlig = Sheets("Feuil2").Range("A" & Sheets("Feuil2").Rows.Count).End(xlUp).Row
Set Cel = Sheets("Feuil1").Columns(2).Find("oui", after:=Range("B65536").End(xlUp), LookIn:=xlValues)
If Not Cel Is Nothing Then
  firstAddress = Cel.Address
    Do
      If Cel.Offset(1, 0) = "non" Or Cel.Offset(1, 0) = "jamais" Then
        If Cel.Offset(0, -1) = Cel.Offset(1, -1) Then
          x = x + 2
          ReDim Preserve tablo1(1 To 2, 1 To x)
          For y = 1 To 2
            tablo1(y, x - 1) = Sheets("Feuil1").Cells(Cel.Row, y)
            tablo1(y, x) = Sheets("Feuil1").Cells(Cel.Offset(1, 0).Row, y)
          Next y
        End If
      End If
      Set Cel = Sheets("Feuil1").Columns(2).FindNext(Cel)
    Loop While Not Cel Is Nothing And Cel.Address <> firstAddress
End If
On Error Resume Next
Sheets("Feuil2").Cells(Derlig, 1).Resize(UBound(tablo1, 2), 2) = Application.Transpose(tablo1)
On Error GoTo 0
End Sub
Une autre variante :
VB:
Sub test3()
Dim tablo1() As Variant
Derlig = Sheets("Feuil2").Range("A" & Sheets("Feuil2").Rows.Count).End(xlUp).Row
Set Cel = Sheets("Feuil1").Columns(2).Find("oui", after:=Range("B65536").End(xlUp), LookIn:=xlValues)
If Not Cel Is Nothing Then
  firstAddress = Cel.Address
    Do
      If Cel.Offset(1, 0) = "non" Or Cel.Offset(1, 0) = "jamais" Then
        If Cel.Offset(0, -1) = Cel.Offset(1, -1) Then
          x = x + 1
          ReDim Preserve tablo1(1 To 2, 1 To x)
          For y = 1 To 2
            tablo1(y, x) = Sheets("Feuil1").Cells(Cel.Row, y)
          Next y
          x = x + 1
          ReDim Preserve tablo1(1 To 2, 1 To x)
          For y = 1 To 2
            tablo1(y, x) = Sheets("Feuil1").Cells(Cel.Offset(1, 0).Row, y)
          Next y
        End If
      End If
      Set Cel = Sheets("Feuil1").Columns(2).FindNext(Cel)
    Loop While Not Cel Is Nothing And Cel.Address <> firstAddress
End If
On Error GoTo Erreur
Sheets("Feuil2").Cells(Derlig, 1).Resize(UBound(tablo1, 2), 2) = Application.Transpose(tablo1)
Exit Sub
Erreur:
MsgBox "Il n'y a rien à copier" & vbCr & "Cliquez sur OK pour terminer.", vbInformation
End Sub
.../...
'On Error GoTo Erreur
'Sheets("Feuil2").Cells(Derlig, 1).Resize(UBound(tablo1, 2), 2) = Application.Transpose(tablo1)
'MsgBox "Vos données ont été copiées" & vbCr & "Cliquez sur OK pour terminer.", vbInformation
'Exit Sub
'Erreur:
'MsgBox "Il n'y a rien à copier" & vbCr & "Cliquez sur OK pour terminer.", vbInformation
'End Sub

.../...
Une macro pour mémo :
VB:
Sub Copie_et_Tri_des_lignes_double()
derlign = 1
With Sheets("Feuil1")
 Set Plage = .Range("A1:A" & .Range("A65536").End(xlUp).Row)
 For i = 1 To Plage.Rows.Count
  If Application.CountIf(Plage, .Cells(i, 1).Value) = 2 Then
   Sheets("Feuil2").Cells(derlign, 1).Resize(, 2) = Sheets("Feuil1").Cells(i, 1).Resize(, 2).Value
   derlign = derlign + 1
  End If
 Next i
End With
'Tri_des_données_de_la_Feuil2
'Tri croissant sur la plage champ A
Sheets("Feuil2").Range("A1:B" & Sheets("Feuil2").Range("A65536").End(xlUp).Row).Sort Key1:=Sheets("Feuil2").Range("A1"), _
Order1:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
'Puis tri décroissant par bloc de 2 Lignes champ B
dl = Sheets("Feuil2").Range("A65536").End(xlUp).Row
x = 1
Do
    y = Sheets("Feuil2").Range("A" & x + 1).Row
    Set plg = Sheets("Feuil2").Range("A" & x & ":B" & y)
    plg.Sort Key1:=Sheets("Feuil2").Range("B" & x), Order1:=xlDescending, Header:=xlNo
    x = y + 1
Loop Until x > dl
End Sub

Klin89
 
Dernière édition:
Re : comparaison et copie de cellules excel avec macro

Re-bonjour,

Une dernière tentative dans le fichier joint, bien que la présentation finale ne corresponde pas à l'illustration du #1 😱 !

VB:
Sub Comparer()
Dim c As Range
Dim der As Long
Dim I As Long

Application.ScreenUpdating = False
Columns("A:C").Clear
Sheets("Feuil1").Columns("A:B").Copy Sheets("Comparaison").Range("A1")
Range("A1", [b65000].End(xlUp)).Sort , key1:=[a1]
'**********************************************************************
'Adaptation d'un code de BOISGONTIER (Merci !)
  F = Range("A65536").End(xlUp).Row
  Set mondico = CreateObject("Scripting.Dictionary")
  For Each c In Range(Cells(1, 1), Cells(F, 1))
    mondico.Item(c.Value) = mondico.Item(c.Value) + 1
  Next c
  For Each c In Range(Cells(1, 1), Cells(F, 1))
    If mondico.Item(c.Value) > 1 Then c.Interior.ColorIndex = 38
  Next c
  Set mondico = Nothing
'**********************************************************************
der = Range("A65536").End(xlUp).Row

For I = der To 1 Step -1
If Range("A" & I).Interior.ColorIndex <> 38 Then Rows(I).Delete
Next I

Range("c2:c" & Range("a65536").End(xlUp).Row).FormulaR1C1 = "=IF(RC[-2]=R[-1]C[-2],RC[-1]&"" - ""&R[-1]C[-1],"""")"
Columns("C:C").Value = Columns("C:C").Value

For I = der To 1 Step -1
If Range("c" & I) = "non - jamais" Or Range("c" & I) = "jamais - non" Or Range("c" & I) = "" Then Rows(I).Delete Shift:=xlUp
Next I

Columns("b:b").Delete
Cells.Interior.ColorIndex = xlNone

Application.ScreenUpdating = True
End Sub
A bientôt 🙂.
 

Pièces jointes

Re : comparaison et copie de cellules excel avec macro

Re à tous,

Au cas où les données ne seraient pas ordonnées comme illustré dans le post #1
On garde les lignes en double en plaçant toujours le "oui" de la colonne B en 1ère position.

VB:
Sub Copie_et_Tri_des_lignes_en_double()
'Copie et tri en Feuil2 des données de Feuil1
'seules les lignes en double sont copiées
derlign = 1
With Sheets("Feuil1")
 Set Plage = .Range("A1:A" & .Range("A65536").End(xlUp).Row)
 For i = 1 To Plage.Rows.Count
  If Application.CountIf(Plage, .Cells(i, 1).Value) = 2 Then
   Sheets("Feuil2").Cells(derlign, 1).Resize(, 2) = Sheets("Feuil1").Cells(i, 1).Resize(, 2).Value
   derlign = derlign + 1
  End If
 Next i
End With
'Tri_des_données_de_la_Feuil2
'Tri croissant sur la plage champ A
Sheets("Feuil2").Range("A1:B" & Sheets("Feuil2").Range("A65536").End(xlUp).Row).Sort Key1:=Sheets("Feuil2").Range("A1"), _
Order1:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
'Puis inversion des blocs de 2 Lignes contenant la chaine "oui" 
'qui sera toujours placée en tête
dl = Sheets("Feuil2").Range("A65536").End(xlUp).Row
x = 1
Do
    y = Sheets("Feuil2").Range("A" & x + 1).Row
    If InStr(Sheets("Feuil2").Range("B" & y), "oui") Then
      tablo = Sheets("Feuil2").Range("B" & x & ":B" & y)
      ReDim Tmp(1, 1)
      For k = 1 To UBound(tablo, 1) / 2
        Tmp(1, 1) = tablo(UBound(tablo) - k + 1, 1)
        tablo(UBound(tablo) - k + 1, 1) = tablo(k, 1)
        tablo(k, 1) = Tmp(1, 1)
      Next k
      Sheets("Feuil2").Range("B" & x & ":B" & y) = tablo
    End If
    x = y + 1
Loop Until x > dl
End Sub

Reste à ne garder que les doubles contenant le "oui" en tête comme illustré post #1 😛

Klin89
 
Dernière édition:
Re : comparaison et copie de cellules excel avec macro

Re bonsoir,

A tester le code final : résultat en Feuil2 comme illustré dans le post #1

VB:
Sub Copie_et_Tri_des_lignes_en_double()
'Copie et trie en Feuil2 les données de Feuil1
'seules les lignes en double contenant "oui" seront copiées
Application.ScreenUpdating = False
derlign = 1
With Sheets("Feuil1")
 Set Plage = .Range("A1:A" & .Range("A65536").End(xlUp).Row)
 For i = 1 To Plage.Rows.Count
  If Application.CountIf(Plage, .Cells(i, 1).Value) = 2 Then
   Sheets("Feuil2").Cells(derlign, 1).Resize(, 2) = Sheets("Feuil1").Cells(i, 1).Resize(, 2).Value
   derlign = derlign + 1
  End If
 Next i
End With
'Tri_des_données_de_la_Feuil2
'Tri croissant sur la plage champ A
Sheets("Feuil2").Range("A1:B" & Sheets("Feuil2").Range("A65536").End(xlUp).Row).Sort Key1:=Sheets("Feuil2").Range("A1"), _
Order1:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
'Puis inversion des blocs de 2 Lignes contenant la chaine "oui"
'qui sera toujours placée en tête
dl = Sheets("Feuil2").Range("A65536").End(xlUp).Row
x = 1
Do
    y = Sheets("Feuil2").Range("A" & x + 1).Row
    If InStr(Sheets("Feuil2").Range("B" & y), "oui") Then
      tablo = Sheets("Feuil2").Range("B" & x & ":B" & y)
      ReDim Tmp(1, 1)
      For k = 1 To UBound(tablo, 1) / 2
        Tmp(1, 1) = tablo(UBound(tablo) - k + 1, 1)
        tablo(UBound(tablo) - k + 1, 1) = tablo(k, 1)
        tablo(k, 1) = Tmp(1, 1)
      Next k
      Sheets("Feuil2").Range("B" & x & ":B" & y) = tablo
    End If
    x = y + 1
Loop Until x > dl
'on supprime les blocs de 2 lignes ne contenant pas "oui" en en-tête
For w = Sheets("Feuil2").Range("A65536").End(xlUp).Row To 1 Step -2
  If Sheets("Feuil2").Range("B" & w - 1) <> "oui" Then
    Set Plage1 = Sheets("Feuil2").Range("A" & w - 1 & ":B" & w)
    Plage1.Delete Shift:=xlUp
  End If
Next
Application.ScreenUpdating = True
End Sub

La fin du code revue, sur un exemple d'Hasco

VB:
.../...
'on supprime les blocs de 2 lignes [en 1 fois] ne contenant pas "oui" en en-tête
On Error Resume Next
For w = Sheets("Feuil2").Range("A65536").End(xlUp).Row To 1 Step -2
  If Sheets("Feuil2").Range("B" & w - 1) <> "oui" Then
    If plageToDelete Is Nothing Then
      Set plageToDelete = Sheets("Feuil2").Range("A" & w - 1 & ":B" & w)
    Else
     'sinon on ajoute à l'union des cellules
    Set plageToDelete = Union(plageToDelete, Sheets("Feuil2").Range("A" & w - 1 & ":B" & w))
    End If
  End If
Next
If Not plageToDelete Is Nothing Then plageToDelete.EntireRow.Delete
On Error GoTo 0
Application.ScreenUpdating = True
End Sub

Klin89

Edit : pas besoin de On Error Resume Next si l'on déclare la variable objet en début de code :
Dim plageToDelete As Range
J'en apprends tous les jours 🙂
 
Dernière édition:
Re : comparaison et copie de cellules excel avec macro

Re à tous,

Pour le fun, on peut éventuellement remplacer la dernière boucle For Next par celle-ci :

VB:
.../...
For w = Sheets("Feuil2").Range("A65536").End(xlUp).Row To 1 Step -2
  If Sheets("Feuil2").Range("B" & w - 1) <> "oui" Then
    Set Plage1 = Sheets("Feuil2").Range("A" & w - 1 & ":B" & w)'Plage à supprimer
  Else
    Set Plage1 = Sheets("Feuil2").Range("A" & w & ":B" & w)'Plage à supprimer
    Sheets("Feuil2").Range("B" & w - 1) = Sheets("Feuil2").Range("B" & w - 1) & " - " & Sheets("Feuil2").Range("B" & w)
  End If
  Plage1.Delete Shift:=xlUp
Next
Application.ScreenUpdating = True
End Sub

Klin89
 
Re : comparaison et copie de cellules excel avec macro

Bonsoir le forum,

A tester dans le fichier du post #6
En simplifiant la boucle Do Loop Until :

VB:
Sub Copie_et_Tri_des_lignes_en_double()
Dim plageToDelete As Range
'Copie et trie en Feuil2 les données de Feuil1
'seules les lignes en double contenant "oui" seront copiées
Application.ScreenUpdating = False
derlign = 1
With Sheets("Feuil1")
 Set Plage = .Range("A1:A" & .Range("A65536").End(xlUp).Row)
 For i = 1 To Plage.Rows.Count
  If Application.CountIf(Plage, .Cells(i, 1).Value) = 2 Then
   Sheets("Feuil2").Cells(derlign, 1).Resize(, 2) = Sheets("Feuil1").Cells(i, 1).Resize(, 2).Value
   derlign = derlign + 1
  End If
 Next i
End With
'Tri_des_données_de_la_Feuil2
'Tri croissant sur la plage champ A
Sheets("Feuil2").Range("A1:B" & Sheets("Feuil2").Range("A65536").End(xlUp).Row).Sort Key1:=Sheets("Feuil2").Range("A1"), _
Order1:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
'Puis inversion des blocs de 2 Lignes contenant la chaine "oui"
'qui sera toujours placée en tête
dl = Sheets("Feuil2").Range("A65536").End(xlUp).Row
x = 1
Do
    y = Sheets("Feuil2").Range("A" & x + 1).Row
    If InStr(Sheets("Feuil2").Range("B" & y), "oui") Then
      tablo = Sheets("Feuil2").Range("B" & x & ":B" & y)
      k = 0 'on permute les valeurs des 2 cellules contiguës
      For n = UBound(tablo) To LBound(tablo) Step -1
        Sheets("Feuil2").Range("B" & x + k).Value = tablo(n, 1)
        k = k + 1
      Next n
    End If
    x = y + 1
Loop Until x > dl
'on supprime les blocs de 2 lignes [en 1 fois] ne contenant pas "oui" en en-tête
'On Error Resume Next
For w = Sheets("Feuil2").Range("A65536").End(xlUp).Row To 1 Step -2
  If Sheets("Feuil2").Range("B" & w - 1) <> "oui" Then
    If plageToDelete Is Nothing Then
      Set plageToDelete = Sheets("Feuil2").Range("A" & w - 1 & ":B" & w)
    Else
     'sinon on ajoute à l'union des cellules
   Set plageToDelete = Union(plageToDelete, Sheets("Feuil2").Range("A" & w - 1 & ":B" & w))
    End If
  End If
Next
If Not plageToDelete Is Nothing Then plageToDelete.EntireRow.Delete
'On Error GoTo 0
Application.ScreenUpdating = True
End Sub

Ou bien ceci sans passer par la suppression des lignes :
VB:
Sub Copie_et_Tri_des_lignes_en_double1()
'Copie et trie en Feuil2 les données de Feuil1
'seules les lignes en double contenant "oui" seront copiées
Application.ScreenUpdating = False
derlign = 1
With Sheets("Feuil1")
 Set Plage = .Range("A1:A" & .Range("A65536").End(xlUp).Row)
 For i = 1 To Plage.Rows.Count
  If Application.CountIf(Plage, .Cells(i, 1).Value) = 2 Then
   Sheets("Feuil2").Cells(derlign, 1).Resize(, 2) = Sheets("Feuil1").Cells(i, 1).Resize(, 2).Value
   derlign = derlign + 1
  End If
 Next i
End With
'Tri_des_données_de_la_Feuil2
'Tri croissant sur la plage champ A
Sheets("Feuil2").Range("A1:B" & Sheets("Feuil2").Range("A65536").End(xlUp).Row).Sort Key1:=Sheets("Feuil2").Range("A1"), _
Order1:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
'Puis inversion des blocs de 2 Lignes contenant la chaine "oui"
'qui sera toujours placée en tête
If Application.CountIf(Sheets("Feuil2").Range("B1:B" & Sheets("Feuil2").Range("B65536").End(xlUp).Row), "oui") >= 1 Then
 dl = Sheets("Feuil2").Range("A65536").End(xlUp).Row
 x = 1
 Do
     y = Sheets("Feuil2").Range("A" & x + 1).Row
     If InStr(Sheets("Feuil2").Range("B" & y), "oui") Then
       tablo = Sheets("Feuil2").Range("B" & x & ":B" & y)
       k = 0 'on permute les valeurs des 2 cellules contiguës
      For n = UBound(tablo) To LBound(tablo) Step -1
         Sheets("Feuil2").Range("B" & x + k).Value = tablo(n, 1)
         k = k + 1
       Next n
     End If
     x = y + 1
 Loop Until x > dl
'copie finale
t = Sheets("Feuil2").Range("A1:B" & Cells(Rows.Count, 1).End(xlUp).Row)
 z = 2
 ReDim t2(1 To 2, 1 To z)
 For j = 1 To UBound(t) Step 2
   If t(j, 2) = "oui" Then
     ReDim Preserve t2(1 To 2, 1 To z)
     For m = 1 To 2
       t2(m, z - 1) = t(j, m)
       t2(m, z) = t(j + 1, m)
     Next m
     z = z + 2
   End If
 Next j
 Sheets("Feuil2").Range("A1:B" & Cells(Rows.Count, 1).End(xlUp).Row).ClearContents
 Sheets("Feuil2").Range("A1").Resize(UBound(t2, 2), 2) = Application.Transpose(t2)
Else: MsgBox "Aucune donnée à copier"
Sheets("Feuil2").Range("A1:B" & Cells(Rows.Count, 1).End(xlUp).Row).ClearContents
End If
Application.ScreenUpdating = True
End Sub

Klin89
 
Dernière édition:
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
5
Affichages
120
Réponses
18
Affichages
691
Retour