Autres Saut de colonne et résultat formule dans autre cellule

GRI84

XLDnaute Nouveau
Bonjour,
Je ne trouve pas de solution dans le FORUM, aussi je poste ce sujet ''multiple", merci de votre aide ou de me renvoyer vers des sujets me donnant la réponse.

Sur le tableau joint (Excel2007 sur mon Pc mais je travaille pour mon bureau en Excel2016) j'ai déjà intégré macro, formule, et MEFC. Mais j'aimerai le faire évoluer de la manière suivante:

1/ lorsqu'une cellule est grisée (RVB 165, 165, 165), la tabulation la saute automatiquement quand la feuille est protégée.
J'ai trouvé une macro pour la colonne D (intégration automatique du GDH) je me demande si je peux l'adapter seulement avec une condition de couleurs?

2/ dans la colonne L, je voudrai que si la formule n'est pas vrai je puisse écrire un texte quelconque sans effacer la formule. Je pensai mettre la formule dans une colonne cachée et faire apparaître le résultat dans la colonne L, mais je ne trouve pas le bon élément.
Bien entendu cette feuille sera protégée donc l'option masquée verrouillée ne fonctionne pas.

Pour info le mot de passe et pw (utilisé dans la macro).

Merci de votre aide et merci à ce site.
 

Pièces jointes

  • MCC_V-ED.xlsm
    361.9 KB · Affichages: 15
Solution
VB:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Static SélectionPrécédente As Range
    Dim Cellule As Range
    Dim Sens As Integer
    Dim Repositionne As Boolean
    
    If SélectionPrécédente Is Nothing Then Set SélectionPrécédente = Target
    
    For Each Cellule In Target.Cells
        If Cellule.Column >= SélectionPrécédente.Column Then Sens = 1 Else Sens = -1
        
        If Cellule.Offset(0, 1 - Cellule.Column).Value = "ARRIVEE" Then
            Do While 1
                Select Case Cellule.Column
                    Case 5, 8, 9, 11
                        Set Cellule = Cellule.Offset(0, Sens)
                        Repositionne = True
                    Case Else
                        Exit Do...

Dudu2

XLDnaute Barbatruc
Bonjour,
Point 1/
Dans une situation "normale" pour "sauter" la cellule grisée, ceci serait suffisant:
VB:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Cells(1).Interior.Color = RGB(165, 165, 165) Then Target.Offset(0, 1).Select
End Sub
Mais la couleur de fond n'est pas celle de la cellule mais celle d'une MFC, et là, c'est possible mais il faut sortir l'artillerie lourde:
1 - pour savoir si une MFC s'applique à la cellule et en extraire le format de couleur de fond
2 - pour savoir si la condidition de la MFC est réalisée
Avec une MFC de Type 2 (formule) on peut certes évaluer la formule, mais si c'est un autre type qui n'a pas de formule(s) c'est plus compliqué.
Donc laisse tomber le test de la couleur de fond et reprend un test logique qui correspond aux conditions de réalisation de la MFC pour "sauter" la cellule:
Code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Cells.Count > 1 Then Exit Sub
    If Target.Column <> 5 And Target.Column <> 8 Then Exit Sub
    
    If Target.Offset(0, 1 - Target.Column).Value = "ARRIVEE" Then Target.Offset(0, 1).Select
End Sub

Point 2/
Je ne peux pas répondre car je ne comprends pas le problème énoncé.
je voudrai que si la formule n'est pas vrai je puisse écrire un texte quelconque
Il suffit de mettre ce texte quelconque en <valeur si faux> dans la formule avec un =SI(<condition>;<valeur si vrai>;<valeur si faux>)
 
Dernière édition:

GRI84

XLDnaute Nouveau
Bonjour Dudu2,
N'étant pas à mon domicile, je ferai les essais mercredi pour la 1er partie de ma question avec tes conseils. Merci.

