Se connecter avec
S'enregistrer | Connectez-vous

Chercher cellule identique ds un autre colonne

Dernière réponse : dans Programmation
Expert Programmation

bonjour,
(ca faisait longtemps :D  !!)

bon, je dois faire une réconciliation de montants. Autrement dit j'ai un tableau avec une colonne Debit et Credit.
Chaque ligne a un montant dans Debit ou/et credit.
je souhaite que pour chaque ligne, on recherche le montant de cette ligne dans l'autre colonne(D ou C selon la colonne ou est le montant initial) puis s'il est trouvé, copie la ligne initialle et la ligne avec le montant trouvé.

j'ai fait un code pour cela mais plusieurs problemes :
- comme il copie les lignes, elles ne disparaissent pas donc j'ai utilisé .hidden ne sachant pas si c'était mieux que height.
- mon code ne fait pas ce que je veux a savoir qu'il me reste toujours des lignes a la fin (qd je ne les fais pas réapparaitre).

de ces constats:
je souhaite que le code trouve la ou est le montant( D ou C) et fasse la recherche dans la colonne opposé.
ce qu'il ne fait pas bien apparemment

d'aute part si quelqu'un a une idée pour m'éviter de faire 3 fois la meme chose !!!!!

help !!!!!

  1. Dim ws_source As Worksheet
  2. Dim matched As Range
  3. Dim cells_found As Range
  4. Dim unmatched As Range
  5. Dim i As Integer
  6. Dim ligne As Long
  7. Dim switch As Boolean
  8. Dim vide As Boolean
  9.  
  10. Set ws_source = Worksheets("Mastersheet")
  11. Set matched = Worksheets("Matched").Rows(2)
  12. Set unmatched = Worksheets("other").Rows(2)
  13.  
  14. ws_source.Range("D:D").Delete 'delete merged cells
  15. ws_source.Range("H:H").Delete
  16.  
  17. first_row = ws_source.Range("B1:B65536").End(xlDown).Row ' find first and last row of the table
  18. last_row = ws_source.Range("B" & first_row & ":B65536").End(xlDown).Row
  19.  
  20. MsgBox "" & first_row & vbCr & _
  21. "" & last_row
  22.  
  23. With ws_source.Rows(first_row)
  24. .Copy Worksheets("Matched").Rows(1)
  25. .Copy Worksheets("Other").Rows(1)
  26. End With
  27.  
  28. For i = first_row + 1 To last_row
  29. 'execute le code pour les cellules non vide et au format numerique de la colonne debit
  30. Select Case ws_source.Cells(i, 8).Value
  31. Case Is = "": vide = True
  32. Case Else: vide = False
  33. End Select
  34.  
  35. If vide = False Then
  36. Select Case ws_source.Cells(i, 7).Value ' on regarde la valeur de credit
  37. Case "": switch = True ' cellule credit vide, cas 1
  38. Case Is = Abs(ws_source.Cells(i, 8).Value): 'meme montant en debit dc copie la ligne
  39. switch = False: ws_source.Rows(i).Copy matched
  40. Set matched = matched.Offset(1)
  41. ws_source.Rows(i).Hidden = True
  42.  
  43. Case Else: 'montants différents ds Debit et Credit sur la meme ligne
  44. switch = False
  45. ws_source.Rows(i).Copy unmatched
  46. Set unmatched = unmatched.Offset(1)
  47. ws_source.Rows(i).Hidden = True
  48. End Select
  49. 'cas 1, on cherche la valeur absolue de la cellule Debit dans toutes les cellules de la colonne credit
  50. If switch = True Then
  51. Set cells_found = Range("G" & first_row & ":G" & last_row).Find(Abs(ws_source.Cells(i, 8).Value), lookat:=xlWhole)
  52. If Not cells_found Is Nothing Then ' meme montant trouvé
  53. ligne = cells_found.Row
  54. ws_source.Rows(ligne).Copy matched
  55. ws_source.Rows(ligne).Hidden = True
  56. Set matched = matched.Offset(1)
  57. ws_source.Rows(i).Copy matched
  58. ws_source.Rows(i).Hidden = True
  59. Else:
  60. ws_source.Rows(ligne).Copy unmatched 'copy unmatched
  61. ws_source.Rows(ligne).Hidden = True
  62. Set unmatched = unmatched.Offset(1)
  63. ws_source.Rows(i).Copy unmatched
  64. ws_source.Rows(i).Hidden = True
  65. End If
  66. End If
  67. Else:
  68. 'on cherche la valeur absolue de la cellule credit dans toutes les cellules de la colonne debit
  69. Set cells_found = Range("H" & first_row & ":H" & last_row).Find(ws_source.Cells(i, 7).Value * -1, lookat:=xlWhole)
  70. If Not cells_found Is Nothing Then ' meme montant trouvé dc copie ds matched
  71. ligne = cells_found.Row
  72. ws_source.Rows(ligne).Copy matched
  73. ws_source.Rows(ligne).Hidden = True
  74. Set matched = matched.Offset(1)
  75. ws_source.Rows(i).Copy matched
  76. ws_source.Rows(i).Hidden = True
  77. Else:
  78. ws_source.Rows(ligne).Copy unmatched 'pas trouvé dc copie ligne ds unmatched
  79. ws_source.Rows(ligne).Hidden = True
  80. Set unmatched = unmatched.Offset(1)
  81. ws_source.Rows(i).Copy unmatched
  82. ws_source.Rows(i).Hidden = True
  83. End If
  84. End If
  85. Next
  86. ws_source.Rows.Hidden = False

Lassé par la pub ? Créez un compte

Meilleure solution

Expert Programmation

pas mal !!!
:sol: 

