Se connecter avec
S'enregistrer | Connectez-vous

"concatener" des zones et leur appliquer une fonction

Dernière réponse : dans Programmation

Bonjour à tous,

Petite question toute simple. Voila mon code
  1. Private Sub CommandButton2_Click()
  2. Dim i As Integer
  3. 'effacer les pourcentages apparus
  4. For i = 14 To 23
  5. i = i + 1
  6. Range(Cells(13, i), Cells(37, i)).ClearContents
  7. Next
  8. End Sub


Je cherche à appliquer cela a 4 zones en tout (soit i=37to46, i=60to69 et i=83to92).

Pour l'instant je repète ma boucle 4 fois. Existe-t-il un moyen de "concatener" ces 4 zones pour faire une seule boucle ??

Merci à tous :) 
Lassé par la pub ? Créez un compte

Meilleure solution

Expert Programmation

Mais qu'est-ce que tu fais ?
  1. For i = 0 To 4
  2. Range(Cells(13, i * 2 + 15), Cells(37, i * 2 + 15)).ClearContents
  3. Range(Cells(13, i * 2 + 38), Cells(37, i * 2 + 38)).ClearContents
  4. Range(Cells(13, i * 2 + 61), Cells(37, i * 2 + 61)).ClearContents
  5. Range(Cells(13, i * 2 + 84), Cells(37, i * 2 + 84)).ClearContents
  6. Next
Si ça, ça marche. on garde ce qui est commun (en rouge), on regarde ce qui ne l'ai pas (en bleu).

Range(Cells(13, i * 2 + xx), Cells(37, i * 2 + xx)).ClearContents

On a une suite 15, 38, 61, 84. Ben c'est une suite affine, représentable par un polynôme du premier degré, donc TRES facile à trouver :
f(x) = 23x + 15
x : [0, 1, 2, 3] -> N


On arrête les maths, on reviens au VB :
  1. For i = 0 To 4
  2. For j = 0 To 4
  3. Range(Cells(13, 2*i + 23*j + 15), Cells(37, 2*i + 23*j + 15)).ClearContents
  4. Next
  5. Next
Expert Programmation

Moi j'en voit une : séparer la boucle dans une fonction ou un sub, dans lequel tu passe les bons arguments.

Mais je me demande si pour ce que tu fait, il n'existe pas plus simple avec Range(Cells(13,14), Cells(37, 23)).ClearContents (j'ai pas excell sous la main pour tester)

En fait je cherche a supprimer le contenu des cellules toutes les 2 colonnes (O13:o 37, Q13:Q37, ..., W13:W37 (1ere zone) puis AL13:AL37, ..., AT13:AT37 (2eme zone) puis 3e, 4e zone)
Citation :
Mais je me demande si pour ce que tu fait, il n'existe pas plus simple avec Range(Cells(13,14), Cells(37, 23)).ClearContents

Avec ça, tout ma zone est supprimée..

Dans une fonction je vois pas trop, je pense en arriver au meme pb, comment definir ces 4 zones pour une seule boucle ?
Expert Programmation

  1. For i = ...
  2. i = ...


ILLEGAL !!!!

Tu n'as pas le droit de changer la valeur d'un indice à l'intérieur d'une boucle For. (Du moins en algorithmique. Quand tu mettras au langage C, on en reparlera).

Deux façons de faire.

Façon VB
  1. For i = 14 To 23 Step 2
  2. MsgBox i
  3. Next


Façon universelle
  1. For i = 0 To 4
  2. MsgBox i * 2 + 14
  3. Next


Je préconise la seconde forme, le VB n'étant pas le seul langage. Et pis un informaticien, un vrai, ça compte à partir de zéro, pis c'est tout :o 
Expert Programmation

Autre chose
  1. .
  2. A B
  3. 0 37 -> 46
  4. 1 60 -> 69
  5. 2 83 -> 92


Donc B(i)=A(i)+1, et A(i+1) = A(i)+23, quelque soit i.

Donc :
  1. A(i) = Cells(k * 23 + 14)
  2. B(k) = Cells(k * 23 + 14 + 9)
  3. B(k) = A(k).Offset(0, 9)

(Mélange Algo+VB)
Expert Programmation

Bon, le titre me semble plus explicite que le baratin !

