Macro : sélection ligne sous contrainte

Bonjour à tous,

j'aimerais savoir s'il était possible de faire une macro pour sélectionner une/des lignes régulièrement.

Les inputs du code seraient :

  • nombre de lignes à sélectionner
  • écart entre chaque sélection
  • ligne de la première selection

En rentrant 1 ligne à selectionner, écart de 1 ligne dès la première ligne, excel sélectionnerait donc les lignes 1; 3; 5; 7 etc....

Je ne suis pas assez calé en code pour écrire ceci, vous seriez d'une grande aide si quelqu'un pouvait proposer une solution.

Merci d'avance et bonne journée,

Maverick'

Bonjour,

Professant autant que je le peux que lorsqu'on agit sur Excel en utilisant VBA, on n'a jamais besoin de sélectionner (il suffit simpllement d'appeler les choses par leur nom, si je puis dire ! ), que la sélection est une opération superflue et parasite, qui prend inutilement du temps et n'a pour effet que de ralentir l'exécution...

On a donc mieux à faire en matière de code que faire traîner les pieds à VBA !

Je te propose donc de faire ce que tu souhaites avec tes lignes ou dans tes lignes, sans jamais les sélectionner...

Cordialement.

Merci pour la réponse.

En fait, je ne souhaite pas sélectionner par plaisir ces lignes mais pour les supprimer.

Je reçois effectivement des fichiers compliqués à traiter puisqu'ils comporte des lignes sans intérêts.

L'espacement entre les lignes est le même au sein d'un fichier mais différent d'un fichier à l'autre.

J'aimerais donc pouvoir sélectionner ces lignes afin de les supprimer en entrant les inputs expliquées dans mon premier message

Bien cordialement,

Mav'

Mais, je me répète décidément ! Il n'y a pas lieu de sélectionner puisque l'objectif est de supprimer !

Objectif = Supprimer => Action = Supprimer (<> Sélectionner)

Bonjour,

Le commentaire de @MFerrand est toujours valide. Pas besoin de sélectionner pour supprimer...

EDIT : et d'ailleurs il le dit lui-même !

Par contre tes critères de définition paraissent curieux : que les lignes à supprimer soient également espacées, à partir d'une ligne prédéfinie aurait mérité un modèle pour visualiser au mieux et éviter des erreurs d'interprétation...

Et nombre de lignes à supprimer : on ne sait s'il s'agit du nombre total, du nombre de lignes consécutives de chaque bloc à supprimer, et du coup l'espacement entre les blocs devient imprécis (écart entre la première ligne de chaque bloc ou écart entre la dernière ligne d'un bloc et la première du bloc suivant...)