bon ben je reposte le code alors ... :D 

  1. Dim ws_source As Worksheet
  2. Dim ws_match As Worksheet
  3. Dim first_cell As Range
  4. Dim last_cell As Range
  5. Dim cell As Range
  6. Dim cells_found As Range
  7. Dim matched As Range
  8. Dim unmatched As Range
  9. Dim somme As Double
  10. Dim demand As Variant
  11. Dim temp As Worksheet
  12. Dim userinput As String
  13. Dim col As Integer
  14.  
  15. Set ws_source = Worksheets("Mastersheet")
  16. Set ws_match = Worksheets("Matched")
  17. Set matched = ws_match.Rows(2)
  18. Set unmatched = Worksheets("Other").Rows(2)
  19.  
  20. demand = MsgBox("Is there merge columns on the table ?", vbYesNoCancel)
  21. If demand = vbYes Then
  22. ws_source.Columns(4).Delete '// delete merged cells
  23. ws_source.Columns(8).Delete
  24. ElseIf demand = vbCancel Then
  25. Exit Sub
  26. End If
  27.  
  28. ' // trouve premiere et derniere cellule pleine dans B1
  29. Set first_cell = ws_source.Range("B1").End(xlDown)
  30. Set last_cell = first_cell.End(xlDown)
  31.  
  32. ' // copie en-tete du tableau
  33. With first_cell.EntireRow
  34. .Copy Worksheets("Matched").Rows(1)
  35. .Copy Worksheets("Other").Rows(1)
  36. End With
  37.  
  38.  
  39.  
  40. userinput = InputBox("Enter the NAME of the Amount column :")
  41. If IsNumeric(userinput) Then
  42. col = Columns(CInt(userinput)).Column
  43. Else
  44. col = Columns(userinput).Column
  45. End If
  46.  
  47. Set temp = Worksheets.Add '// sauvegarde du raport intact
  48. ws_source.Cells.Copy temp.Cells
  49.  
  50. somme = Abs(Round(WorksheetFunction.Sum(ws_source.Columns(col).Cells), 2))
  51. If somme <= 0.05 Then
  52. ws_source.Range(first_cell.EntireRow, last_cell.EntireRow).Copy matched.Offset(-1) '// si somme = 0 alors copie dans matched
  53. Else
  54.  
  55. For Each cell In ws_source.Range(first_cell, last_cell).Offset(1, col - first_cell.Column) ' // pour chaque cellule du tableau de la colonne col (sans l'entete)
  56.  
  57. If cell.Value <> "" Then ' // uniquement les cellules pleines
  58. If cell.Value <> 0 Then
  59. Set cells_found = ws_source.Range(cell, last_cell).Find(-cell.Value, lookat:=xlWhole, searchdirection:=xlNext)
  60. If Not cells_found Is Nothing Then ' // meme montant trouvé
  61. LineCopy cell.EntireRow, matched, True
  62. LineCopy cells_found.EntireRow, matched, True
  63. Else
  64. ' // pas trouvé donc copie dans Other
  65. LineCopy cell.EntireRow, unmatched, True
  66. End If
  67. Else
  68. ' // copie dans match les opérations nulles
  69. LineCopy cell.EntireRow, matched, True
  70. End If
  71. End If
  72. Next
  73.  
  74. Application.DisplayAlerts = False '// desactivation alertes
  75. temp.Cells.Copy ws_source.Cells
  76. temp.Delete '// suppression feuille temporaire
  77. Application.DisplayAlerts = True '// reactivation alertes
  78. End If
Expert Programmation

bon, j'ai résolu mon probleme en l'écrivant... ;) 
donc si qqn a juste une idée pour le rendre moins long et répétitif ?

code final :

  1. Dim ws_source As Worksheet
  2. Dim matched As Range
  3. Dim cells_found As Range
  4. Dim unmatched As Range
  5. Dim i As Integer
  6. Dim ligne As Long
  7. Dim switch As Boolean
  8. Dim vide As Boolean
  9. dim first_row as long
  10. dim last_row as long
  11.  
  12. Set ws_source = Worksheets("Mastersheet")
  13. Set matched = Worksheets("Matched").Rows(2)
  14. Set unmatched = Worksheets("Other").Rows(2)
  15.  
  16. ws_source.Range("D:D").Delete 'delete merged cells
  17. ws_source.Range("H:H").Delete
  18.  
  19. first_row = ws_source.Range("B1:B65536").End(xlDown).Row ' find first and last row of the table
  20. last_row = ws_source.Range("B" & first_row & ":B65536").End(xlDown).Row
  21.  
  22. MsgBox "" & first_row & vbCr & _
  23. "" & last_row
  24.  
  25. With ws_source.Rows(first_row)
  26. .Copy Worksheets("Matched").Rows(1)
  27. .Copy Worksheets("Other").Rows(1)
  28. End With
  29.  
  30. For i = first_row + 1 To last_row
  31. 'execute le code pour les cellules non vide et au format numerique de la colonne debit
  32. Select Case ws_source.Cells(i, 8).Value
  33. Case Is = "": vide = True
  34. Case Else: vide = False
  35. End Select
  36.  
  37. If vide = False Then
  38. Select Case ws_source.Cells(i, 7).Value ' on regarde la valeur de credit
  39. Case "": switch = True ' cellule credit vide, cas 1
  40. Case Is = Abs(ws_source.Cells(i, 8).Value): 'meme montant en debit dc copie la ligne
  41. switch = False: ws_source.Rows(i).Copy matched
  42. Set matched = matched.Offset(1)
  43. ws_source.Rows(i).Hidden = True
  44.  
  45. Case Else: 'montants différents ds Debit et Credit sur la meme ligne
  46. switch = False
  47. ws_source.Rows(i).Copy unmatched
  48. Set unmatched = unmatched.Offset(1)
  49. ws_source.Rows(i).Hidden = True
  50.  
  51. End Select
  52. 'cas 1, on cherche la valeur absolue de la cellule Debit dans toutes les cellules de la colonne credit
  53. If switch = True Then
  54. Set cells_found = Range("G" & first_row + 1 & ":G" & last_row).Find(Abs(ws_source.Cells(i, 8).Value), lookat:=xlWhole)
  55. If Not cells_found Is Nothing Then ' meme montant trouvé
  56. ligne = cells_found.Row
  57. ws_source.Rows(ligne).Copy matched
  58. ws_source.Rows(ligne).Hidden = True
  59. Set matched = matched.Offset(1)
  60. ws_source.Rows(i).Copy matched
  61. ws_source.Rows(i).Hidden = True
  62. Set matched = matched.Offset(1)
  63. Else:
  64. ws_source.Rows(ligne).Copy unmatched 'copy unmatched
  65. ws_source.Rows(ligne).Hidden = True
  66. Set unmatched = unmatched.Offset(1)
  67. ws_source.Rows(i).Copy unmatched
  68. ws_source.Rows(i).Hidden = True
  69. Set unmatched = unmatched.Offset(1)
  70. End If
  71. End If
  72. ElseIf vide = True Then
  73. 'on cherche la valeur absolue de la cellule credit dans toutes les cellules de la colonne debit
  74. Set cells_found = Range("H" & first_row & ":H" & last_row).Find((ws_source.Cells(i, 7).Value * -1), lookat:=xlWhole)
  75. If Not cells_found Is Nothing Then ' meme montant trouvé dc copie ds matched
  76. ligne = cells_found.Row
  77. ws_source.Rows(ligne).Copy matched
  78. ws_source.Rows(ligne).Hidden = True
  79. Set matched = matched.Offset(1)
  80. ws_source.Rows(i).Copy matched
  81. ws_source.Rows(i).Hidden = True
  82. Set matched = matched.Offset(1)
  83. Else:
  84. 'pas trouvé dc copie ligne ds unmatched
  85. ws_source.Rows(i).Copy unmatched
  86. ws_source.Rows(i).Hidden = True
  87. Set unmatched = unmatched.Offset(1)
  88. End If
  89. End If
  90. Next
  91. ws_source.Rows.Hidden = False
Expert Programmation

