Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Modification d'une partie du contenu de cellules si le mot de début est en majuscules

10 réponses
Avatar
Coriandre
Bonjour,

Sur une feuille Excel, dans une plage nommée "toto", je souhaiterais
sélectionner de haut en bas les lignes qui _commencent_ par un mot
en majuscule, mot de longueur variable (mais au moins 3 lettres).
A la première de ces lignes serait ajouté le chiffre 1 suivi d'une
parenthèse : ")" .
A la seconde de ces lignes serait ajouté le chiffre 2 suivi d'une
parenthèse : ")" .
Etc.

Les lignes qui, ou bien ne sont pas dans la plage, ou bien ne commencent pas
par un mot en majuscule, resteraient sans changement.

A partir de :

BLABLA et blablabla
BLIBLI et blablabla
bloblo et blablabla et BLABLABLA
BLOUBLOU et blablabla

on obtiendrait donc :

1) BLABLA et blablabla
2) BLIBLI et blablabla
bloblo et blablabla et BLABLABLA
3) BLOUBLOU et blablabla

Ces modifications doivent au mieux intervenir spontanément à
chaque changement du contenu de la plage "toto"
(utilisation de "Private Sub Worksheet_Change" ?).
Si ce n'est pas possible, je m'arrangerais d'une macro à déclencher.

Comment procéder ?
Merci de votre aide.

--
Coriandre

10 réponses

Avatar
Brunos
Bonjour Coriandre,
Exemple de code:

sub procedure()
Dim n As Integer
n = 1
For Each c In Range("toto")
If Len(c.Value) > 2 Then
If UCase(Left(c.Value, 1)) = Left(c.Value, 1) Then
c.Value = n & ")" & c.Value
n = n + 1
End If
End I
Next
End Sub

http://cjoint.com/?bokHlEs7Xx


"Coriandre" a écrit dans le message de news:

Bonjour,

Sur une feuille Excel, dans une plage nommée "toto", je souhaiterais
sélectionner de haut en bas les lignes qui _commencent_ par un mot
en majuscule, mot de longueur variable (mais au moins 3 lettres).
A la première de ces lignes serait ajouté le chiffre 1 suivi d'une
parenthèse : ")" .
A la seconde de ces lignes serait ajouté le chiffre 2 suivi d'une
parenthèse : ")" .
Etc.

Les lignes qui, ou bien ne sont pas dans la plage, ou bien ne commencent
pas
par un mot en majuscule, resteraient sans changement.

A partir de :

BLABLA et blablabla
BLIBLI et blablabla
bloblo et blablabla et BLABLABLA
BLOUBLOU et blablabla

on obtiendrait donc :

1) BLABLA et blablabla
2) BLIBLI et blablabla
bloblo et blablabla et BLABLABLA
3) BLOUBLOU et blablabla

Ces modifications doivent au mieux intervenir spontanément à
chaque changement du contenu de la plage "toto"
(utilisation de "Private Sub Worksheet_Change" ?).
Si ce n'est pas possible, je m'arrangerais d'une macro à déclencher.

Comment procéder ?
Merci de votre aide.

--
Coriandre




Avatar
Coriandre
Merci Brunos de ta rapide réponse.

Le code fonctionne très bien pour une seule exécution de la macro.
Si on reclique sur le bouton, cela rajoute les 1), 2), etc. à ceux déjà
existants :

1) 1) BLABLA
2) 2) BLOBLOBLO...

Or le contenu de la plage est susceptible de changer, une ligne passant au
dessus de l'autre et son contenu se modifiant, et je souhaiterais qu'à
chaque fois, le même processus se réactive.

Si :

1) BLABLA
bloblo
2) BLOUBLOU

devient :

bloblo
BLOUBLOU
CLAPCLAP

On doit toujours obtenir la première ligne de majuscules avec 1) devant, la
seconde avec 2) devant, etc, c'est à dire :

bloblo
1) BLOUBLOU
2) CLAPCLAP

J'ai bien tenté de poser une condition avec "IsNumeric" pour enlever le 1)
déjà présent, sans succès, vu que je manipule très mal les fonctions left et
len...
D'autant qu'une ligne peut commencer par un chiffre mais non suivi de
parenthèse.
Elle ne doit alors pas être modifiée par une condition qui ôterait tout
chiffre en début de cellule ; ex. :

"2 équipes"
doit rester tel quel, tandis que :
"2) Equipe X"
doit pouvoir changer.


Merci de votre aide.

--
Coriandre

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


"Brunos" a écrit dans le message de
news:
Bonjour Coriandre,
Exemple de code:

