OVH Cloud OVH Cloud

Une boucle qui ne boucle pas

13 réponses
Avatar
Patrick BASTARD
Bonsoir, toutes et tous.

Qui aurait l'amabilité de me dire ou je merdoie ?

Cette @#&...@@ de macro efface toutes les colonnes du premier onglet,
au lieu de n'effacer que certaines colonnes de tous les onglets (sauf
Récap.)

Sub ménage()
Dim Sh As Worksheet
'Application.ScreenUpdating = False
For Each Sh In ThisWorkbook.Sheets
If Sh.Name <> "Récap" Then
'Insère une colonne avant A
Columns("A:A").Insert Shift:=xlToRight
'Numérote les lignes pour le tri
Range("A1").FormulaR1C1 = "1"
Range("A2").FormulaR1C1 = "2"
Range("A1:A2").AutoFill Destination:=Range("A1:A1000"),
Type:=xlFillDefault
'Trie sur colonnes C et A
Rows("1:1000").Sort Key1:=Range("C1"), Order1:=xlAscending,
Key2:=Range("A1") _
, Order2:=xlAscending, Header:=xlGuess,
OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
'Supprime les colonnes A et B
Columns("A:B").Delete Shift:=xlToLeft
'Supprime les colonnes G à M
Columns("G:M").Delete Shift:=xlToLeft
'Ajuste la largeur des colonnes
Cells.EntireColumn.AutoFit
'Range("A1").CurrentRegion.Select
'Selection.Copy
End If
'*********DEVRAIT PASSER A L'ONGLET SUIVANT, MAIS NON
Next Sh
' ;-( ;-(
'Application.ScreenUpdating = True
End Sub

Avec mes remerciements zanticipés zé chaleureux.
--
Bien amicordialement,
P. Bastard

10 réponses

1 2
Avatar
anonymousA
bonsoir,

ce sont les références aux plages ( range, columns) qui posent problème.
Ce n'est pas parce que tu parcours la collection des feuilles que les
plages sont pour autant référencées à automatiquement au parcours de
cette collection. En fait comme tu ne mets aucune référence, les plages
sont référencées à la feuille active du moment et point barre.

tu vois la différence entre
for each sh in thisworkbook.sheets
sh.range("A1")=2 et
range("A1")=2
next

essaye et tu verras.

A+

Bonsoir, toutes et tous.

Qui aurait l'amabilité de me dire ou je merdoie ?

Cette @#&...@@ de macro efface toutes les colonnes du premier onglet,
au lieu de n'effacer que certaines colonnes de tous les onglets (sauf
Récap.)

Sub ménage()
Dim Sh As Worksheet
'Application.ScreenUpdating = False
For Each Sh In ThisWorkbook.Sheets
If Sh.Name <> "Récap" Then
'Insère une colonne avant A
Columns("A:A").Insert Shift:=xlToRight
'Numérote les lignes pour le tri
Range("A1").FormulaR1C1 = "1"
Range("A2").FormulaR1C1 = "2"
Range("A1:A2").AutoFill Destination:=Range("A1:A1000"),
Type:=xlFillDefault
'Trie sur colonnes C et A
Rows("1:1000").Sort Key1:=Range("C1"), Order1:=xlAscending,
Key2:=Range("A1") _
, Order2:=xlAscending, Header:=xlGuess,
OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
'Supprime les colonnes A et B
Columns("A:B").Delete Shift:=xlToLeft
'Supprime les colonnes G à M
Columns("G:M").Delete Shift:=xlToLeft
'Ajuste la largeur des colonnes
Cells.EntireColumn.AutoFit
'Range("A1").CurrentRegion.Select
'Selection.Copy
End If
'*********DEVRAIT PASSER A L'ONGLET SUIVANT, MAIS NON
Next Sh
' ;-( ;-(
'Application.ScreenUpdating = True
End Sub

Avec mes remerciements zanticipés zé chaleureux.


Avatar
Patrick BASTARD
Bonjour, *anonymousA*
J'ai lu ton post 42a489c5$0$25050$
avec le plus grand intéret :

Sub ménage2()
Dim Sh As Worksheet
'Application.ScreenUpdating = False
For Each Sh In ThisWorkbook.Sheets
If Sh.Name <> "Récap" Then
Sh.Columns("A:A").Insert Shift:=xlToRight
Sh.Range("A1").FormulaR1C1 = "1"
Sh.Range("A2").FormulaR1C1 = "2"
Sh.Range("A1:A2").AutoFill Destination:=Sh.Range("A1:A1000"),
Type:=xlFillDefault
Rows("1:1000").Sort Key1:=Range("C1"), Order1:=xlAscending,
Key2:=Range("A1") _
, Order2:=xlAscending, Header:=xlGuess,
OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
Sh.Columns("A:B").Delete Shift:=xlToLeft
Sh.Columns("G:M").Delete Shift:=xlToLeft
Sh.Cells.EntireColumn.AutoFit
'Range("A1").CurrentRegion.Select
'Selection.Copy
End If
Next Sh
'Application.ScreenUpdating = True
End Sub