Eh, eh, le temps que je regarde et tu as posté la réponse. A la décharge, je te faisais une réponse longue. La voici (c'est la réponse au premier code) :

  1. Dim ws_source As Worksheet
  2. Dim matched As Range
  3. Dim cells_found As Range
  4. Dim unmatched As Range
  5. Dim i As Integer
  6. Dim ligne As Long
  7. Dim switch As Boolean
  8. Dim vide As Boolean
  9.  
  10. Set ws_source = Worksheets("Mastersheet" )
  11. Set matched = Worksheets("Matched" ).Rows(2)
  12. Set unmatched = Worksheets("other" ).Rows(2)
' // Bien
  1. ws_source.Range("D:D" ).Delete 'delete merged cells
  2. ws_source.Range("H:H" ).Delete
' // Pas mal. Tu peux aussi utiliser Columns("D") ou Columns(4)
  1. first_row = ws_source.Range("B1:B65536" ).End(xlDown).Row ' find first and last row of the table
  2. last_row = ws_source.Range("B" & first_row & ":B65536" ).End(xlDown).Row
:pt1cable:  Tu te donnes bien du mal !
Et tes variables ne sont pas déclarées :fou: 
  1. ' // Avec des nombres
  2. first_row = Feuil1.Range("B1").End(xlDown).Row
  3. last_row = Feuil1.Cells(first_row, 2).End(xlDown).Row
  4.  
  5. ' // Avec des cellules
  6. Set cell_1er = ws_source.Range("B1").End(xlDown)
  7. Set cell_der = cell_1er.End(xlDown)
  1. MsgBox "" & first_row & vbCr & _
  2. "" & last_row
Oozenot, le débogueur fou !!! :lol: 
  1. With ws_source.Rows(first_row)
  2. .Copy Worksheets("Matched" ).Rows(1)
  3. .Copy Worksheets("Other" ).Rows(1)
  4. End With
  5.  
  6. For i = first_row + 1 To last_row
Ah très grave erreur ! Les lignes vont jusqu'à 65536, or i est un Integer...
  1. 'execute le code pour les cellules non vide et au format numerique de la colonne debit
  2. Select Case ws_source.Cells(i, 8).Value
  3. Case Is = "": vide = True
  4. Case Else: vide = False
  5. End Select
Un Select ici ??? :heink:  Tu veux bien me changer ça tout de suite ! Mets un simple If ou mieux :
  1. vide = ws_source.Cells(i, 8).Value = ""
  1. If vide = False Then
Arrête de comparer des booléens. Ce sont déjà des booléens :pfff: 
  1. If Not vide Then
  1. Select Case ws_source.Cells(i, 7).Value ' on regarde la valeur de credit
  2. Case "": switch = True ' cellule credit vide, cas 1
  3. Case Is = Abs(ws_source.Cells(i, 8).Value): 'meme montant en debit dc copie la ligne
  4. switch = False: ws_source.Rows(i).Copy matched
  5. Set matched = matched.Offset(1)
  6. ws_source.Rows(i).Hidden = True
Pas mal ;)  Et le coup de la ligne cachée, c'est astucieux.
  1. Case Else: 'montants différents ds Debit et Credit sur la meme ligne
  2. switch = False
  3. ws_source.Rows(i).Copy unmatched
  4. Set unmatched = unmatched.Offset(1)
  5. ws_source.Rows(i).Hidden = True
  6. End Select
  7. 'cas 1, on cherche la valeur absolue de la cellule Debit dans toutes les cellules de la colonne credit
  8. If switch = True Then
:fou: 
  1. Set cells_found = Range("G" & first_row & ":G" & last_row).Find(Abs(ws_source.Cells(i, 8).Value), lookat:=xlWhole)
:sarcastic: 
  1. If Not cells_found Is Nothing Then ' meme montant trouvé
Ah, enfin une comparaison bien faite
  1. ligne = cells_found.Row
  2. ws_source.Rows(ligne).Copy matched
  3. ws_source.Rows(ligne).Hidden = True
  4. Set matched = matched.Offset(1)
  5. ws_source.Rows(i).Copy matched
  6. ws_source.Rows(i).Hidden = True
  7. Else:
(Vire les deux points après le Else) Dis donc, t'as pas l'impression d'avoir déjà traité ces cas dans le Select ?
  1. ws_source.Rows(ligne).Copy unmatched 'copy unmatched
  2. ws_source.Rows(ligne).Hidden = True
  3. Set unmatched = unmatched.Offset(1)
  4. ws_source.Rows(i).Copy unmatched
  5. ws_source.Rows(i).Hidden = True
  6. End If
  7. End If
  8. Else:
(Vire les deux points après le Else)
  1. 'on cherche la valeur absolue de la cellule credit dans toutes les cellules de la colonne debit
  2. Set cells_found = Range("H" & first_row & ":H" & last_row).Find(ws_source.Cells(i, 7).Value * -1, lookat:=xlWhole)
  3. If Not cells_found Is Nothing Then ' meme montant trouvé dc copie ds matched
  4. ligne = cells_found.Row
  5. ws_source.Rows(ligne).Copy matched
  6. ws_source.Rows(ligne).Hidden = True
  7. Set matched = matched.Offset(1)
  8. ws_source.Rows(i).Copy matched
  9. ws_source.Rows(i).Hidden = True
  10. Else:
(Vire les deux points après le Else)
  1. ws_source.Rows(ligne).Copy unmatched 'pas trouvé dc copie ligne ds unmatched
  2. ws_source.Rows(ligne).Hidden = True
  3. Set unmatched = unmatched.Offset(1)
  4. ws_source.Rows(i).Copy unmatched
  5. ws_source.Rows(i).Hidden = True
  6. End If
  7. End If
  8. Next
  9. ws_source.Rows.Hidden = False

Bon, ce n'est pas mal tout ça, sinon :) 

-------------------

D'abord, une procédure pour ne pas faire de répétitions :
  1. Sub LineCopy(ByVal Line As Range, ByRef target As Range, Optional Clear As Boolean)
  2. Line.EntireRow.Copy Destination:=target
  3. Set target = target.Offset(1)
  4. If Clear Then Line.Clear
  5. End Sub


Maintenant le corps de la procédure principale :
  1. Dim ws_source As Worksheet
  2. Dim matched As Range
  3. Dim unmatched As Range
  4. Dim cell_1er As Range
  5. Dim cell As Range
  6. Dim cell_D As Range
  7. Dim cell_C As Range
  8. Dim plage As Range
  9. Dim found As Boolean
  10.  
  11. Set matched = Worksheets("Matched" ).Rows(1)
  12. Set unmatched = Worksheets("other" ).Rows(1)
  13.  
  14. Set ws_source = Worksheets("Mastersheet" ).Copy(After:=Worksheets(Worksheets.Count))
  15. Set cell_1er = ws_source.Range("B1").End(xlDown)
  16.  
  17. Set plage = ws_source.Range(cell_1er, cell_1er.End(xlDown))
  18.  
  19. LineCopy ws_source.Rows(1), matched
  20. LineCopy ws_source.Rows(1), unmatched
  21.  
  22. For Each cell In plage
  23.  
  24. Set cell_D = cells.Offset(0, 7)
  25. Set cell_C = cells.Offset(0, 8)
  26.  
  27. ' // --- A charge pour Oozenot de vérifier le numéro de décalage de colonnes ---
  28. MsgBox "cellule DEBIT" & cell_D.Columns.Address(False, False)
  29. MsgBox "cellule CREDIT" & cell_C.Columns.Address(False, False)
  30. ' // --- A charge pour Oozenot de vérifier le numéro de décalage des colonnes ---
  31.  
  32. If Trim(cell_D.Value) = "" And _
  33. Trim(cell_C.Value) = "" _
  34. Then
  35. ' // DEBIT et CREDIT sont vides
  36. ' // On ne fait rien.
  37.  
  38. ElseIf Trim(cell_D.Value) <> "" And _
  39. Trim(cell_C.Value) <> "" _
  40. Then
  41. ' // DEBIT et CREDIT sont non vides
  42.  
  43. If Abs(cell_D.Value) = Abs(cell_C.Value) Then
  44. LineCopy cell, matched, True
  45. Else
  46. LineCopy cell, unmatched, True
  47. End If
  48.  
  49. ElseIf Trim(cell_D) <> "" _
  50. Then
  51. ' // DEBIT est non vide / CREDIT est donc vide
  52.  
  53. For Each cell_C in plage.Offset(8)
  54. If Trim(cell_C) <> "" And _
  55. Abs(cell_D.Value) = Abs(cell_C.Value) _
  56. Then
  57. LineCopy cell_D, matched, True
  58. LineCopy cell_C, matched, True
  59. found = True
  60. Exit For
  61. End If
  62. Next
  63. If Not found Then LineCopy cell_D unmatched, True
  64.  
  65. ElseIf Trim(cell_C) <> "" _
  66. Then
  67. ' // CREDIT est non vide / DEBIT est donc vide
  68.  
  69. For Each cell_D in plage.Offset(7)
  70. If Trim(cell_D) <> "" And _
  71. Abs(cell_D.Value) = Abs(cell_C.Value) _
  72. Then
  73. LineCopy cell_D, matched, True
  74. LineCopy cell_C, matched, True
  75. found = True
  76. Exit For
  77. End If
  78. Next
  79. If Not found Then LineCopy cell_C, unmatched, True
  80. End If
  81. Next