sub procedure()
Dim n As Integer
n = 1
For Each c In Range("toto")
If Len(c.Value) > 2 Then
If UCase(Left(c.Value, 1)) = Left(c.Value, 1) Then
c.Value = n & ")" & c.Value
n = n + 1
End If
End I
Next
End Sub

http://cjoint.com/?bokHlEs7Xx


Avatar
Brunos
Effectivement, je n'avais pas bien perçu la complexité...
Le problème est que le marquage se fait dans la même cellule que le texte
marqué. Donc il faudrait effacer le prédédent marquage avant de remarquer.
C'est compliqué.
Pourrais-tu marquer le texte dans une colonne à côté ?
Je te donne un exemple qui marche sans macro : http://cjoint.com/?bolLOtuZ0n
Brunos

"Coriandre" a écrit dans le message de news:
%
Merci Brunos de ta rapide réponse.

Le code fonctionne très bien pour une seule exécution de la macro.
Si on reclique sur le bouton, cela rajoute les 1), 2), etc. à ceux déjà
existants :

1) 1) BLABLA
2) 2) BLOBLOBLO...

Or le contenu de la plage est susceptible de changer, une ligne passant au
dessus de l'autre et son contenu se modifiant, et je souhaiterais qu'à
chaque fois, le même processus se réactive.

Si :

1) BLABLA
bloblo
2) BLOUBLOU

devient :

bloblo
BLOUBLOU
CLAPCLAP

On doit toujours obtenir la première ligne de majuscules avec 1) devant,
la
seconde avec 2) devant, etc, c'est à dire :

bloblo
1) BLOUBLOU
2) CLAPCLAP

J'ai bien tenté de poser une condition avec "IsNumeric" pour enlever le 1)
déjà présent, sans succès, vu que je manipule très mal les fonctions left
et len...
D'autant qu'une ligne peut commencer par un chiffre mais non suivi de
parenthèse.
Elle ne doit alors pas être modifiée par une condition qui ôterait tout
chiffre en début de cellule ; ex. :

"2 équipes"
doit rester tel quel, tandis que :
"2) Equipe X"
doit pouvoir changer.


Merci de votre aide.

--
Coriandre

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


"Brunos" a écrit dans le message de
news:
Bonjour Coriandre,
Exemple de code:

sub procedure()
Dim n As Integer
n = 1
For Each c In Range("toto")
If Len(c.Value) > 2 Then
If UCase(Left(c.Value, 1)) = Left(c.Value, 1) Then
c.Value = n & ")" & c.Value
n = n + 1
End If
End I
Next
End Sub

http://cjoint.com/?bokHlEs7Xx





Avatar
Brunos
Ci-joint un exemple où la macro efface le marquage avant de le remettre.

Sub Bouton1_Clic()
Dim n As Integer, p As Integer
' effacement
For Each c In Range("toto")
p = InStr(1, CStr(c.Value), ")")
If p > 0 Then
c.Value = Right(c.Value, Len(c.Value) - p)
End If
Next
' marquage
n = 1
For Each c In Range("toto")
If Len(c.Value) > 2 Then
If UCase(Left(c.Value, 1)) = Left(c.Value, 1) Then
c.Value = n & ")" & c.Value
n = n + 1
End If
End If
Next
End Sub

http://cjoint.com/?bomqqgn01Z

Attention : comme le marquage se fait à partir de la recherche de ")", ça ne
marche pas s'il y a une ")" naturelle dans le texte.
Par exemple "blabla)dodo" devient "dodo"

Brunos

"Coriandre" a écrit dans le message de news:
%
Merci Brunos de ta rapide réponse.

Le code fonctionne très bien pour une seule exécution de la macro.
Si on reclique sur le bouton, cela rajoute les 1), 2), etc. à ceux déjà
existants :

1) 1) BLABLA
2) 2) BLOBLOBLO...

Or le contenu de la plage est susceptible de changer, une ligne passant au
dessus de l'autre et son contenu se modifiant, et je souhaiterais qu'à
chaque fois, le même processus se réactive.

Si :

1) BLABLA
bloblo
2) BLOUBLOU

devient :

bloblo
BLOUBLOU
CLAPCLAP

On doit toujours obtenir la première ligne de majuscules avec 1) devant,
la
seconde avec 2) devant, etc, c'est à dire :

bloblo
1) BLOUBLOU
2) CLAPCLAP

J'ai bien tenté de poser une condition avec "IsNumeric" pour enlever le 1)
déjà présent, sans succès, vu que je manipule très mal les fonctions left
et len...
D'autant qu'une ligne peut commencer par un chiffre mais non suivi de
parenthèse.
Elle ne doit alors pas être modifiée par une condition qui ôterait tout
chiffre en début de cellule ; ex. :