Tu connais la directive Union ?
Viens jouer aux échecs avec moi :) 
  1. Dim ma_zone As Range
  2.  
  3. Set ma_zone = Union(Range("A1:A2"), Range("B3:B4"))
  4. Set ma_zone = Union(ma_zone, Range("C5:C6"), Range("D7:D8"))
  5. Set ma_zone = Union(ma_zone, Range("D3:D4"), Range("C1:C2"), Range("A5:A6"), Range("B7:B8"))
  6.  
  7. ma_zone.Interior.ColorIndex = 1


Bon, ben maintenant, on fait une double boucle !
  1. Dim zone_noire As Range
  2. Dim zone_blanche As Range
  3.  
  4. Cells.Interior.ColorIndex = xlNone
  5.  
  6. ' // Union ne marche pas si une des zones est vide
  7. Set zone_noire = Range("A1")
  8. Set zone_blanche = Range("C1")
  9.  
  10. For i = 0 To 3
  11. For j = 0 To 3
  12. Set zone_noire = Union(zone_noire, Range(Cells(i * 4 + 1, j * 4 + 1), Cells(i * 4 + 2, j * 4 + 2)))
  13. Set zone_noire = Union(zone_noire, Range(Cells(i * 4 + 3, j * 4 + 3), Cells(i * 4 + 4, j * 4 + 4)))
  14.  
  15. Set zone_blanche = Union(zone_blanche, Range(Cells(i * 4 + 1, j * 4 + 3), Cells(i * 4 + 2, j * 4 + 4)))
  16. Set zone_blanche = Union(zone_blanche, Range(Cells(i * 4 + 3, j * 4 + 1), Cells(i * 4 + 4, j * 4 + 2)))
  17. Next
  18. Next
  19. zone_noire.Interior.ColorIndex = 1
  20. zone_blanche.Interior.ColorIndex = 2

Ah Zeb!
Citation :
ILLEGAL !!!!
:lol: 

oui c'est vrai que je me suis affranchi de certaines règles basiques ..

Donc après une première reflexion je suis arrivé à
  1. 'effacer les pourcentages apparus
  2. For i = 0 To 4
  3. Range(Cells(13, i * 2 + 15), Cells(37, i * 2 + 15)).ClearContents
  4. Range(Cells(13, i * 2 + 38), Cells(37, i * 2 + 38)).ClearContents
  5. Range(Cells(13, i * 2 + 61), Cells(37, i * 2 + 61)).ClearContents
  6. Range(Cells(13, i * 2 + 84), Cells(37, i * 2 + 84)).ClearContents
  7. Next
qui marche pil poil comme il faut;

Mais du coup si bien parti je voulais comprendre ta logique. Pour le plateau du jeu d'echec pas trop de pb. J'ai donc essayé de condenser ces 4 lignes ci dessus.
  1. For j = 0 To 3
  2. Set zone = Range(Cells(13, j * 23 + 15), Cells(37, j * 23 + 23))
  3. For Each c In zone_noire
  4. c.ClearContents 'qqchose pour effacer toutes les 2 colonnes dans ces zones car ça, ça m'efface tout à l'intérieur
  5. Next
  6. Next

Mes zones sont bien définies mais je dois trouver qqch pour que la cellules passe de col 15 à col 17 sans effacer la 16 ...

J'espere que je suis clair.. :whistle: 
Expert Programmation

Ça marche ? :??: 
Alors tant mieux ! :) 
Maintenant on peut pinailler. :o 

Ben oui, quoi. On va la définir cette zone multiple :
  1. Dim ma_zone As Range
  2. Dim i As Long
  3. Dim j As Long
  4.  
  5. For i = 0 To 4
  6. For j = 0 To 4
  7. Set ma_zone = Union(ma_zone, _
  8. Range(Cells(13, 2 * i + 23 * j + 15), _
  9. Cells(37, 2 * i + 23 * j + 15)))
  10. Next
  11. Next
  12.  
  13. ma_zone.ClearContents