Expert Programmation

salut zeb,

ah oui, dsl pour l'oubli des déclaration de first_row et last_row..
sinon j'ai regardé ton code parcequ'il y avait des fonctions que je ne connaissais pas !!

Par contre il y a des erreurs de syntaxe (je pense).
linecopy n'existe pas sous VBA donc je présume que c'est line.copy qui est bon (je ne connaissais pas l'existence de line... cool)
ensuite je ne connaisait pas non plus cette syntaxe pour copy (avec les virgules) et du coup, n'aillant rien trouvé sur l'aide, a quoi sert les ",True " a la fin de lignes ?
et pourquoi les mettre que de temps en temps ?
  1. cell_D.EntireRow.Copy, unmatched, True

Autre question, l'utilisation de Clear supprime le contenu des lignes non ? parceque moi j'aimerais que la feuille 1 reste telle qu'elle est initialement. EDIT: d'ou la copie en début de code ^^ mais par contre, bug: objet requis
sinon, merci !!!!!!!

maintenant (et non, c'est pas fini) je souhaite que pour les unmatched on fasse un autre test :
faire tous les calculs de somme possible jusqu'a ce que une somme de débit + somme crédit = +/- 0.05 (en avancant chronologiquement,dc ds l'ordre des ligne parceque le tableau est trié de la plus vieille date a la plus récente)
sachant qu'apres je demanderai a l'utlisateur de rentrer la marge qu'il souhaite.
Je me suis pas encore penché dessus mais cette nuit j'ai pensé utilisé la boucle do ... loop until
je m'y met ...

( :D  je fais des reves de programmation !!! :(  )
Expert Programmation

Quelles erreurs de syntaxe ?
Bon, il y avait deux trois bricoles que je viens d'éditer.

Mais la fonction LineCopy() existe, c'est moi qui l'ai inventée. Relis mon message précédent.

(Fais de beaux rêves ;)  )
Expert Programmation

pfiou,
je suis fatigué !! j'avais completement zapé la fonction que tu avais crée...

par contre j'ai une erreur objet required "424" sur cette ligne

  1. Set ws_source = Worksheets("Mastersheet").Copy(After:=Worksheets(Worksheets.Count))


et je n'arrive pas a l'expliquée.. (Set est bien présent), Mastersheet existe, la copy est bonne etla destination semble l'etre aussi puisqu'il me le copie correctement !..

pour ma boucle j'ai pensé faire qqch comme ca : (je l'integre apres dans le premier programme)


  1. Sub sommesCumulee()
  2.  
  3. Dim j As Long
  4. Dim ligne As Long
  5. Dim ligne1 As Long
  6. Dim ws_proposal As Worksheet
  7. Dim ws_unmatched As Worksheet
  8. dim somme_cumulee as double
  9.  
  10. Set ws_unmatched = Worksheets("Other")
  11. Set ws_proposal = Worksheets("Matched Proposal")
  12.  
  13. j = 2
  14. Do
  15. Do
  16. For ligne = j To ws_unmatched.Columns(7).End(xlDown).Row
  17. somme_cumulee = Cdbl(ws_unmatched.Cells(ligne, 7).Value) + Cdbl(ws_unmatched.Cells(ligne, 8).Value)
  18. Next
  19. Exit Do
  20. Loop Until Abs(somme_cumulee) <= 0.05
  21. For ligne1 = j To ws_unmatched.Columns(7).End(xlDown).Row
  22. LineCopy ws_unmatched.Rows(ligne1), ws_proposal.Rows
  23. Next
  24. j = j + 1
  25. Exit Do
  26. Loop Until j = unmatched.Columns(7).End(xlDown).Row
  27.  
  28. End Sub
Expert Programmation

  1. Set ws_source = Worksheets("Mastersheet" ).Copy(After:=Worksheets(Worksheets.Count))
Arrgggggh ! Saloperie de VBA de m[:zeb:5]e qu'est pas fichu d'avoir un modèle objet complet [:marcus67] [:marcus67] [:marcus67]
  1. Worksheets("Mastersheet" ).Copy(After:=Worksheets(Worksheets.Count))
  2. Set ws_source = Worksheets(Worksheets.Count)


Je vois encore des variables non déclarée. Est-ce :
[ ] par égard pour le forum, pour ne pas alourdir les messages,
[ ] par oubli, mais c'est la dernière fois,
[ ] parce que tu as encore oublié à cause du fait que tu n'utilises pas l'option explicite
[ ] obiwan kenobi - la réponse D
?

(Si tu oses me répondre que c'est parce que tu t'en carres de l'option explicite, j'te cause plus :kaola:  )
Expert Programmation

réponse D : obiwan Kenobi !!!! :D 
dsl c'est un pur méga oubli.. :sleep:  (sur quel code ? le dernier ? (edit fait sur le premier))
ms VBA est pourri la dessus aussi.. il ne devrait pas faire tourner le code !!!

edit: oups ma somme !!!!!
Expert Programmation

j'ai avancé ma somme cumulée... mais marche pas..

  1. Dim j As Long
  2. Dim k As Long
  3. Dim ligne As Long
  4. Dim ligne1 As Long
  5. Dim ws_proposal As Worksheet
  6. Dim ws_unmatched As Worksheet
  7. Dim somme_cumulee As Double
  8.  
  9. Set ws_unmatched = Worksheets("Other")
  10. Set ws_proposal = Worksheets("Matched Proposal")
  11.  
  12. j = 2
  13. k = ws_unmatched.Columns(2).End(xlDown).Row
  14.  
  15. For ligne = j To k
  16. Do
  17. somme_cumulee = CDbl(ws_unmatched.Cells(ligne, 7).Value) + CDbl(ws_unmatched.Cells(ligne, 8).Value)
  18. j = j + 1
  19. Exit Do
  20. Loop Until Abs(somme_cumulee) <= 0.06 Or j = k
  21. If Abs(somme_cumulee) <= 0.05 Then
  22. For ligne1 = j To ligne
  23. ws_unmatched.Rows(ligne1).Copy ws_proposal.Rows(2)
  24. Next
  25. End If
  26. Next