Comme ça, ça marche.

Merci, beaucoup...


--
Bien amicordialement,
P. Bastard

bonsoir,

ce sont les références aux plages ( range, columns) qui posent
problème. Ce n'est pas parce que tu parcours la collection des
feuilles que les plages sont pour autant référencées à
automatiquement au parcours de cette collection. En fait comme tu ne
mets aucune référence, les plages sont référencées à la feuille
active du moment et point barre.
tu vois la différence entre
for each sh in thisworkbook.sheets
sh.range("A1")=2 et
range("A1")=2
next

essaye et tu verras.

A+

Bonsoir, toutes et tous.

Qui aurait l'amabilité de me dire ou je merdoie ?

Cette @#&...@@ de macro efface toutes les colonnes du premier onglet,
au lieu de n'effacer que certaines colonnes de tous les onglets (sauf
Récap.)

Sub ménage()
Dim Sh As Worksheet
'Application.ScreenUpdating = False
For Each Sh In ThisWorkbook.Sheets
If Sh.Name <> "Récap" Then
'Insère une colonne avant A
Columns("A:A").Insert Shift:=xlToRight
'Numérote les lignes pour le tri
Range("A1").FormulaR1C1 = "1"
Range("A2").FormulaR1C1 = "2"
Range("A1:A2").AutoFill Destination:=Range("A1:A1000"),
Type:=xlFillDefault
'Trie sur colonnes C et A
Rows("1:1000").Sort Key1:=Range("C1"),
Order1:=xlAscending, Key2:=Range("A1") _
, Order2:=xlAscending, Header:=xlGuess,
OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
'Supprime les colonnes A et B
Columns("A:B").Delete Shift:=xlToLeft
'Supprime les colonnes G à M
Columns("G:M").Delete Shift:=xlToLeft
'Ajuste la largeur des colonnes
Cells.EntireColumn.AutoFit
'Range("A1").CurrentRegion.Select
'Selection.Copy
End If
'*********DEVRAIT PASSER A L'ONGLET SUIVANT, MAIS NON
Next Sh
' ;-( ;-(
'Application.ScreenUpdating = True
End Sub

Avec mes remerciements zanticipés zé chaleureux.




Avatar
Modeste
Bonsour® Patrick ,
il faut qualifier la feuille sur laquelle tu appliques l'action
If Sh.Name <> "Récap" Then
With Sh
'et ensuite l'objet(range,rows,columns) précédé d'un point
'-------v le point devant l'objet Columns (ou Range,Rows,Cells )
.Columns("A:A").Insert Shift:=xlToRight
'------ etc....
../..
End With
Next Sh

ou bien activer la feuille sur laquelle tu appliques l'action (exemple
ci-dessous)

Sub ménage()
Dim Sh As Worksheet
'Application.ScreenUpdating = False
For Each Sh In ThisWorkbook.Sheets
If Sh.Name <> "Récap" Then
'------------- ICI par exemple -----

' Sh.Activate
'Insère une colonne avant A
Columns("A:A").Insert Shift:=xlToRight
'Numérote les lignes pour le tri
Range("A1").FormulaR1C1 = "1"
Range("A2").FormulaR1C1 = "2"
Range("A1:A2").AutoFill Destination:=Range("A1:A1000"),
Type:=xlFillDefault
'Trie sur colonnes C et A
Rows("1:1000").Sort Key1:=Range("C1"),
Order1:=xlAscending, Key2:=Range("A1") _
, Order2:=xlAscending, Header:=xlGuess,
OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
'Supprime les colonnes A et B
Columns("A:B").Delete Shift:=xlToLeft
'Supprime les colonnes G à M
Columns("G:M").Delete Shift:=xlToLeft
'Ajuste la largeur des colonnes
Cells.EntireColumn.AutoFit
'Range("A1").CurrentRegion.Select
'Selection.Copy
End If
'*********DEVRAIT PASSER A L'ONGLET SUIVANT, MAIS NON
Next Sh
' ;-( ;-(
'Application.ScreenUpdating = True
End Sub

Avec mes remerciements zanticipés zé chaleureux.