Bon, comme ce crétin de VB ne sait pas ajouter RIEN à quelque chose, il faut différencier le code si la zone est encore vide ou pas :
  1. Dim zone_globale As Range
  2. Dim ma_zone As Range
  3.  
  4. Dim i As Long
  5. Dim j As Long
  6.  
  7. For i = 0 To 4
  8. For j = 0 To 4
  9.  
  10. Set ma_zone = Range(Cells(13, 2 * i + 23 * j + 15), _
  11. Cells(37, 2 * i + 23 * j + 15))
  12.  
  13. If zone_globale Is Nothing Then
  14. Set zone_globale = ma_zone
  15. Else
  16. Set zone_globale = Union(zone_globale, ma_zone)
  17. End If
  18. Next
  19. Next
  20.  
  21. zone_globale.ClearContents


Autre version :
  1. Dim zone_globale As Range
  2.  
  3. Dim i As Long
  4. Dim j As Long
  5.  
  6. For i = 0 To 4
  7. For j = 0 To 4
  8. If zone_globale Is Nothing Then
  9. Set zone_globale = Range(Cells(13, 2 * i + 23 * j + 15), _
  10. Cells(37, 2 * i + 23 * j + 15))
  11. Else
  12. Set zone_globale = Union(zone_globale, _
  13. Range(Cells(13, 2 * i + 23 * j + 15), _
  14. Cells(37, 2 * i + 23 * j + 15)))
  15. End If
  16. Next
  17. Next
  18.  
  19. zone_globale.ClearContents


Beurk.

Voici donc la fonction Union, revue et corrigéé par votre serviteur :
  1. Function Union_X(arg1 As Range, arg2 As Range, _
  2. Optional arg3 As Range, Optional arg4 As Range, Optional arg5 As Range, _
  3. Optional arg6 As Range, Optional arg7 As Range, Optional arg8 As Range, _
  4. Optional arg9 As Range, Optional arg10 As Range, Optional arg11 As Range, _
  5. Optional arg12 As Range, Optional arg13 As Range, Optional arg14 As Range, _
  6. Optional arg15 As Range, Optional arg16 As Range, Optional arg17 As Range, _
  7. Optional arg18 As Range, Optional arg19 As Range, Optional arg20 As Range, _
  8. Optional arg21 As Range, Optional arg22 As Range, Optional arg23 As Range, _
  9. Optional arg24 As Range, Optional arg25 As Range, Optional arg26 As Range, _
  10. Optional arg27 As Range, Optional arg28 As Range, Optional arg29 As Range, _
  11. Optional arg30 As Range) As Range
  12. If arg1 Is Nothing And arg2 Is Nothing And arg3 Is Nothing And arg4 Is Nothing And _
  13. arg5 Is Nothing And arg6 Is Nothing And arg7 Is Nothing And arg8 Is Nothing And _
  14. arg9 Is Nothing And arg10 Is Nothing And arg11 Is Nothing And arg12 Is Nothing And _
  15. arg13 Is Nothing And arg14 Is Nothing And arg15 Is Nothing And arg16 Is Nothing And _
  16. arg17 Is Nothing And arg18 Is Nothing And arg19 Is Nothing And arg20 Is Nothing And _
  17. arg21 Is Nothing And arg22 Is Nothing And arg23 Is Nothing And arg24 Is Nothing And _
  18. arg25 Is Nothing And arg26 Is Nothing And arg27 Is Nothing And arg28 Is Nothing And _
  19. arg29 Is Nothing And arg30 Is Nothing Then
  20. Set Union_X = Nothing
  21. Else
  22. If arg1 Is Nothing Then
  23. Set Union_X = Union_X(arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, _
  24. arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, _
  25. arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25, _
  26. arg26, arg27, arg28, arg29, arg30)
  27. Else
  28. Dim u As Range
  29. Set u = Union_X(arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, _
  30. arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, _
  31. arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25, _
  32. arg26, arg27, arg28, arg29, arg30)
  33. If u Is Nothing Then
  34. Set Union_X = arg1
  35. Else
  36. Set Union_X = Union(arg1, u)
  37. End If
  38. End If
  39. End If
  40. End Function

:sol: 

Et voilà le code pour Popeye :
  1. Dim zone_globale As Range
  2.  
  3. Dim i As Long
  4. Dim j As Long
  5.  
  6. For i = 0 To 4
  7. For j = 0 To 4
  8. Set zone_globale = Union(zone_globale, _
  9. Range(Cells(13, 2 * i + 23 * j + 15), _
  10. Cells(37, 2 * i + 23 * j + 15)))
  11. Next
  12. Next
  13. zone_globale.faire_quelque_chose
Lassé par la pub ? Créez un compte