Expert Programmation

Bon, je suis dans un bon jour, alors si tu me promets de ne plus mettre de : après tes Else (tu m'énerves avec ça :sarcastic:  ), si tu acceptes d'étudier un peu ce code, et si en plus tu inventes toi-même la fonction ZoneCopy(), alors je t'invite à accepter ça :
  1. Dim plage As Range
  2. Dim cell As Range
  3. Dim zone As Range
  4. Dim valeur As Double
  5. Dim cumul As Double
  6.  
  7. Set zone = Nothing
  8. For Each cell In plage
  9. If Trim(cell.Offset(, 5).Value) <> "" And _
  10. Trim(cell.Offset(, 6).Value) = "" _
  11. Then
  12. ' // C'est parti !
  13. Set zone = cell.Offset(, 5)
  14. Else
  15. If zone Is Nothing Then
  16. ' // Ca n'a pas encore commencé
  17. Else
  18. ' // La zone est enrichie
  19. Set zone = zone.Worksheet.Range(zone.Cells(1), cell.Offset(, 6))
  20.  
  21. ' // Un peu de calcul
  22. valeur = zone.Cells(1, 1).Value
  23. cumul = WorksheetFunction.Sum(zone.Columns(2))
  24.  
  25. If Abs(valeur - cumul) < 0.05 Then
  26. ' // Yeah !!!
  27. ZoneCopy zone, target, True
  28.  
  29. ' // On remet les compteurs à zéro
  30. Set zone = Nothing
  31. End If
  32. End If
  33. End If
  34. Next

Ah, j'oubliais. Faut gérer target et en plus, ça ne fait que la moitié du boulot. Faut recommencer pour les débits (ou les crédits, je ne sais plus).

:sol: 

------------
[private]
Je suis trop content de te voir aider les autres en leurs faisant suivre certains de mes préceptes. Je ne détiens pas la Vérité Absolue, et on peut encore m'en apprendre, mais ceux-ci viennent d'années d'expérience et savoir que c'est transmis au moins pour partie me remplit de plaisir ;) 
Expert Programmation

Salut zeb,

Alors, j'ai un peu regardé ta propostion de code (celle remplacant mon code au début de la disussion) maisil s'avere que je peine a le faire fonctionner, le deboggeur m'envoyant de erreur 1004 application objet defined error a la volée !!

Je n'ai ps encore eu le tps de jeter un coup d'oeil a ta derniere proposition de code sur la somme cumullee mais je m'apprete a le faire. Pour ce qui est du fait qu'il ne marche que pour une colonne, tant mieux, parce que je n'ai pas toujours 2 colonnes !! parfois j'ai les débit et les crédits dans la meme colonne !! (ben oui franchement, pourquoi faire simple !!! :D  )
Du coup je vais m'inspirer de ta méthode et l'adapter fortement a mon cas !!

SInon une question : je remarque que tu propose souvent des méthode avec des range
Excel met moins de tps a executer le code VBA lorsque je lui délimite le tableau d'entrée mais tu dis que mes adresses de Range sont pas top top... du coup que privilégier ?

---------
[private]

Mais de rien, ca fait toujours plaisir d'aider les autres (qd je peux !!! :)  ). En plus ce forum est sérieux et sympa !!!
Expert Programmation

re,

je viens de regarder le code et j'ai du faire qqs modifs e cause de ce ***** de VBA :

  1. Set cell_D = ws_source.Columns(8).Cells

j'ai du enlever les .offset (erreur 1004 object defined error). J'ai déja remarquer qu'il ne les aime pas trop ceux la !!

pour les Trim() j'ai regardé l'aide (je connaissait pas): ne s'utilise que sur des expressions String.. or j'ai des montants dans mes cases d'ou l'erreur 13 : type mismatch. par contre qd mes cellules sont vides il bloque aussi or le vide peut etre en n'importe quel format nn ?
..
j'avance pour le reste !
Expert Programmation

Eh, pour les Trim(), en VBA, en VB, en ksh, en SQL, partout j'en mets. On n'est pas à l'abri d'un espace oublié. Mais peut être faut-il alors écrire :
  1. If Trim(cellule.Text) Then


Si tu as des erreurs 1004, ce n'est pas Offset() qui pose problème, mais l'objet juste avant.

Effectivement, il faut dans certains cas ajouter .Cells, même sur un objet Range. VB est mal écrit :pfff: 
Expert Programmation

pfiou !

apres quelques retouches c'est effectivement le .value qui bloquait.
ok, le programme tourne, je me penche maintenant sur celui des sommes cumulées.
je pense que je vais surtout me resservir de la méthode d'enrichissement de zone !!!

j'attaque [:_blackfox_]
Expert Programmation

coucou,

bon j'ai pas avancé sur la somme mais par contre je corrige quelques erreurs sur le code précédent et en lancant ce dernier j'ai remarqué que Find me trouve TOUTES les cellules égales a celle qu'il recherche.
Or moi, pour que la somme des 2 fasse 0 il ne m'en faut qu'une !!!

d'ou ma question y a t'il un argument non présent dans l'aide qui completerai .FIND() pour qu'il s'arrete qd il a trouver une cellule identique.
ci dessous la partie de mon code correspondante
  1. [...]
  2. For i = first_row + 1 To last_row
  3. 'execute le code pour les cellules non vide et au format numerique de la colonne montant
  4. vide = ws_source.Cells(i, col).Value = ""
  5.  
  6. If Not vide Then
  7. Select Case ws_source.Cells(i, col).Value
  8. Case Is < 0: Set cells_found = Range(Cells(i + 1, col), Cells(last_row, col)).Find(Abs(ws_source.Cells(i, col).Value), lookat:=xlWhole)
  9. Case Is > 0: Set cells_found = Range(Cells(i + 1, col), Cells(last_row, col)).Find((ws_source.Cells(i, col).Value * -1), lookat:=xlWhole)
  10. Case Is = 0: ws_source.Rows(i).Copy matched: Set matched = matched.Offset(1)
  11. End Select
  12.  
  13. If Not cells_found Is Nothing Then
  14. [...]
Expert Programmation

Salut,

M'enfin, un simple Exit For pour sortir de ta boucle quand tu as trouvé, et c'est tout ! C'est pas comme si je t'avais pas déjà proposé ce type de code.

Eh oui, tout ce que je te propose est à étudier, pas à copier bêtement :o 

;) 
Expert Programmation

salut zeb,

tkt, je ne recopie rien betement ce serai trop dommage !!
Par contre un simple exit for... je veux bien mais dans ma configuration actuelle, si je met un simple exit for il arretera de me faire les recherches pour les autres lignes non ?