Avatar
anonymousA
eh oui!. Utiliser la mot clé with sh -end with la rendrait d'ailleurs à
la fois encore plus lisible et plus rapide.
me semble d'ailleurs qu'il manque encore un sh. devant Rows("1:1000")
ainsi que devant Range("C1") et Range("A1") car tous les range
quelqu'ils soient doivent être référencés à la feuille en cours de la
collection, sinon tu risques à terme d'avoir des surprises douloureuses.

Cordialement,


Bonjour, *anonymousA*
J'ai lu ton post 42a489c5$0$25050$
avec le plus grand intéret :

Sub ménage2()
Dim Sh As Worksheet
'Application.ScreenUpdating = False
For Each Sh In ThisWorkbook.Sheets
If Sh.Name <> "Récap" Then
Sh.Columns("A:A").Insert Shift:=xlToRight
Sh.Range("A1").FormulaR1C1 = "1"
Sh.Range("A2").FormulaR1C1 = "2"
Sh.Range("A1:A2").AutoFill Destination:=Sh.Range("A1:A1000"),
Type:=xlFillDefault
Rows("1:1000").Sort Key1:=Range("C1"), Order1:=xlAscending,
Key2:=Range("A1") _
, Order2:=xlAscending, Header:=xlGuess,
OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
Sh.Columns("A:B").Delete Shift:=xlToLeft
Sh.Columns("G:M").Delete Shift:=xlToLeft
Sh.Cells.EntireColumn.AutoFit
'Range("A1").CurrentRegion.Select
'Selection.Copy
End If
Next Sh
'Application.ScreenUpdating = True
End Sub

Comme ça, ça marche.

Merci, beaucoup...




Avatar
Patrick BASTARD
Bonjoir, *Modeste*

Et merci infiniment de tes conseils.

Néophyte débutant primaire en VBA, j'avais tenté d'épurer le code que me
donnait l'enregistreur, mais, si j'ai bien compris, j'aurais dû laisser un
.activate en début de procédure pour que le p'tit bonhomme dans la machine
sache quel onglet il doit se coltiner.
Peut-être plus simple que les with...end with et les ;Range... du mions dans
ce cas.

Une nouvelle fois, Merci.

;-)


--
Bien amicordialement,
P. Bastard


Bonsour® Patrick ,
il faut qualifier la feuille sur laquelle tu appliques l'action
If Sh.Name <> "Récap" Then
With Sh
'et ensuite l'objet(range,rows,columns) précédé d'un point
'-------v le point devant l'objet Columns (ou Range,Rows,Cells )
.Columns("A:A").Insert Shift:=xlToRight
'------ etc....
../..
End With
Next Sh

ou bien activer la feuille sur laquelle tu appliques l'action (exemple
ci-dessous)

Sub ménage()
Dim Sh As Worksheet
'Application.ScreenUpdating = False
For Each Sh In ThisWorkbook.Sheets
If Sh.Name <> "Récap" Then
'------------- ICI par exemple -----

' Sh.Activate
'Insère une colonne avant A
Columns("A:A").Insert Shift:=xlToRight
'Numérote les lignes pour le tri
Range("A1").FormulaR1C1 = "1"
Range("A2").FormulaR1C1 = "2"
Range("A1:A2").AutoFill Destination:=Range("A1:A1000"),
Type:=xlFillDefault
'Trie sur colonnes C et A
Rows("1:1000").Sort Key1:=Range("C1"),
Order1:=xlAscending, Key2:=Range("A1") _
, Order2:=xlAscending, Header:=xlGuess,
OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
'Supprime les colonnes A et B
Columns("A:B").Delete Shift:=xlToLeft
'Supprime les colonnes G à M
Columns("G:M").Delete Shift:=xlToLeft
'Ajuste la largeur des colonnes
Cells.EntireColumn.AutoFit
'Range("A1").CurrentRegion.Select
'Selection.Copy
End If
'*********DEVRAIT PASSER A L'ONGLET SUIVANT, MAIS NON
Next Sh
' ;-( ;-(
'Application.ScreenUpdating = True
End Sub

Avec mes remerciements zanticipés zé chaleureux.




Avatar
Patrick BASTARD
Bonjour, *anonymousA*
J'ai lu ton post 42a4a151$0$25050$
avec le plus grand intéret :

Pourtant, actuellement, ça mAAArche.
Je vais tester de ce pas le sh.activate de Modeste.

P.S : j'aime pô les surprises douloureuses.

Bien amicordialement,
Schtroumpf GrincheuxEtDouillet