"2 équipes"
doit rester tel quel, tandis que :
"2) Equipe X"
doit pouvoir changer.


Merci de votre aide.

--
Coriandre

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


"Brunos" a écrit dans le message de
news:
Bonjour Coriandre,
Exemple de code:

sub procedure()
Dim n As Integer
n = 1
For Each c In Range("toto")
If Len(c.Value) > 2 Then
If UCase(Left(c.Value, 1)) = Left(c.Value, 1) Then
c.Value = n & ")" & c.Value
n = n + 1
End If
End I
Next
End Sub

http://cjoint.com/?bokHlEs7Xx





Avatar
Brunos
Petite correction (le code précedent considérait un chiffre comme une
majuscule).
http://cjoint.com/?bomEcYQLhY

Sub Bouton1_Clic()
Dim n As Integer, p As Integer
' effacement
For Each c In Range("toto")
p = InStr(1, CStr(c.Value), ")")
If p > 0 Then
c.Value = Right(c.Value, Len(c.Value) - p)
End If
Next
' marquage chr
n = 1
For Each c In Range("toto")
If Len(c.Value) > 2 Then
If Asc(c.Value) > 64 And Asc(c.Value) < 91 Then
c.Value = n & ")" & c.Value
n = n + 1
End If
End If
Next
End Sub

Brunos


"Coriandre" a écrit dans le message de news:
%
Merci Brunos de ta rapide réponse.

Le code fonctionne très bien pour une seule exécution de la macro.
Si on reclique sur le bouton, cela rajoute les 1), 2), etc. à ceux déjà
existants :

1) 1) BLABLA
2) 2) BLOBLOBLO...

Or le contenu de la plage est susceptible de changer, une ligne passant au
dessus de l'autre et son contenu se modifiant, et je souhaiterais qu'à
chaque fois, le même processus se réactive.

Si :

1) BLABLA
bloblo
2) BLOUBLOU

devient :

bloblo
BLOUBLOU
CLAPCLAP

On doit toujours obtenir la première ligne de majuscules avec 1) devant,
la
seconde avec 2) devant, etc, c'est à dire :

bloblo
1) BLOUBLOU
2) CLAPCLAP

J'ai bien tenté de poser une condition avec "IsNumeric" pour enlever le 1)
déjà présent, sans succès, vu que je manipule très mal les fonctions left
et len...
D'autant qu'une ligne peut commencer par un chiffre mais non suivi de
parenthèse.
Elle ne doit alors pas être modifiée par une condition qui ôterait tout
chiffre en début de cellule ; ex. :

"2 équipes"
doit rester tel quel, tandis que :
"2) Equipe X"
doit pouvoir changer.


Merci de votre aide.

--
Coriandre

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


"Brunos" a écrit dans le message de
news:
Bonjour Coriandre,
Exemple de code:

sub procedure()
Dim n As Integer
n = 1
For Each c In Range("toto")
If Len(c.Value) > 2 Then
If UCase(Left(c.Value, 1)) = Left(c.Value, 1) Then
c.Value = n & ")" & c.Value
n = n + 1
End If
End I
Next
End Sub

http://cjoint.com/?bokHlEs7Xx





Avatar
Coriandre
Voici le fichier modifié : http://cjoint.com/?bomzWlDxFn

A vrai dire, le contenu des lignes n'a pas d'importance, il peut être très
variable et libre.

Je vois que dans ton fichier, tu as eu l'idée de placer les numéros de
lignes dans une colonne à part, à gauche des lignes.
Pourquoi pas ?
Mais dans ton exemple, on écrit les données dans une plage, et on les lit
dans une autre.

Je précise que la plage qui contient les données à lire est aussi et doit
rester celle où on les introduit.

En gardant une seule plage d'écrit et de lecture, et en reprenant l'idée
d'une colonne supplémentaire à gauche pour le numérotage des lignes, cela
m'obligerait à modifier entièrement ma feuille (dont l'apparence compte
beaucoup), ce qui serait très compliqué et long.
Si on ne peut faire autrement, je m'y attelerai...

Grand merci en tous cas de ton aide.

--
Coriandre


"Brunos" a écrit dans le message de
news:
Effectivement, je n'avais pas bien perçu la complexité...
Le problème est que le marquage se fait dans la même cellule que le texte
marqué. Donc il faudrait effacer le prédédent marquage avant de remarquer.
C'est compliqué.
Pourrais-tu marquer le texte dans une colonne à côté ?
Je te donne un exemple qui marche sans macro :
http://cjoint.com/?bolLOtuZ0n
Brunos