ou alors il quitte juste la boucle en cours (et dans ce cas j'ai un mega point de base a revoir !!! :ouch:  )
Expert Programmation

et bien en fait moi je veux qu'il ne trouve qu' UNE seule des cellules possible.

pour -26000 il doit trouver 26000 mais qu'une seule fois pour que -26000 + 26000 = 0
si il me trouve 4 fois 26000 je me retrouve avec une balance différente de 0 !!

en fait je pense que du coup FIND n'est pas approprié ou qu'on peut lui ajouter un paramètre supplémentaire... mais lequel.. rien ds l'aide

Expert Programmation

salut,
je n'arrive pas avec find alors j'ai chercher une autre fonction qui ne renvoyait l'adresse que d'une seule occurence (la premiere) et j'ai trouvé INSTR() pour les string mais moi il me faudrait un équivalent pour les nombres et je trouve pas..
Expert Programmation

Euh.....
J'étais à l'instant en train de te répondre que je ne comprenais rien à ton baratin, que Find() ne renvoyait qu'une cellule à la fois, etc. Quand j'ai enfin compris ton problème. Ouf !!!!!

Quand tu prends en compte la ligne i (courante) et la ligne j=i+n (renvoyée par Find()), tu prends bien la peine, grâce à l'itération (la boucle For) de ne pas reconsidérer la ligne i, mais dans un prochain tour, tu peux reconsidérer la ligne j, pour un i différent.

D'où mes propositions :
  • Travailler sur une feuille temporaire pour pouvoir y faire des coupes sombres.
  • Vider les lignes prises en compte.

    Rappel :
    1. Sub LineCopy(ByVal Line As Range, ByRef target As Range, Optional Clear As Boolean)
    2. Line.EntireRow.Copy Destination:=target
    3. Set target = target.Offset(1)
    4. If Clear Then Line.Clear
    5. End Sub

    Réétudier ce code. Comprendre l'intérêt de la ligne 4 :o 



    ;) 
    Expert Programmation

    ca fait 2 jours que je m'arrache les cheveux la dessus... j'ai l'impression de ne plus avancer et de ne plus voir les fautes dans les codes... c'est pas bon.
    en plus je manque de tps, mon boss me presse pour finir ce code pour qu'il puisse l'envoyer a tt le monde ...grrr
    Expert Programmation

    Citation :
    maisje pensais que mon .hidden faisait la meme chose...

    ?!?!?!?!?!?!?!? Mais non. Les choses cachées existent quand même. Ce n'est pas parce que tu n'as jamais vu de rennes volants que le Père Noël n'existe pas.

    Code :
    1. Range("B3").Value = "Père Noël"
    2. Rows(3).Hidden = True
    3. Columns("B").Hidden = True
    4.  
    5. MsgBox "Le " & Range("B3").Value & " existe, il se cache dans la cellule " & Cells.Find("Père Noël").Address(False, False)
    Expert Programmation

    ZEb tu es GENIAL !!!!

    je viens de comprendre ce que tu disais avec les lignes (avant de voir ton mess !!! :D  )
    Du coup j'ai remplacé tous mes horibles . hidden et j'ai réutilisé ta fonction linecopy ()
    c'est genial, ca marche super bien et tres rapidement.
    ci desous le code quand il y a une seule colonne avec les montants D et C

    1. Sub LineCopy(ByVal Line As Range, ByRef target As Range, Optional Clear As Boolean)
    2. Line.EntireRow.Copy Destination:=target
    3. Set target = target.Offset(1)
    4. If Clear Then Line.Clear
    5. End Sub
    6.  
    7. Sub reconciliation2() 'tableau avec une colonne montant (crédit et débit inclus) et transaction
    8.  
    9. Dim ws_source As Worksheet
    10. Dim matched As Range
    11. Dim cells_found As Range
    12. Dim unmatched As Range
    13. Dim i As Long
    14. Dim j As Long
    15. Dim first_row As Long
    16. Dim last_row As Long
    17. Dim col As String
    18. Dim somme_col As Double
    19. Dim ws_match As Worksheet
    20. Dim lstrow As Long
    21. Dim clear_result As Range
    22.  
    23. Set ws_source = Worksheets("Mastersheet")
    24. Set matched = Worksheets("Matched").Rows(2)
    25. Set unmatched = Worksheets("Other").Rows(2)
    26. Set ws_match = Worksheets("Matched")
    27. Set clear_result = Worksheets("Clear Matched results").Rows(16)
    28.  
    29. demand = MsgBox("Is there Merge cells/column on the table ?", vbYesNoCancel)
    30. If demand = vbYes Then
    31. ws_source.Columns(4).Delete 'delete merged cells
    32. ws_source.Columns(8).Delete
    33. ElseIf demand = vbCancel Then
    34. Exit Sub
    35. End If
    36. ws_source.Cells.Copy Worksheets("Report1").Cells 'sauvegarde du raport intact
    37.  
    38. ' find first and last row of the table
    39. first_row = ws_source.Range("B1").End(xlDown).Row
    40. last_row = ws_source.Cells(first_row, 2).End(xlDown).Row
    41.  
    42. With ws_source.Rows(first_row)
    43. .Copy Worksheets("Matched").Rows(1)
    44. .Copy Worksheets("Other").Rows(1)
    45. End With
    46.  
    47. col = UCase(InputBox("Enter the Name of the Amount column :"))
    48. MsgBox "" & col
    49.  
    50. For i = first_row + 1 To last_row
    51. 'execute le code pour les cellules non vide et au format numerique de la colonne montant
    52. vide = ws_source.Cells(i, col).Value = ""
    53.  
    54. If Not vide Then
    55. Select Case ws_source.Cells(i, col).Value
    56. Case Is < 0: Set cells_found = Range(Cells(i + 1, col), Cells(last_row, col)).Find(Abs(ws_source.Cells(i, col).Value), lookat:=xlWhole, searchdirection:=xlNext)
    57. Case Is > 0: Set cells_found = Range(Cells(i + 1, col), Cells(last_row, col)).Find((ws_source.Cells(i, col).Value * -1), lookat:=xlWhole, searchdirection:=xlNext)
    58. Case Is = 0: LineCopy ws_source.Rows(i), matched, True
    59. End Select
    60.  
    61. If Not cells_found Is Nothing Then ' meme montant trouvé
    62. ligne = cells_found.Row
    63. LineCopy ws_source.Rows(ligne), matched, True
    64. LineCopy ws_source.Rows(i), matched, True
    65.  
    66. Else
    67. LineCopy ws_source.Rows(i), unmatched, True ' pas trouvé donc copie dans Other
    68. End If
    69.  
    70. End If
    71. Next
    72.  
    73. 'mise en forme dans le tableau prévu clear results
    74. lstrow = ws_match.Columns(2).End(xlDown).Row 'nombre d'opérations réconciliées
    75. k = 1
    76. Do
    77. Worksheets("Clear Matched results").Rows(17).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
    78. k = k + 1
    79. Loop Until k = lstrow
    80.  
    81. For j = 2 To lstrow
    82. If ws_match.Cells(j, col).Value < 0 Then
    83. ws_match.Cells(j, col).Copy clear_result.Cells(, 3)
    84. ws_match.Cells(j, 6).Copy clear_result.Cells(, 1)
    85. ElseIf ws_match.Cells(j, col).Value > 0 Then
    86. ws_match.Cells(j, col).Copy clear_result.Cells(, 4)
    87. ws_match.Cells(j, 6).Copy clear_result.Cells(, 1)
    88. Else
    89. ws_match.Cells(j, col).Copy clear_result.Cells(, 4)
    90. ws_match.Cells(j, 6).Copy clear_result.Cells(, 1)
    91. End If
    92. Set clear_result = clear_result.Offset(1)
    93. Next
    94. End Sub


    il ne me reste plus qu'a ajuster le programme pour le cas ou C et D sont dans ds colonnes différentes !!

    (ne m'en veux pas mais pendant tout ce temps je n'avais pas utiliser ta fonction bien que comprise parce que je voulais absolument reussir avec mon début de programme et comprendre pourquoi il ne marchait pas. ca m'apprendra a etre tétu !!)
    Expert Programmation

    je reviens sur ce que j'ai dit... il ya encore des petites erreurs.
    en fait lorsque j'ai trois op2rations expl :100 puis -100 et encore -100
    il me copie bien le100 et le -100
    mais apres, comme find a trouver le deuxieme -100: il copie la ligne originale (cleared donc une ligne vide) et la ligne avec le 2eme -100...

    comment endigué cela ?

    edit: j'ai le meme probleme sur l'autre code
    Expert Programmation

    Ma fonction n'était pas à utiliser, mais à étudier, puis à adapter.
    Après si le code que je fournis est suffisamment générique pour resservir tel quel :sol:  (<-- crâneur)


    Citation :
    je reviens sur ce que j'ai dit... il ya encore des petites erreurs.

    EDIT: A ben c'était bien la peiner de crâner, tiens !! :/ 
    Expert Programmation

    Wahou, j'avais pas décortiqué ça :
    1. Select Case ws_source.Cells(i, col).Value
    2. Case Is < 0: Set cells_found = Range(Cells(i + 1, col), Cells(last_row, col)).Find(Abs(ws_source.Cells(i, col).Value), lookat:=xlWhole, searchdirection:=xlNext)
    3. Case Is > 0: Set cells_found = Range(Cells(i + 1, col), Cells(last_row, col)).Find((ws_source.Cells(i, col).Value * -1), lookat:=xlWhole, searchdirection:=xlNext)
    4. Case Is = 0: ...


    Petit rappel de math :
    x * -1 = -x


    Par ailleurs, si x est strictement négatif : Abs(x) = -x

    Donc ton bazar peut s'écrire plus simplement (Sauf que je rajoute les ws_source oubliés ;)  ) :
    1. If ws_source.Cells(i, col).Value <> 0 Then
    2. Set cells_found = ws_source.Range(ws_source.Cells(i + 1, col), ws_source.Cells(last_row, col)).Find(-ws_source.Cells(i, col).Value, lookat:=xlWhole, searchdirection:=xlNext)
    3.  
    4. ' // Et ça laisse de la place pour mettre des trucs ici !
    5.  
    6. Else
    7. LineCopy ws_source.Rows(i), matched, True
    8. End If


    Bon, comme on a de la place là ou je dis qu'il y a de la place ( :sarcastic:  ), tous les trucs qui viennent après, de ta ligne 61 à ta ligne 68, on va pouvoir les y coller.
    Parce que en l'état, si on est passé par la case 0 ( Case Is =0 ), on passe aussi par ce code, et ça, c'est pas terrible.

    (le ton volontairement goguenard employé est destiné à t'inciter à plus de rigueur, la prochaine fois :lol:  )
    Expert Programmation

    (Plus je relis ton code, plus je refais des exemples en reprenant ton code, et plus je trouve que l'utilisation d'objets Range plutôt que de variables entières est élégant (c'est un avis discutable) et simple (peut être pas au premier abord)
    1. ' // first_row = ws_source.Range("B1" ).End(xlDown).Row
    2. first_cell = ws_source.Range("B1" ).End(xlDown)
    3.  
    4. ' // last_row = ws_source.Cells(first_row, 2).End(xlDown).Row
    5. last_cell = first_cell.End(xlDown) ' // <-- Ah, déjà, c'est plus simple !
    6.  
    7. ' // With ws_source.Rows(first_row)
    8. With first_cell.EntireRow ' // <-- Pas plus simple. Différent, logique.
    9. .Copy Worksheets("Matched" ).Rows(1)
    10. .Copy Worksheets("Other" ).Rows(1)
    11. End With
    12.  
    13. col = UCase(InputBox("Enter the Name of the Amount column :" ))
    14. MsgBox "" & col
    15.  
    16. ' // For i = first_row + 1 To last_row
    17. For Each cell In ws_source.Range(first_cell.Offset(col - 2), last_cell.Offset(col - 2)) ' // <-- Un peu moins simple. Mais seulement ici.
    18.  
    19. ' // vide = ws_source.Cells(i, col).Value = ""
    20. ' // If Not vide Then
    21.  
    22. If cell.Value <> "" Then ' // Trop simple
    23. If cell.Value <> 0 Then
    24. Set cells_found = ws_source.Range(cell, last_cell).Find(-cellValue, lookat:=xlWhole, searchdirection:=xlNext)
    25. If Not cells_found Is Nothing Then ' meme montant trouvé
    26. ' // ligne = cells_found.Row
    27. ' // LineCopy ws_source.Rows(ligne), matched, True
    28. ' // LineCopy ws_source.Rows(i), matched, True
    29. LineCopy cell.EntireRow, matched, True ' // C'est pas dix fois
    30. LineCopy cell_found.EntireRow, matched, True ' // plus simple ?
    31. Else
    32. ' // LineCopy ws_source.Rows(i), unmatched, True ' pas trouvé donc copie dans Other
    33. LineCopy cell.EntireRow, unmatched, True ' // C'est pas cent fois plus simple ?
    34. End If
    35. Else
    36. ' // LineCopy ws_source.Rows(i), matched, True
    37. LineCopy cell.EntireRow, matched, True ' // C'est pas mille fois plus simple ?
    38. End If
    Je ne t'impose rien. Ça s'appelle du style, et chaque auteur peut avoir le sien, sans que l'un soit mieux que l'autre. Mais je serai curieux de connaître ton avis sur le sujet ;)  )
    Expert Programmation

    salut zeb,

    Je suis d'accord avec toi sur le fait que l'utilisation de range simplifie grandement le code (dans la plupart des cas et si les range sont explicitement déclarés !!).
    mais c'est sur que la tu as fait fort !!

    le code est tres lisible et tres compréhensible. !!!

    par contre ligne 17 ma variable col est un string.. je ne pense pas qu'excel comprenne le offset(col -2).

    mais sinon j'approuve a 100 %

    je poste mon code tel qu'il était avant...
    1. Dim ws_source As Worksheet
    2. Dim matched As Range
    3. Dim cells_found As Range
    4. Dim unmatched As Range
    5. Dim i As Long
    6. Dim first_row As Long
    7. Dim last_row As Long
    8. Dim col As String
    9. Dim ws_match As Worksheet
    10. Dim lstrow As Long
    11. Dim temp As Worksheet
    12. Dim demand As Variant
    13. Dim vide As Boolean
    14. Dim ligne As Long
    15. Dim somme As Double
    16.  
    17. Set ws_match = Worksheets("Matched")
    18. Set ws_source = Worksheets("Mastersheet")
    19. Set matched = ws_match.Rows(2)
    20. Set unmatched = Worksheets("Other").Rows(2)
    21.  
    22.  
    23. demand = MsgBox("Is there merge columns on the table ?", vbYesNoCancel)
    24. If demand = vbYes Then
    25. ws_source.Columns(4).Delete 'delete merged cells
    26. ws_source.Columns(8).Delete
    27. ElseIf demand = vbCancel Then
    28. Exit Sub
    29. End If
    30.  
    31. ' find first and last row of the table
    32. first_row = ws_source.Range("B1").End(xlDown).Row
    33. last_row = ws_source.Cells(first_row, 2).End(xlDown).Row
    34.  
    35. col = UCase(InputBox("Enter the Name of the Amount column :"))
    36. MsgBox "You have written " & col & " for the column name. ", vbOKOnly
    37.  
    38. somme = WorksheetFunction.Sum(ws_source.Columns(col).Cells)
    39. If Abs(somme) <= 0.05 Then
    40. ws_source.Range(Cells(first_row, 1), Cells(last_row, 10)).Copy matched.Offset(-1) 'si somme = 0 alors copie dans matched
    41. Else
    42. With ws_source.Rows(first_row)
    43. .Copy ws_match.Rows(1)
    44. .Copy Worksheets("Other").Rows(1)
    45. End With
    46.  
    47. Set temp = Worksheets.Add
    48. ws_source.Cells.Copy temp.Cells 'sauvegarde du raport intact
    49.  
    50. For i = first_row + 1 To last_row
    51. 'execute le code pour les cellules non vide et au format numerique de la colonne montant
    52.  
    53. If ws_source.Cells(i, col).Value <> 0 Then
    54. Set cells_found = ws_source.Range(ws_source.Cells(i + 1, col), ws_source.Cells(last_row, col)).Find(-ws_source.Cells(i, col).Value, lookat:=xlWhole, searchdirection:=xlNext)
    55.  
    56. If Not cells_found Is Nothing Then ' meme montant trouvé
    57. ligne = cells_found.Row
    58. LineCopy ws_source.Rows(ligne), matched, True
    59. LineCopy ws_source.Rows(i), matched, True
    60. Else
    61. LineCopy ws_source.Rows(i), unmatched, True ' pas trouvé donc copie ligne dans Other
    62. End If
    63. Else
    64. LineCopy ws_source.Rows(i), matched, True
    65. End If
    66. Next
    67.  
    68. Application.DisplayAlerts = False
    69. temp.Cells.Copy ws_source.Cells
    70. temp.Delete 'suppression feuille temporaire
    71.  
    72. End If

    et je vais le modifier pour voir ce que ca donne avec ce que tu propose.... :D 
    Expert Programmation

    re,

    ALors, en appliquant et corrigeant quelques fautes de frappes j'arrive a un résultat plus que satisfaisant !! mes lignes vides ont disparues ... et mon code est plus compréhensible (merci a la fonction aussi !!!)

    j'arrive a ce résultat :


    1. Dim ws_source As Worksheet
    2. Dim ws_match As Worksheet
    3. Dim first_cell As Range
    4. Dim last_cell As Range
    5. Dim cell As Range
    6. Dim cells_found As Range
    7. Dim matched As Range
    8. Dim unmatched As Range
    9. Dim somme As Double
    10. Dim demand As Variant
    11. Dim col As Long
    12. Dim temp As Worksheet
    13.  
    14. Set ws_source = Worksheets("Mastersheet")
    15. Set ws_match = Worksheets("Matched")
    16. Set matched = ws_match.Rows(2)
    17. Set unmatched = Worksheets("Other").Rows(2)
    18.  
    19. demand = MsgBox("Is there merge columns on the table ?", vbYesNoCancel)
    20. If demand = vbYes Then
    21. ws_source.Columns(4).Delete 'delete merged cells
    22. ws_source.Columns(8).Delete
    23. ElseIf demand = vbCancel Then
    24. Exit Sub
    25. End If
    26.  
    27. ' trouve premiere et derniere cellule pleine dans B1
    28. Set first_cell = ws_source.Range("B1").End(xlDown)
    29. Set last_cell = first_cell.End(xlDown)
    30.  
    31. ' copie en-tete du tableau
    32. With first_cell.EntireRow
    33. .Copy Worksheets("Matched").Rows(1)
    34. .Copy Worksheets("Other").Rows(1)
    35. End With
    36.  
    37. col = UCase(InputBox("Enter the NUMBER of the Amount column :"))
    38. MsgBox "" & col
    39.  
    40. Set temp = Worksheets.Add 'sauvegarde du raport intact
    41. ws_source.Cells.Copy temp.Cells
    42.  
    43. somme = Abs(Round(WorksheetFunction.Sum(ws_source.Columns(col).Cells), 2))
    44. If somme <= 0.05 Then
    45. ws_source.Range(first_cell.EntireRow, last_cell.EntireRow).Copy matched.Offset(-1) 'si somme = 0 alors copie dans matched
    46. Else
    47.  
    48. For Each cell In ws_source.Range(first_cell.Offset(1, col - 2), last_cell.Offset(, col - 2)) ' pour chaque cellule du tableau de la colonne col
    49.  
    50. If cell.Value <> "" Then ' uniquement les cellules pleines
    51. If cell.Value <> 0 Then
    52. Set cells_found = ws_source.Range(cell, last_cell).Find(-cell.Value, lookat:=xlWhole, searchdirection:=xlNext)
    53. If Not cells_found Is Nothing Then ' meme montant trouvé
    54. LineCopy cell.EntireRow, matched, True
    55. LineCopy cells_found.EntireRow, matched, True
    56. Else
    57. ' pas trouvé donc copie dans Other
    58. LineCopy cell.EntireRow, unmatched, True
    59. End If
    60. Else
    61. ' copie dans match les opérations nulles
    62. LineCopy cell.EntireRow, matched, True
    63. End If
    64. End If
    65. Next
    66.  
    67. Application.DisplayAlerts = False 'suppression feuille temporaire
    68. temp.Cells.Copy ws_source.Cells
    69. temp.Delete
    70. End If


    comm on dit en anglais : Brillant !!
    Expert Programmation

    :sol: 

    A la place des lignes 37, 38 et pour répondre à ton problème de col qui est une chaîne de caractères :

    1. Dim userinput As String
    2. Dim col As Integer
    3.  
    4. userinput = InputBox("Never trust user input")
    5. If IsNumeric(userinput) Then
    6. col = Columns(CInt(userinput)).Column
    7. Else
    8. col = Columns(userinput).Column
    9. End If


    Pour la ligne 48, j'ai un tout petit peu mieux à te reproposer (code hyper-générique ;) ) :
    1. For Each cell In ws_source.Range(first_cell, last_cell).Offset(, col - first_cell.Column)


    Et surtout, correction de gros bug !!!!!!!!!!
    Ligne 67, tu désactives les messages d'alerte. Or je ne vois pas que tu les réactives.
    Expert Programmation

    Bon, j'ai tout relu, et je trouve encore un truc à redire.
    (Quand je bossais outre-manche, on me surnommait the perfectionnist :lol:  ).

    Il est plus convenable de traiter les données de la copie plutôt que celle de l'original. A l'issue du traitement, plutôt de d'écraser l'original avec la sauvegarde, puis de supprimer celle-ci, il suffit de supprimer la sauvegarde.

    C'est plus simple, mais c'est surtout plus prudent. Si pour une raison quelconque, ton processus n'aboutit pas, tes données originales ne sont pas altérées.

    A la ligne 14, tu écris :
    1. Set ws_source = Worksheets.Add
    2. Worksheets.("Mastersheet").Cells.Copy ws_source.Cells


    Tu supprimes ensuite la ligne 75, et à suivante, tu mets ws_source à la place de temp. C'est plus joli, non ?
    Lassé par la pub ? Créez un compte