Pour la seconde partie, je vais expliciter un peu mieux. le problème avec une formule positionnée dans la cellule où l'on attend un résultat =SI(OU(NB.SI($J7;"*EDB*");NB.SI($J7;"*RQZ*");NB.SI($J7;"*DDC*"));"OWNISTREP";""), on ne peut plus écrire sous peine de faire disparaitre la formule, mais ça vous le savez mieux que moi!
Or il faut que dans cette cellule, je puisse y écrire un commentaire quand la condition d'affichage automatique n'est pas appliquée, tout en conservant le bénéfice de la formule en cas de modifications qui ultérieures.
J'ai bien essayé de masquer la cellule, mais lorsque je verrouille la feuille cela n’empêche pas cette suppression même si la formule n'est plus visible, par ailleurs le fait de verrouiller mon fichier empêcherai d'écrire dans cette cellule.
Donc je me disais que peut être en écrivant la formule ci-dessus dans la feuille "Parametres" (que je masque lors de l'utilisation) on pourrai écrire celle-ci mais en faisant référence à la feuille "ARRIVEE - DEPART" "cellule Lx", ainsi la formule ne serait plus directement insérée dans la cellule et je pourrai y écrire un commentaire quelconque comme je l'ai fait en exemple dans mon fichier.

Merci pour ta réponse.
 

Dudu2

XLDnaute Barbatruc
D'une part tu ne peux pas avoir le beurre et l'argent du beurre, c'est à dire avoir une formule et une constante dans une cellule.
1593363224125.gif

D'autre part je ne vois pas ce que tu veux faire avec ta feuille "Paramètres" en espérant valoriser une cellule de la feuille "ARRIVEE - DEPART" avec une formule. Ça ne peut pas marcher.
1593363246763.gif


La seule option simple que tu as c'est de saisir ton commentaire quelque part dans une cellule du classeur (ex en K5 pour L5) et dans ta formule en colonne L y faire référence "quand la condition d'affichage automatique n'est pas appliquée". Ex pour L5: =SI(<condition>;<valeur si vrai>;K5)
Ou si le commentaire doit primer =SI(K5<>0;K5;<Formule>)

Une autre solution plus complexe pour avoir le beurre et les faveurs de la crémière
1593363445365.gif
(mais pas l'argent) est d'utiliser du VBA lorsque tu sélectionnes un cellule en colonne L avec une macro qui:
- Évalue la formule (paramétrée en anglais dans le code)
- Si elle donne un résultat nul proposer la saisie d'un commentaire et le placer comme constante dans la cellule
- Si elle donne un résultat non nul placer la formule dans la cellule

Tu n'as pas l'argent du beurre car dès lors qu'une constante est placée dans la cellule, tu n'as plus les avantages de la formules qui ne peut donc réagir aux conditions de sa réalisation.
 

Dudu2

XLDnaute Barbatruc
Ou un mix des 2 solutions, c'est à dire:
Lorsque tu sélectionnes la cellule en colonne L exécuter une macro qui:
- Évalue la formule (.Formula récupérée en anglais dans le code)
- Si elle donne un résultat nul proposer la saisie d'un commentaire et le placer sous forme de texte comme <valeur si faux> de la formule,
- Si elle donne un résultat non nul ne rien modifier dans la cellule.
Comme ça tu as le beurre, l'argent du beurre et les faveurs de la crémière
1593364333901.gif
.

Edit cette solution étant applicable dans les 2 options:
- "quand la condition d'affichage automatique n'est pas appliquée":
=SI(<condition>;<valeur si vrai>;"Texte saisi dans la macro")
- Ou si le commentaire doit primer:
=SI("Texte saisi dans la macro"<>0;"Texte saisi dans la macro";<Formule>)
 
Dernière édition:

GRI84

XLDnaute Nouveau
Bonsoir Dudu2,
J'ai abandonné l'option du point 2 qui était trop usine à gaz et qui à l'asge n'apportait pas une plus-valu importante. Merci quand même.

Par contre sur le point 1 j’essaie d'intégrer la même solution de saut de case grisée mais pour la valeur "DEPART" en A1 qui sauterait la cellule de la colonne G. J'ai recopié en corrigeant le 5 par 7 et en supprimant la cellule 8, mais j'ai une erreur de Worksheet......J'ai essayé d’insérer un Else If un Dim en début et autres alternatives mais Nada.
Aurais-tu une solution?
Merci encore pour ton aide précieuse.
 

Dudu2

XLDnaute Barbatruc
Bonjour GRI84,
Une version un peu plus élaborée...
VB:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Static SélectionPrécédente As Range
    Dim Cellule As Range
    Dim Sens As Integer
    Dim Repositionne As Boolean
    
    If SélectionPrécédente Is Nothing Then Set SélectionPrécédente = Target
    
    For Each Cellule In Target.Cells
        If Cellule.Column >= SélectionPrécédente.Column Then Sens = 1 Else Sens = -1
        
        If Cellule.Offset(0, 1 - Cellule.Column).Value = "ARRIVEE" Then
            If Cellule.Column = 5 Or Cellule.Column = 8 Then
                Set Target = Cellule.Offset(0, Sens)
                Repositionne = True
            End If
        ElseIf Cellule.Offset(0, 1 - Cellule.Column).Value = "DEPART" Then
            If Cellule.Column = 8 Then
                Set Target = Cellule.Offset(0, Sens)
                Repositionne = True
            End If
        End If
        
        If Repositionne Then
            Application.EnableEvents = False
            Target.Select
            Application.EnableEvents = True
            Exit For
        End If
    Next Cellule
    
    Set SélectionPrécédente = Target
End Sub
 
Dernière édition:

GRI84

XLDnaute Nouveau
Merci,
C'est presque bon, mais il faudrait sauter les colonnes 5, 8, 9 et 11 pour le mot "ARRIVEE"
Pour le mot DEPART tout est bon (saut des colonnes 7, 9 et 11.
J'ai essayé de rajouter "Or Cellule.Column = 9" après la même ligne en 8,mais cela ne fonctionne pas.
Merci Dudu
 

Dudu2

XLDnaute Barbatruc
VB:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Static SélectionPrécédente As Range
    Dim Cellule As Range
    Dim Sens As Integer
    Dim Repositionne As Boolean
    
    If SélectionPrécédente Is Nothing Then Set SélectionPrécédente = Target
    
    For Each Cellule In Target.Cells
        If Cellule.Column >= SélectionPrécédente.Column Then Sens = 1 Else Sens = -1
        
        If Cellule.Offset(0, 1 - Cellule.Column).Value = "ARRIVEE" Then
            Do While 1
                Select Case Cellule.Column
                    Case 5, 8, 9, 11
                        Set Cellule = Cellule.Offset(0, Sens)
                        Repositionne = True
                    Case Else
                        Exit Do
                End Select
            Loop
            
        ElseIf Cellule.Offset(0, 1 - Cellule.Column).Value = "DEPART" Then
            Do While 1
                Select Case Cellule.Column
                    Case 7, 9, 11
                        Set Cellule = Cellule.Offset(0, Sens)
                        Repositionne = True
                    Case Else
                        Exit Do
                End Select
            Loop
        End If
        
        If Repositionne Then
            Set Target = Cellule
            Application.EnableEvents = False
            Target.Select
            Application.EnableEvents = True
            Exit For
        End If
    Next Cellule
    
    Set SélectionPrécédente = Target
End Sub
 

GRI84

XLDnaute Nouveau
Bonjour Dudu2,
J'ai pu voir ta macro qui fonctionne à merveille, félicitation pour avoir mis en musique mon idée.
Je vais maintenant regarder de plus prés les formules pour bien comprendre le résonnement.
Encore Merci pour ton aide.
 

Dudu2

XLDnaute Barbatruc
No problem !
Dans ce cas tu as 2 ou 3 petites choses à savoir.

1 - Une variable Static garde sa valeur en permanence contrairement aux autres variables (dynamiques) dont la mémoire est en principe allouée et initialisée à l'entrée de la fonction.
Ici elle sert à garder la position de la sélection précédente pour savoir si la nouvelle sélection indique un mouvement de gauche à droite ou de droite à gauche du curseur. Je n'ai pas différencié une sélection par curseur d'une sélection par souris pour rester simple, mais c'est possible.
Une variable module aurait tout aussi bien pu faire l'affaire. Mais là tout est localisé dans la fonction.

2 - L'argument Target de la fonction Worksheet_SelectionChange() est un Range (une plage) qui peut représenter une simple cellule, un groupe de cellules ou plusieurs groupes de cellules selon ce que tu as sélectionné. C'est pour ça qu'elles sont toutes examinées dans la boucle For Each Cellule In Target.Cells.
Dans ce code, il suffit que l'une des cellules sélectionnées fasse partie des colonnes à sauter pour que le saut soit effectué.

3 - Si le Target.select est précédé de Application.EnableEvents = False, c'est pour empêcher que cette sélection faite en VBA ne déclenche à nouveau l'évènement Worksheet_SelectionChange() (exactement comme une sélection manuelle de cellule(s)) ce qui provoquerait l'appel (récursif) de cette même fonction, perturbant ainsi le traitement. Ce n'est pas obligatoire de le faire, mais il faut être conscient des conséquences éventuelles (ex. empilement infini d'appels récursifs qui se termine par un plantage) si on provoque toujours l'évènement dans le code.
 
Dernière édition:

Discussions similaires

Réponses
2
Affichages
102
Réponses
10
Affichages
319

Statistiques des forums

Discussions
311 720
Messages
2 081 899
Membres
101 834
dernier inscrit
Jeremy06510