Avatar
Coriandre
Après un rapide test, que je fouillerai plus tard, ça a l'air de fonctionner
à merveille.

Bravo et merci à Brunos !

--
Coriandre.


"Brunos" a écrit dans le message de
news:

http://cjoint.com/?bomEcYQLhY

Sub Bouton1_Clic()
Dim n As Integer, p As Integer
' effacement
For Each c In Range("toto")
p = InStr(1, CStr(c.Value), ")")
If p > 0 Then
c.Value = Right(c.Value, Len(c.Value) - p)
End If
Next
' marquage chr
n = 1
For Each c In Range("toto")
If Len(c.Value) > 2 Then
If Asc(c.Value) > 64 And Asc(c.Value) < 91 Then
c.Value = n & ")" & c.Value
n = n + 1
End If
End If
Next
End Sub

Brunos


Avatar
Coriandre
Bonjour,

Je reviens sur la macro proposée par Brunos hier.

Il s'agissait de numéroter les lignes dont le premier mot (de plus de 3
lettres) est écrit en majuscules, de haut en bas (de 1 à ...), en ajoutant
après le numéro de ligne une parenthèse, et de pouvoir recommencer à chaque
fois que contenu des lignes change.

La macro de Brunos fonctionne donc très bien, sauf quand une ligne contient
une phrase qui commence par un mot avec une majuscule de début : la ligne se
retrouve numérotée.
Or seuls les mots en majuscule de plus de 3 lettres doivent être pris en
compte dans le numérotage.
D'autre part, les parenthèses contenues dans le corps des phrases, ailleurs
que dans le numérotage, étaient prises en compte par la macro, et toute la
partie gauche de la phrase sautait avec.

J'ai donc adapté la macro ainsi :
-----------------------
Sub numeroter_lignes_majuscules()
Dim n As Integer, p As Integer
' effacement
For Each c In Range("blanc_non_ald")
p = InStr(1, CStr(c.Value), ")")
'la recherche de parenthèse ne se fait qu'au sein
'des 4 premiers caractères de la cellule :
If p > 2 And p < 4 Then
c.Value = Right(c.Value, Len(c.Value) - p - 1)
End If
Next
' marquage chr
n = 1
For Each c In Range("blanc_non_ald")
If Len(c.Value) > 2 Then
'on recherche les caractères qui sont des lettres
'ET qui sont en majuscule
'la condition se fait dans les deux premiers caractères
'de gauches de la ligne
'(pour éliminer les mots normaux de début de phrase
'commençant donc par une majuscule)
If Asc(c.Value) > 64 And Asc(c.Value) < 91 _
And Left(c.Value, 2) = UCase(Left(c.Value, 2)) Then
c.Value = n & ")" & c.Value
n = n + 1
End If
End If
Next
End Sub
-------------------------

Si Brunos ou quelqu'un d'autre a le temps, peut-on m'expliquer brièvement :

- à quoi sert le "CStr(c.Value)" au lieu d'un simple c.Value ?
- pourquoi UCase considère un chiffre comme une majuscule ?
- j'ai inversé dans la macros adaptée de brunos :
If UCase(Left(c.Value, 2)) = Left(c.Value, 2)
par :
If Left(c.Value, 2) = UCase(Left(c.Value, 2))
et ça a l'air de fonctionner pareil ;
Laquelle des deux conditions exprime dans le bon ordre de code :
"Si les deux premières lettres de la cellules sont en majuscule" ?

Merci de votre éclairage.

--
Coriandre


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

"Brunos" a écrit dans le message de
news:
Petite correction (le code précedent considérait un chiffre comme une
majuscule).
http://cjoint.com/?bomEcYQLhY

Sub Bouton1_Clic()
Dim n As Integer, p As Integer
' effacement
For Each c In Range("toto")
p = InStr(1, CStr(c.Value), ")")
If p > 0 Then
c.Value = Right(c.Value, Len(c.Value) - p)
End If
Next
' marquage chr
n = 1
For Each c In Range("toto")
If Len(c.Value) > 2 Then
If Asc(c.Value) > 64 And Asc(c.Value) < 91 Then
c.Value = n & ")" & c.Value
n = n + 1
End If
End If
Next
End Sub

Brunos


Avatar
Brunos
Bonjour,
- à quoi sert le "CStr(c.Value)" au lieu d'un simple c.Value ?
à éviter une erreur en cas de valeur numérique, mais je crois qu'on peut

l'enlever sans pb.