eh oui!. Utiliser la mot clé with sh -end with la rendrait d'ailleurs
à la fois encore plus lisible et plus rapide.
me semble d'ailleurs qu'il manque encore un sh. devant Rows("1:1000")
ainsi que devant Range("C1") et Range("A1") car tous les range
quelqu'ils soient doivent être référencés à la feuille en cours de la
collection, sinon tu risques à terme d'avoir des surprises
douloureuses.
Cordialement,


Bonjour, *anonymousA*
J'ai lu ton post 42a489c5$0$25050$
avec le plus grand intéret :

Sub ménage2()
Dim Sh As Worksheet
'Application.ScreenUpdating = False
For Each Sh In ThisWorkbook.Sheets
If Sh.Name <> "Récap" Then
Sh.Columns("A:A").Insert Shift:=xlToRight
Sh.Range("A1").FormulaR1C1 = "1"
Sh.Range("A2").FormulaR1C1 = "2"
Sh.Range("A1:A2").AutoFill
Destination:=Sh.Range("A1:A1000"), Type:=xlFillDefault
Rows("1:1000").Sort Key1:=Range("C1"),
Order1:=xlAscending, Key2:=Range("A1") _
, Order2:=xlAscending, Header:=xlGuess,
OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
Sh.Columns("A:B").Delete Shift:=xlToLeft
Sh.Columns("G:M").Delete Shift:=xlToLeft
Sh.Cells.EntireColumn.AutoFit
'Range("A1").CurrentRegion.Select
'Selection.Copy
End If
Next Sh
'Application.ScreenUpdating = True
End Sub

Comme ça, ça marche.

Merci, beaucoup...




Avatar
anonymousA
M'excuse de m'immiscer mais il n'est pas plus simple de faire des
activate. Ca peut le sembler mais chaque qu'il est possible d'eviter
Activate, il faut le faire car cela ralentit inutilement les macros.
Tu peux "pratiquement" tout faire sans Activate. Seuls de très rares cas
(mais cependant,il y en a) nécessitent un emploi de cette instruction.
Par ailleurs, je ne suis pas sur qu'on puisse te qualifier de néophyte
débutant primaire. tu es bien trop "Modeste".

A+


Bonjoir, *Modeste*

Et merci infiniment de tes conseils.

Néophyte débutant primaire en VBA, j'avais tenté d'épurer le code que me
donnait l'enregistreur, mais, si j'ai bien compris, j'aurais dû laisser un
.activate en début de procédure pour que le p'tit bonhomme dans la machine
sache quel onglet il doit se coltiner.
Peut-être plus simple que les with...end with et les ;Range... du mions dans
ce cas.

Une nouvelle fois, Merci.

;-)




Avatar
Patrick BASTARD
Oupps...

Maudite chirogourdie :

Lire, bien entendu :
...et les .Range... du moins dans ce cas.


Bonjoir, *Modeste*

Et merci infiniment de tes conseils.

Néophyte débutant primaire en VBA, j'avais tenté d'épurer le code que
me donnait l'enregistreur, mais, si j'ai bien compris, j'aurais dû
laisser un .activate en début de procédure pour que le p'tit bonhomme
dans la machine sache quel onglet il doit se coltiner.
Peut-être plus simple que les with...end with et les ;Range... du
mions dans ce cas.

Une nouvelle fois, Merci.

;-)



Bonsour® Patrick ,
il faut qualifier la feuille sur laquelle tu appliques l'action
If Sh.Name <> "Récap" Then
With Sh
'et ensuite l'objet(range,rows,columns) précédé d'un point
'-------v le point devant l'objet Columns (ou Range,Rows,Cells )
.Columns("A:A").Insert Shift:=xlToRight
'------ etc....
../..
End With
Next Sh

ou bien activer la feuille sur laquelle tu appliques l'action
(exemple ci-dessous)

Sub ménage()
Dim Sh As Worksheet
'Application.ScreenUpdating = False
For Each Sh In ThisWorkbook.Sheets
If Sh.Name <> "Récap" Then
'------------- ICI par exemple -----

' Sh.Activate
'Insère une colonne avant A
Columns("A:A").Insert Shift:=xlToRight
'Numérote les lignes pour le tri
Range("A1").FormulaR1C1 = "1"
Range("A2").FormulaR1C1 = "2"
Range("A1:A2").AutoFill Destination:=Range("A1:A1000"),
Type:=xlFillDefault
'Trie sur colonnes C et A
Rows("1:1000").Sort Key1:=Range("C1"),
Order1:=xlAscending, Key2:=Range("A1") _
, Order2:=xlAscending,
Header:=xlGuess, OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
'Supprime les colonnes A et B
Columns("A:B").Delete Shift:=xlToLeft
'Supprime les colonnes G à M
Columns("G:M").Delete Shift:=xlToLeft
'Ajuste la largeur des colonnes
Cells.EntireColumn.AutoFit
'Range("A1").CurrentRegion.Select
'Selection.Copy
End If
'*********DEVRAIT PASSER A L'ONGLET SUIVANT, MAIS NON
Next Sh
' ;-( ;-(
'Application.ScreenUpdating = True
End Sub