La précision doit être mathématique (ou chirurgicale puisqu'il s'agit d'une ablation ! )

Salut Pedro !

Bonjour MAVERICK39

En fait, je ne souhaite pas sélectionner par plaisir ces lignes mais pour les supprimer.

Je reçois effectivement des fichiers compliqués à traiter puisqu'ils comporte des lignes sans intérêts.

L'espacement entre les lignes est le même au sein d'un fichier mais différent d'un fichier à l'autre.

J'aimerais donc pouvoir sélectionner ces lignes afin de les supprimer en entrant les inputs expliquées dans mon premier message

Voila une macro qui devrait convenir:

Ben, mon cama, tu parles d'une bombe atomique!

On écrase un moustique, là...

A+

Curulis Je suis bien d'accord !

Bonjour à tous,

allez, comme il n'y a pas grand chose à se mettre sous la dent

Et puis on ne sait pas. C'est peut-être du répétitif et sur de longs fichiers (?)

Tu n'auras même pas de saisies à faire.

Tu sélectionnes à la souris les 2 premiers blocs à supprimer et tu lances la macro :

Sub suppLig()
    Dim lig As Long, sel As Long, pas As Long, pl As Range
    With Selection
        If .Areas.Count <> 2 Then Exit Sub
        If .Areas(1).Rows.Count <> .Areas(2).Rows.Count Then Exit Sub
        lig = .Areas(1).Row
        sel = .Areas(1).Rows.Count
        pas = .Areas(2).Row - .Areas(1).Row
        Set pl = .Areas(1).EntireRow
    End With
    For lig = lig + pas To Cells.Find("*", , , , xlByRows, xlPrevious).Row Step pas
        Set pl = Union(pl, Rows(lig).Resize(sel).EntireRow)
    Next lig
    pl.Select
    If MsgBox("Confirmez-vous la suppression de ces lignes ?", vbYesNo + vbDefaultButton2) = vbYes Then pl.Delete
End Sub

J'ai mis quelques sécurités quand même, d'où le .Select justifié ici.

Sinon c'est non comme disent les camarades Tu vois qu'on aurait pu faire pl.Delete directement

Salut Maverick,

Eriiic

Géniale, UNION !

Pour tout avouer, j'étais parti sur le même type de boucle mais avec l'idée HIDDEN=True , DELETE, HIDDEN=False sur les lignes concernées quand j'ai vu ta réponse. Brillant... et j'utilise UNION tous les jours!

Bref, je phagocyte l'idée de tes neurones et l'adapte à ma boucle, en te remerciant beaucoup.

@Maverick

  • démarrage de la macro d'un double-clic sur [A1] ;
  • une InputBox te demande les références des blocs à éliminer START/STEP/ROWS/END

Chaque référence doit être séparée du caractère "/" sans espace.

Attention! Pas de sécurité installée! Travaille comme un pro!

* START : première ligne à traiter ;

* STEP : le pas entre les blocs ;

* ROWS : nombre de lignes à éliminer ;

* END : l'ensemble du fichier = 0 sinon tu tapes le n° de la première ligne à CONSERVER pour, éventuellement, garder le reste du fichier intact.

Ex: 2/5/3/0

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
'
Dim tSplit, rCells As Range
Cancel = True
Application.ScreenUpdating = False
'
If Not Intersect(Target, Range("A1")) Is Nothing Then
    sRep = Application.InputBox("Veuillez encoder : START/STEP/ROWS/END", "Suppression de lignes")
    If Len(sRep) > 6 Then
        tSplit = Split(sRep, "/")
        iStart = CInt(tSplit(0))
        iStep = CInt(tSplit(1))
        iRows = CInt(tSplit(2))
        lEnd = IIf(tSplit(3) = "0", UsedRange.Rows.Count, CLng(tSplit(3)) - 1)
        Set rCells = Rows(UsedRange.Rows.Count + 1)
        For x = iStart To lEnd Step iStep
            Set rCells = Union(rCells, Rows(x).Resize(IIf(lEnd = UsedRange.Rows.Count, iRows, IIf(x + iRows - 1 < lEnd, iRows, lEnd - x+1)), 1).EntireRow)
        Next
    End If
    rCells.Delete
End If
'
Application.ScreenUpdating = True
'
End Sub

A+

Ben, oui, condenser, j'aime ça...

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
'
Dim rCells As Range
Cancel = True
'
sRep = Application.InputBox("Veuillez encoder : START/STEP/ROWS/END", "Suppression de lignes")
If Len(sRep) < 7 Then Exit Sub
iRows = CInt(Split(sRep, "/")(2))
lEnd = IIf(Split(sRep, "/")(3) = "0", UsedRange.Rows.Count, CLng(Split(sRep, "/")(3)) - 1)
'
Set rCells = Rows(UsedRange.Rows.Count + 1).EntireRow
For x = CInt(Split(sRep, "/")(0)) To lEnd Step CInt(Split(sRep, "/")(1))
    Set rCells = Union(rCells, Rows(x).Resize(IIf(lEnd = UsedRange.Rows.Count, iRows, IIf(x + iRows - 1 < lEnd, iRows, lEnd - x + 1)), 1).EntireRow)
Next
rCells.Delete
'
End Sub

Bonjour,

phagocyte curulis, pas de soucis

Reste à voir s'il préfère la version avec ou sans saisie.

eric

Salut Maverick, Eriiic,

Pas de MP si cela ne se justifie pas, stp, Maverick!

Il s'agit de procédures événementielles, c-à-d, qui réagissent à un événement et non des procédures standard.

Le code se trouve, dans ce cas-ci, dans le module VBA de la feuille concernée par le traitement.

Dans le fichier joint, j'ai nommé la feuille 'BDD' : regarde dans ce module!

J'y ai mis les deux procédures : la "longue" (double-clic) et la "condensée" (clic droit).

A+

Bonjour,

as-tu regardé ma proposition au moins ?

eric

Bonjour,

j'ai amélioré...

Même plus besoin d'appeler la macro.

Si deux plages de même hauteur sont sélectionnées (Ctrl+cliqué glissé pour la 2nde), il est proposé la suppression des lignes suivant ce motif.

eric

8classeur2.xlsm (17.00 Ko)

Bravo pour ce challenge haletant !

Le demandeur n'halète pas trop lui...

Ou alors il est à bout de souffle et ne peux plus parler

Bé ! Faut suivre !

Dans bien des cas, lorsqu'il y a abondance sur un sujet, je n'ai jamais vraiment compris les critères de choix des demandeurs (pas toujours, certains donnent des raisons qui peuvent être discutables mais claires, mais pour d'autres, les raisons restent inconnues).

Eriic,

merci c'est encore mieux effectivement, j'adore vraiment le principe de selectionner les premières lignes désirées, puis les suivantes.

On a l'apercu de ce qu'il peut être supprimé et la confirmation.

C'est vraiment parfait !

merci infiniment Eriiic et désolé pour les réponses tardives, je n'ai pas accès le soir à ma connexion.

Bonne journée,

Maverick'

Salut Maverick,

Bien le bonjour MFerrand,

Respect Eriiic,

grâce à toi, j'ai bien appris sur ce coup-là et c'est bien là l'essentiel!

Inspiré par ton code, je l'ai encore amélioré dans l'esprit du mien, à savoir définir une éventuelle partie de fichier à conserver.

@Maverick,

c'est la même idée qu'Eriiic :

  • si tu veux traiter l'ensemble du fichier, tu sélectionnes comme Eriiic l'a prévu ;
  • si tu veux conserver une partie du fichier, ta première sélection DOIT être la première ligne à CONSERVER (ligne unique), les deux autres sélections étant celles définissant les blocs à éliminer.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'
With Selection
    iOK = 0
    Select Case .Areas.Count
        Case 2
            If .Areas(1).Rows.Count = .Areas(2).Rows.Count Then iOK = 1
        Case 3
            If .Areas(2).Rows.Count = .Areas(3).Rows.Count Then iOK = 2
    End Select
    If iOK > 0 Then
        iStart = .Areas(iOK).Row
        iStep = .Areas(iOK + 1).Row - .Areas(iOK).Row
        iRows = .Areas(iOK).Rows.Count
        lEnd = IIf(iOK = 1, UsedRange.Rows.Count, .Areas(1).Row - 1)
        Set rCells = Rows(UsedRange.Rows.Count + 1).EntireRow
        For x = iStart To lEnd Step iStep
            Set rCells = Union(rCells, Rows(x).Resize(IIf(lEnd = UsedRange.Rows.Count, iRows, IIf(x + iRows - 1 < lEnd, iRows, lEnd - x + 1)), 1)).EntireRow
        Next
        rCells.Select
        If MsgBox("Confirmez-vous la suppression de ces lignes ?", vbYesNo + vbDefaultButton2) = vbYes Then rCells.Delete
        [A1].Select
    End If
End With
'
End Sub

A+

Rechercher des sujets similaires à "macro selection ligne contrainte"