- pourquoi UCase considère un chiffre comme une majuscule ?
Ce n'est pas exactment ça. Ucase met toutes les lettres en majuscule.

Si tu compare UCase(x) avec x, c'est différent si x est une lettre.
Si x n'est pas une lettre, un chiffre ou un tiret par exemple, alors
UCase(x) = x.
Pour éviter cette confusion, j'avais utilisé Asc.
Asc(mot) renvoie le n° d'ordre du 1er caractère de mot dans la table ASCII.
Les majuscules A, B, C,..., Z ont un n° d'ordre compris entre 65 et 90.

- j'ai inversé dans la macros adaptée de brunos :
If UCase(Left(c.Value, 2)) = Left(c.Value, 2)
par :
If Left(c.Value, 2) = UCase(Left(c.Value, 2))
et ça a l'air de fonctionner pareil ;


oui c'est équivalent

Laquelle des deux conditions exprime dans le bon ordre de code :
"Si les deux premières lettres de la cellules sont en majuscule" ?
C'est bon, sauf que (voir plus haut) le mot A-bcd passe ton test.


"Coriandre" a écrit dans le message de news:
%
Bonjour,

Je reviens sur la macro proposée par Brunos hier.

Il s'agissait de numéroter les lignes dont le premier mot (de plus de 3
lettres) est écrit en majuscules, de haut en bas (de 1 à ...), en ajoutant
après le numéro de ligne une parenthèse, et de pouvoir recommencer à
chaque fois que contenu des lignes change.

La macro de Brunos fonctionne donc très bien, sauf quand une ligne
contient une phrase qui commence par un mot avec une majuscule de début :
la ligne se retrouve numérotée.
Or seuls les mots en majuscule de plus de 3 lettres doivent être pris en
compte dans le numérotage.
D'autre part, les parenthèses contenues dans le corps des phrases,
ailleurs que dans le numérotage, étaient prises en compte par la macro, et
toute la partie gauche de la phrase sautait avec.

J'ai donc adapté la macro ainsi :
-----------------------
Sub numeroter_lignes_majuscules()
Dim n As Integer, p As Integer
' effacement
For Each c In Range("blanc_non_ald")
p = InStr(1, CStr(c.Value), ")")
'la recherche de parenthèse ne se fait qu'au sein
'des 4 premiers caractères de la cellule :
If p > 2 And p < 4 Then
c.Value = Right(c.Value, Len(c.Value) - p - 1)
End If
Next
' marquage chr
n = 1
For Each c In Range("blanc_non_ald")
If Len(c.Value) > 2 Then
'on recherche les caractères qui sont des lettres
'ET qui sont en majuscule
'la condition se fait dans les deux premiers caractères
'de gauches de la ligne
'(pour éliminer les mots normaux de début de phrase
'commençant donc par une majuscule)
If Asc(c.Value) > 64 And Asc(c.Value) < 91 _
And Left(c.Value, 2) = UCase(Left(c.Value, 2)) Then
c.Value = n & ")" & c.Value
n = n + 1
End If
End If
Next
End Sub
-------------------------

Si Brunos ou quelqu'un d'autre a le temps, peut-on m'expliquer brièvement
:

- à quoi sert le "CStr(c.Value)" au lieu d'un simple c.Value ?
- pourquoi UCase considère un chiffre comme une majuscule ?
- j'ai inversé dans la macros adaptée de brunos :
If UCase(Left(c.Value, 2)) = Left(c.Value, 2)
par :
If Left(c.Value, 2) = UCase(Left(c.Value, 2))
et ça a l'air de fonctionner pareil ;
Laquelle des deux conditions exprime dans le bon ordre de code :
"Si les deux premières lettres de la cellules sont en majuscule" ?

Merci de votre éclairage.

--
Coriandre


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

"Brunos" a écrit dans le message de
news:
Petite correction (le code précedent considérait un chiffre comme une
majuscule).
http://cjoint.com/?bomEcYQLhY

Sub Bouton1_Clic()
Dim n As Integer, p As Integer
' effacement
For Each c In Range("toto")
p = InStr(1, CStr(c.Value), ")")
If p > 0 Then
c.Value = Right(c.Value, Len(c.Value) - p)
End If
Next
' marquage chr
n = 1
For Each c In Range("toto")
If Len(c.Value) > 2 Then
If Asc(c.Value) > 64 And Asc(c.Value) < 91 Then
c.Value = n & ")" & c.Value
n = n + 1
End If
End If
Next
End Sub

Brunos






Avatar
Coriandre
Merci brunos de tes explications qui m'aident à progresser.

--
Coriandre