Avec mes remerciements zanticipés zé chaleureux.






Avatar
Patrick BASTARD
:-)

M'excuse de m'immiscer mais il n'est pas plus simple de faire des
activate. Ca peut le sembler mais chaque qu'il est possible d'eviter
Activate, il faut le faire car cela ralentit inutilement les macros.
Tu peux "pratiquement" tout faire sans Activate. Seuls de très rares
cas (mais cependant,il y en a) nécessitent un emploi de cette
instruction. Par ailleurs, je ne suis pas sur qu'on puisse te
qualifier de néophyte débutant primaire. tu es bien trop "Modeste".


Si seulement !!!
Mais merci quand même.

--
Bien amicordialement,
P. Bastard


A+


Bonjoir, *Modeste*

Et merci infiniment de tes conseils.

Néophyte débutant primaire en VBA, j'avais tenté d'épurer le code
que me donnait l'enregistreur, mais, si j'ai bien compris, j'aurais
dû laisser un .activate en début de procédure pour que le p'tit
bonhomme dans la machine sache quel onglet il doit se coltiner.
Peut-être plus simple que les with...end with et les ;Range... du
mions dans ce cas.

Une nouvelle fois, Merci.

;-)




Avatar
anonymousA
Enfin pour finir, prends garde aux incohérences potentielles de tes
déclarations de variables par rapport à la réalité de ton classeur. En
effet , autant il est de bon usage de déclarer ses variables autant on
peut se trouver dans des situations inconfortables.
Dans ton code, tu écris Dim sh as worksheet puis tu parcours la
collection sheets de thisworkbook, or si tu as p.e une feuille graphique
(qui fait partie de la collection sheets mais n'est pas une worksheet) ,
ton code va se planter car sh n'est pas un objet Chart .
Si tu es certain de ne pas avoir d'autres objets que des worksheets tu
peux écrire sans inquiétude ce que tu as écrit. Dans le cas contraire,
une déclaration de variable de type Object sera + adaptée. Ceci dit, ca
ne te dispenserait pas de faire une gestion d'erreur étant entendu que
tu ne peux pas faire un certain nombre d'actions permises sur une
feuille de type worksheet mais pas sur une feuille de type Chart.


Bonjour, *anonymousA*
J'ai lu ton post 42a4a151$0$25050$
avec le plus grand intéret :

Pourtant, actuellement, ça mAAArche.
Je vais tester de ce pas le sh.activate de Modeste.

P.S : j'aime pô les surprises douloureuses.

Bien amicordialement,
Schtroumpf GrincheuxEtDouillet


eh oui!. Utiliser la mot clé with sh -end with la rendrait d'ailleurs
à la fois encore plus lisible et plus rapide.
me semble d'ailleurs qu'il manque encore un sh. devant Rows("1:1000")
ainsi que devant Range("C1") et Range("A1") car tous les range
quelqu'ils soient doivent être référencés à la feuille en cours de la
collection, sinon tu risques à terme d'avoir des surprises
douloureuses.
Cordialement,



Bonjour, *anonymousA*
J'ai lu ton post 42a489c5$0$25050$
avec le plus grand intéret :

Sub ménage2()
Dim Sh As Worksheet
'Application.ScreenUpdating = False
For Each Sh In ThisWorkbook.Sheets
If Sh.Name <> "Récap" Then
Sh.Columns("A:A").Insert Shift:=xlToRight
Sh.Range("A1").FormulaR1C1 = "1"
Sh.Range("A2").FormulaR1C1 = "2"
Sh.Range("A1:A2").AutoFill
Destination:=Sh.Range("A1:A1000"), Type:=xlFillDefault
Rows("1:1000").Sort Key1:=Range("C1"),
Order1:=xlAscending, Key2:=Range("A1") _
, Order2:=xlAscending, Header:=xlGuess,
OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal, DataOption2 _
:=xlSortNormal
Sh.Columns("A:B").Delete Shift:=xlToLeft
Sh.Columns("G:M").Delete Shift:=xlToLeft
Sh.Cells.EntireColumn.AutoFit
'Range("A1").CurrentRegion.Select
'Selection.Copy
End If
Next Sh
'Application.ScreenUpdating = True
End Sub

Comme ça, ça marche.

Merci, beaucoup...









1 2