Fusionner plusieurs codes orientés MFC en VBA

Bonjour à tous.

Il y a quelques années votre forum m'a permis de finaliser un fichier dont le code initial m'avait été proposé sur un autre forum. Je ne cherche pas à lancer une polémique sur qui est meilleur, car je peux comprendre que d'établir du code pour autrui n'est pas toujours motivant et que les connaisseurs "décrochent" parfois d'un fil de discussion avant qu'un néophyte (moi ^^) n'obtienne ce qu'il souhaitait exactement ...

Bref, je suis confronté au même problème aujourd'hui : je n'y connais pas grand chose en VBA, j'ai des bouts de codes qui fonctionnent, d'autres non, et je cherche une âme charitable et compétente pour me fusionner tout ça, pour "finir le travail".

Avant-propos.

Je veux retranscrire des MFC basiques en VBA. (beaucoup me conseillent d'éviter, mais j'en ai marre des règles de MFC qui se démultiplient à chaque copier / coller / coupage de ligne / changement d'onglet .. bref je veux un truc " en dur ")

État actuel.

J'utilise ce code, très utile

Private Sub Worksheet_Change(ByVal Target As Range)
Dim TY As Range
 If Not Intersect([_TYPES_TABLEAU], Target) Is Nothing Then
   On Error Resume Next

  Set TY = [_TYPES].Find(Target, LookAt:=xlWhole)
       With Target.Offset(0, 0).Resize(1, 1)
        .Interior.ColorIndex = TY.Interior.ColorIndex
        .Font.Bold = TY.Font.Bold
        .Font.Italic = TY.Font.Italic
        .Font.Color = TY.Font.Color
   End With
  End If
  End Sub

On vient de m'indiquer ces autres pans de code :

Private Sub Worksheet_Change(ByVal Target As Excel.Range)
If Target.Cells.Count > 1 Or IsEmpty(Target) Then Exit Sub

  If Not Intersect(Target, Range("E4:E23")) Is Nothing Then
    With Target
      Select Case Target.Value
        Case Is < 0.5
          .Interior.ColorIndex = 3
        Case 0.5 To 0.79
          .Interior.ColorIndex = 44
        Case 0.8 To 0.99
          .Interior.ColorIndex = 6
      End Select
    End With
  End If
End Sub
Private Sub Workbook_Open()

End Sub
Sub tri()
Application.ScreenUpdating = False
Call reclasse
fin = Range("C" & Rows.Count).End(xlUp).Row
For n = fin To 2 Step -1
  If Range("C" & n).Font.ColorIndex = 2 Then
  debut = n + 1
   ActiveSheet.Sort.SortFields.Clear
   ActiveSheet.Sort.SortFields.Add Key:=Range("C" & debut & ":C" & fin) _
        , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    With ActiveSheet.Sort
        .SetRange Range("A" & debut & ":DK" & fin)
        .Header = xlGuess
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    fin = n - 3
  End If
Next
Application.ScreenUpdating = True
End Sub
Sub reclasse()
For n = 3 To Range("D" & Rows.Count).End(xlUp).Row
  If Range("D" & n) <> "" Then
    If Range("D" & n).Font.ColorIndex = 2 Then
      etape = Left(Range("D" & n), 1)
    Else
      If Left(Range("D" & n), 1) <> etape Then
        oucopier = ligne(Left(Range("D" & n), 1))
        Rows(n).Copy Destination:=Rows(oucopier)
        Rows(oucopier + 1).Insert
        Rows(oucopier + 1).Interior.ColorIndex = xlNone
        If oucopier < n Then
          asupp = n + 1
        Else
          asupp = n
        End If
        Rows(asupp).Delete
      End If
    End If
  End If
Next
End Sub
Function ligne(etape)
For n = 3 To Range("D" & Rows.Count).End(xlUp).Row
If Range("D" & n) <> "" Then
    If Range("D" & n).Font.ColorIndex = 2 And Left(Range("D" & n), 1) = etape Then
      For m = n To 100
        If Range("D" & m) = "" Then
          ligne = m
          Exit For
        End If
      Next
    End If
 End If
Next
End Function 
Option Explicit
' DoubleZero
Private Sub Worksheet_Change(ByVal c As Range)
    Set plage = Range("g2:q999")
    If Not Intersect([plage], c) Is Nothing And c.Count = 1 Then Call MFC_selon_valeur
    [plage].Columns.AutoFit
End Sub

'' ORIGINAL
'Private Sub Worksheet_Change(ByVal Target As Range)
'
'Dim TY As Range
' If Not Intersect([_TYPES_TABLEAU], Target) Is Nothing Then
'   On Error Resume Next
'
'  Set TY = [_TYPES].Find(Target, LookAt:=xlWhole)
'       With Target.Offset(0, 0).Resize(1, 1)
'        .Interior.ColorIndex = TY.Interior.ColorIndex
'        .Font.Bold = TY.Font.Bold
'        .Font.Italic = TY.Font.Italic
'        .Font.Color = TY.Font.Color
'   End With
'  End If
'End Sub

On remarque que le code d'origine est désactivé ...

Option Explicit
Public plage As Range
Sub MFC_selon_valeur()
    Dim c As Range
    With Application: .ScreenUpdating = False: .Calculation = xlManual: .EnableEvents = False: End With
    [c2:s999].Font.Size = 11
    For Each c In Range("g:q").SpecialCells(xlCellTypeConstants, 23)
        c.Font.ColorIndex = 1
        If c.Value Like "*OK*" Then c.Font.ColorIndex = 10
        If c.Value Like "*attente*" Then c.Font.ColorIndex = 46: c.Font.Bold = True
        If c.Value Like "*prévoir*" Then c.Font.ColorIndex = 3: c.Font.Bold = True
        If c.Value Like "*problème*" Then c.Font.ColorIndex = 3: c.Font.Bold = True: c.Font.Size = 13
    Next
    With Application: .EnableEvents = True: .Calculation = xlAutomatic: .ScreenUpdating = True: End With
End Sub
Sub MFC_manuelle_une_ligne_sur_deux()
    Set plage = [c2:s999]
    With plage: .FormatConditions.Delete: .FormatConditions.Add Type:=xlExpression, Formula1:="=MOD(LIGNE(); 2 )": .FormatConditions(1).Interior.Color = 14089948: End With
End Sub 

Ce que j'aimerai, si possible

- qu'un expert me confirme que le code n'est pas exagérément complexe

(j'avias déjà posé en 2015 une question sur de la MFC en VBA, et le code me paraissait beaucoup moins obscure : https://forum.excel-pratique.com/excel/convertir-des-formules-de-mfc-en-vba-t68330.html )

- que quelqu'un est l'amabilité de faire en sorte que toutes ces fonctions cohabitent dans un même classeur

- le surlignage 1 ligne sur 2 ne fonctionne pas, au pire je peux m'en passer (si j'ai une seule règle de MFC à gérer ça va)

- l'idéal serait de regrouper les pans de codes puis de les re-dispatcher en 3 feuilles de code :

1 = ancien code qui va lire le contenu et la mise en forme des données TYPES pour les retranscrire dans TYPES_Tableau

2 = nouveau code permettant d'appliquer des règles de MFC (et moi qui n'y connait pas grand chose, je ne bidouillerai qu'au niveau des If c.Value Like "*OK*" Then c.Font.ColorIndex = 10 ...)

3 = code pour surlignage 1 ligne sur 2 qui n'a aucun rapport avec les autres codes, et que je n'utilise que dans un seul classeur (alors que les autres codes me seraient très utiles, pour plusieurs années et des dizaines de classeurs ...)

Merci d'avoir lu jusqu'au bout.

Et merci de prendre la peine de vous impliquer !

Bonsoir,

Je vous avoue ne pas être un expert...

Mais ceci dit il y a des choses qui me chiffonnes !!!

Dans votre fichier il y a un code qui est lancé lors du changement d'une valeur sur la feuille :

Private Sub Worksheet_Change(ByVal c As Range)
    Set plage = Range("g2:q999")
    If Not Intersect([plage], c) Is Nothing And c.Count = 1 Then Call MFC_selon_valeur
    [plage].Columns.AutoFit
End Sub

Ce code appel MFC_selon_Valeur si les conditions sont réunies.

Cette Sub est la suivante :

Sub MFC_selon_valeur()
    Dim c As Range
    With Application: .ScreenUpdating = False: .Calculation = xlManual: .EnableEvents = False: End With
    [c2:s999].Font.Size = 11
    For Each c In Range("g:q").SpecialCells(xlCellTypeConstants, 23)
        c.Font.ColorIndex = 1
        If c.Value Like "*OK*" Then c.Font.ColorIndex = 10
        If c.Value Like "*attente*" Then c.Font.ColorIndex = 46: c.Font.Bold = True
        If c.Value Like "*prévoir*" Then c.Font.ColorIndex = 3: c.Font.Bold = True
        If c.Value Like "*problème*" Then c.Font.ColorIndex = 3: c.Font.Bold = True: c.Font.Size = 13
    Next
    With Application: .EnableEvents = True: .Calculation = xlAutomatic: .ScreenUpdating = True: End With
End Sub

Ce qui me chiffonne : une cellule est modifiée et tout le tableau ou une bonne partie est scruté !

Hors lorsque qu'une cellule est modifiée elle est représentée par :

Private Sub Worksheet_Change(ByVal Target As Range)

donc, on pourrait simplifié ceci par :

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, [plage]) Is Nothing And Target.Count = 1 Then
        With Application: .ScreenUpdating = False: .Calculation = xlManual: .EnableEvents = False: End With
            If Target.Value Like "*OK*" Then Target.Font.ColorIndex = 10
            If Target.Value Like "*attente*" Then Target.Font.ColorIndex = 46: c.Font.Bold = True
            If Target.Value Like "*prévoir*" Then Target.Font.ColorIndex = 3: c.Font.Bold = True
            If Target.Value Like "*problème*" Then Target.Font.ColorIndex = 3: c.Font.Bold = True: c.Font.Size = 13
        Next
        [plage].Columns.AutoFit
        With Application: .EnableEvents = True: .Calculation = xlAutomatic: .ScreenUpdating = True: End With
    End If
End Sub

En fait vous appliquez la mise en forme uniquement à la cellule modifiée.

Après j'avoue ne pas avoir tout compris...

Une dernière chose : vous parlez de mettre une ligne sur deux en couleur verte. Ma question :

votre tableau est bien un tableau ? Alors pourquoi ne pas remplacer la plage de cellule par un tableau Excel grâce au menu "insertion" du ruban, puis tableau, ensuite dans format tableau vous pouvez créer votre propre format.

L'avantage est que lors d'un filtre les lignes colorées sont toujours affichées une sur deux, ce qui n'est pas le cas avec la MFC par formule.

@ bientôt

LouReeD

Nota : mon application APACHES contient des codes VBA de "création de MFC par VBA" afin de contourner les problèmes de démultiplication de celles-ci par Excel, j'ai réussis à intégrer la gestion des textures et autre !

Bonsoir, salut LouReed !

Je ne vais pas décortiquer comme l'a fait LouReed... D'ailleurs quand j'ai vu la longueur de ton post je me suis contenté de début et vaguement la fin !

Je ne vois pas trop la raison de ton préambule... On n'aime pas en général la mise en concurrence, les situations claires dans un climat collaboratif sont toujours préférables... Pour ma part, je cesse de produire s'il y a un doute à ce sujet. J'espère donc que tes propos ne masquent pas d'élément non dit...

Le problème des fractionnements de MFC dans le cadre de certaines utilisations est un vrai problème, et on peut effectivement y pallier par une procédure de reconstruction des MFC.

Par exemple, à l'ouverture du classeur, on supprime les MFC et on les reconstruit...

J'ai donc jeté un oeil sur ton classeur, qui ne contient aucune MFC ! Tu fais état de 5 MFC distinctes. L'étendue des lignes 2 à 999 me gêne un peu, je préfèrerais un ajustement plus précis à la zone occupée (au moins pour 4 d'entre elles).

En tout cas, il serait mieux que ton modèle soit conforme au classeur dans lequel définir les MFC concernées...

Il vaut toujours mieux ne pas travailler dans le vide.

C'est assez simple à faire, d'autant que les formules conditionnelles se codent en mode "local" (telles qu'on les saisit manuellement), mais cela reste un type de procédure toujours un peu fastidieux à écrire (à mon sens).

Sans avoir lu toutes les procédures que tu cites, au survol je n'ai détecté qu'une seul invocation d'un objet FormatCondition...

Il serait bon que tu fournisses un classeur mieux adapté à ton propos, qui permette d'évaluer la meilleure méthode pour garantir la permanence des MFC.

Cordialement.

Bonjour.

Merci à tous les deux pour vos premières réponses.

Je ne vois pas trop la raison de ton préambule...

Expliquer pourquoi j’ai des pans de code que je ne maitrise pas (= ils viennent d’autres personnes)

Par souci d’honnêteté (= ces personnes sont des membres d’autres forums)

J'espère donc que tes propos ne masquent pas d'élément non-dit...

Tu donnes toi-même un élément de réponse :

« quand j'ai vu la longueur de ton post je me suis contenté de début et vaguement la fin ! »

Exactement, rien qu’à lire mon message « trop long », tu n’es pas motivé à 100%. Ce n’est pas un reproche, c’est une sorte de constante sur les forums pointus (maths, excel, …). On n’est pas sur les réseaux sociaux, les forums de jeunes mamans ou de recettes de cuisine où les réponses (plus ou moins valables d’ailleurs) pullulent. De par les connaissances nécessaires pour me répondre, cela limite les internautes capables de le faire. Et comme je ne suis pas tout seul (y a chaque jour plus de 50 sujets liés au VBA sur les forums Excel francophones) …… c’est récurrent de ne pas avoir de réponse. Mais c’est normal, comme cette « passion » n’est pas vraiment récompensée, il est humain que toi, ou toute autre membre, laisse des sujets « en souffrance ». Bref, il n’y a pas de non-dit, c’est juste que si je n’ai pas de réponse, je cherche ailleurs.

On n'aime pas en général la mise en concurrence

Le fait est que sur d’autres bouts de code, c’est ici qu’on me les avait complétés / finalisés.

Mais je ne vous sollicite pas pour un « concours de kiki » inter-forums-francophones … y a juste que :

  • La journée j’ai un boulot à la con
  • Le soir, pour les loisirs, mais j’ai un bébé à gérer
Dans les 2 créneaux j’utilise Excel, et même si je me débrouille plutôt bien en info, je n’y connais pas grand-chose en programmation. Donc tout ce qui peut me faciliter la vie et me faire gagner du temps est « tout bénéf’ ». Et égoïstement, si je n’ai pas de réponse (Cf. paragraphe au-dessus, ou tout simplement le lien que j'ai mis sur mon fil de discussion d'il y a 2 ans qui n'avait pas abouti sur un problème similaire) j’augmente mes chances d’en avoir en postant ailleurs (plutôt que de mettre ces insupportables UP UP UP pour remonter mes fils de discussion).

pourquoi ne pas remplacer la plage de cellules par un tableau Excel

Je n’y avais pas pensé (ou du moins je croyais que la mise en forme prédéfinie prenait l’ascendant sur toute ma MF classique (du genre des lignes + épaisses) mais en fait non, ça fonctionne. Bonne idée ! Merci …

Après j'avoue ne pas avoir tout compris…

J’aimerai profiter de 3 choses.

La n°3, on va dire qu’elle est réglée (soit grâce au tableau, soit au pire je peux rentrer 1 règle de MFC)

La n°1 c’est la possibilité d’avoir un choix de liste déroulante, qui conserve la MF des champs que j’ai renseigné dans un autre onglet (que j’appelle XL). On m’avait écrit un code qui fonctionne, et je l’utilise depuis environ 2 ans. Sans parler des lacunes ou problèmes à l’intérieur même des codes ; j’ai comme souci que la personne qui a rédigé le code pour le n°2 a désactivé le n°1, alors que j’ai besoin des deux en même temps dans le même classeur.

La n°2 c’est un moyen de palier à l’absence de possibilité de figer les règles de MFC.

(et accessoirement le VBA permet de changer la taille de la police)

La finalité de ma demande serait d’avoir les 3 choses dans 3 feuilles de codes

(on va dire les 2 codes dans 2 feuilles distinctes si on enlève mon « n°3 »)

Pourquoi ? pour pouvoir les réutiliser dans (beaucoup) d’autres classeurs, et à mon niveau, un copier/coller est plus accessible que de dupliquer des fonctions qui en appellent d’autres étalées sur plusieurs feuilles. Enfin ça c’est si c’est de l’ordre du possible. Au pire si j’ai n°1 n°2 n°3 qui fonctionnent ensemble grâce à 6 feuilles de code, je me débrouillerai (mais c’est moins lisible pour un néophyte comme moi)

à l'ouverture du classeur, on supprime les MFC et on les reconstruit...

En 5 ans, t’es le premier à évoquer cette idée !!!

Pourquoi pas (à part qu’on ne peut pas changer la police).

fractionnements de MFC dans le cadre de certaines utilisations est un vrai problème

contourner les problèmes de démultiplication de celles-ci par Excel

Ça fait plaisir d’être compris. Sans enfoncer le couteau dans la plaie, on m’a à plusieurs reprises (ailleurs qu’ici) expliqué qu’il fallait soit faire avec, soit éduquer les utilisateurs, etc.

Rien que couper quelques lignes dans des dossiers en cours, pour les coller dans un autre onglet une fois terminés, je ne peux pas m’en passer. Et c’est sans compter les insertions. Et tout ça foire quotidiennement mes règles de MFC …

Tu fais état de 5 MFC distinctes

Plutôt qu’une solution ponctuelle dédiée à 1 classeur ; je préfèrerai si possible du code avec une « section » que je modifierai moi-même au grès de mes besoins dans les prochaines années. Exemples

 If Cells(chiffre, lettre).Value Like "*faire *" Then
            ActiveCell.Interior.Color = 0
            ActiveCell.Font.ColorIndex = 3
        End If

ou encore

 If c.Value Like "*attente*" Then c.Font.ColorIndex = 46: c.Font.Bold = True 

L'étendue des lignes 2 à 999 me gêne un peu

Je suis entre 300 et 400 dans mon ‘’ vrai ‘’ classeur, donc admettons 500 ça serait bien.

Par contre, en restriction de colonnes, y en a que 8 : G H I J + O P Q R

Il vaut toujours mieux ne pas travailler dans le vide.

Je joins mon tableau avec seulement le (code n°1) et les règles de MFC

C'est assez simple à faire […] mais cela reste un type de procédure toujours un peu fastidieux à écrire (à mon sens).

Par avance, merci pour toutes les interventions et le travail d’écriture !

.

Bonjour,

On ne peut pas dire que tu n'es pas loquace !

Effectivement de trop longs posts au démarrage d'un sujet peuvent décourager... On attend que le sujet soit bien caractérisé, mais de façon concise, de façon qu'on puisse détecter rapidement la question posée et décider si on y va voir de plus près ou pas...

Ensuite si d'autres précisions doivent être apportées ou si le modèle ne fournit pas tous les éléments, il y a lieu de développer mais la chose est alors engagée.

Le fractionnement des MFC est un problème connu ici . Comme on finit toujours pas le rencontrer en utilisant Excel, il doit l'être certainement aillleurs ! Et utiliser VBA pour remettre de l'ordre régulièrement est une solution qui tombe sous le sens. Je suis loin d'être le seul à y avoir pensé et je ne crois pas qu'on ait le sentiment d'avoir trouvé une solution originale, car que faire d'autre ?

J'ai eu un peu de mal à suivre tes digressions... Le code que tu cites ne crée pas de MFC...

Restons sur les MFC, j'ai codé la reconstruction des MFC telles que définies. En procédure Workbook_Open, qui donc s'exécutera à l'ouverture du classeur.

Si tu n'as pas de telle procédure déjà existante, je conseille de laisser ainsi. Si tu en as déjà une, pour mieux t'y retrouver, je conseille de déplacer ce code dans un module standard, donner un nom à la procédure, par exemple Sub MFCdossiers (qui remplace le Private Sub Workbook_Open) et tu mets le nom (MFCdossiers) en fin de ta proc. Wbk_Open pour qu'elle soit lancée à l'ouverture.

Private Sub Workbook_Open()
    Dim clr, bld, tx, i%
    clr = Array(vbRed, vbRed, RGB(226, 107, 10), RGB(118, 147, 60))
    bld = Array(True, False, True, False)
    tx = Array("problème", "prévoir", "attente", "OK")
    With Worksheets("DOSSIERS")
        With .Range("C2:S999")
            .FormatConditions.Delete
            With .FormatConditions.Add(xlExpression, , "=MOD(LIGNE();2)")
                .Interior.Color = RGB(216, 228, 188)
                .Borders(xlTop).LineStyle = xlContinuous
                .Borders(xlBottom).LineStyle = xlContinuous
                .StopIfTrue = False
            End With
        End With
        With .Range("G2:R999")
            For i = 0 To 3
                With .FormatConditions.Add(xlTextString, String:=tx(i), TextOperator:=xlContains)
                    With .Font
                        .Color = clr(i): .Bold = bld(i)
                    End With
                    .StopIfTrue = False
                End With
            Next i
        End With
    End With
End Sub

J'ai fait aussi compact que possible... L'utilisation de variables devrait te faciliter les adaptations si tu en as. Tes 4 MFC se différencient par 3 éléments : la couleur de police, police gras ou non, et le texte testé.

C'est pourquoi on peut établir 3 tableaux (inclus dans des variables Variant) d'indice 0 à 3 (chacun correspondant à la caractéristique d'une des MFC) :

  • le tableau clr liste les couleurs (NB- pour les 8 couleurs de base on dispose de constantes VBA : vbRed, vbBlue, vbCyan, etc., et pour les autres utiliser la fonction RGB pour les définir, [dans le menu des Couleurs, au tableau autres, on trouve les valeurs RGB de la couleur choisie)
  • le tableau bld liste le caractère Gras ou non (valeurs booléennes, True ou False)
  • le tableau tx liste les critères texte...
On peut donc modifier les textes testés et la mise en forme si trouvés. On peut en ajouter (augmenter alors aussi la boucle 0 à 3 (3 étant l'indice max des tableaux, il faut l'ajuster sur les tableaux, soit nombre d'éléments-1) ou en retrancher (réduire la boucle aussi) ou modifier...

Cordialement.

Bonjour.

Merci pour ton classeur.

Je pense toutefois que tu surestimes ma compréhension du VBA ^^

Le code que tu cites ne crée pas de MFC...

Effectivement, j'ai d'ailleurs supprimé le Worksheet_Change cité plus haut, qui doit être un reliquat d'un autre de mes classeurs.

Tri Reclasse et Ligne, j'avoue que je ne sais pas trop, donc j'ai tout viré ...

Et puisque Worksheet_Change n'est pas impacté, j'ai laissé mon (code n°1) avec TYPES et TYPES Tableau pour ma liste déroulante.

Là, tout semble plus cohérent.

j'ai codé la reconstruction des MFC telles que définies

J'ai copié le code, et juste changé le nom du classeur : ça marche, c'est nickel !

Si j'ajoute une règle volontairement ou si elles se dupliquent par copier/coller ... quand je relance le classeur tout revient dans l'ordre.

Un grand merci, ça fonctionne pour ce classeur, je peux poursuivre mon travail dessus et suis serein de ce côté là !

L'utilisation de variables devrait te faciliter les adaptations si tu en as. [...] On peut en ajouter (augmenter alors aussi la boucle 0 à 3 (3 étant l'indice max des tableaux, il faut l'ajuster sur les tableaux, soit nombre d'éléments-1) ou en retrancher (réduire la boucle aussi) ou modifier...

Sérieusement !?

Je n'irai pas jusqu'à dire que je n'ai rien compris, car je cerne la logique de ta méthode, et je comprends un peu le cheminement de ton code. Mais sincèrement, c'est inutilisable à mon niveau pour d'autres classeurs.

Si je me base sur mes années 2010-2017 et admettons les 5 prochaines années, je sais que je n'utiliserai de façon récurrente aucune MFC complexe. Et même dans des manips classiques d'Excel, je ne testerai jamais de dates. Concrètement, ça pourrait être un test lié à la valeur d'un nombre, mais plus probablement la même chose qu'ici, à savoir " le texte contient ".

À cela je sais déjà que pour moi, il y a du formatage que je n'utilise jamais, donc il reste :

  • contour ou pas contour en trait plein
  • couleur de remplissage de l'arrière plan
  • style de la police (normal, italique, gras)
  • couleur de la police
  • taille de la police
  • (éventuellement) changement de police

Sans faire de mise-en-concurrence (cf. début du topic), les bouts de code que j'avais déjà eu m'apparaissent beaucoup plus clairs.

If c.Value Like "*attente*" Then c.Font.ColorIndex = 46: c.Font.Bold = True

Je ne sais pas si c'est ce code est optimal, mais le jour où j'ai 10 mots à tester, je copie toute la feuille de code, j'ouvre une page web avec les couleurs d'index, et il me reste à dupliquer une ligne de ce genre 10 fois et adapter aux besoins du nouveau classeur. Ça irait presque plus vite que de créer 10 règles de MFC avec l'interface.

Là dans ce que tu me proposes, ça me parait infaisable ... c'est trop compliqué pour moi.

Est-ce envisageable pour toi d'étoffer ton code pour le présenter avec range / le mot recherché / les 6 éléments de formatage que je viens de citer. ? Afin qu'à mon niveau ça soit adaptable pour mes futurs besoins !?

PS : Tu en as déjà beaucoup fait (à commencer par lire mes messages ^^)

donc si ce n'est pas possible, pas grave je me débrouillerai (ou reviendrai vous voir pour mon prochain classeur ^^).

Encore merci en tout cas, pour mes prochaines semaines j'ai de quoi faire sereinement !

Bonjour,

If c.Value Like "*attente*" Then c.Font.ColorIndex = 46: c.Font.Bold = True

C'est une expression cohérente, mais pas MFC !, on parlait MFC... !

Une petite critique cependant : jusqu'à Excel 2003, pour ce qui est des couleurs, il fallait privilégier ColorIndex, car seules les couleurs de la palettes pouvaient être affichées dans Excel. A partir de Excel 2007 tout a changé pour les couleur, plus de limitation, et il est devenu préférable de privilégier Color (que l'on peut facilement définir avec la fonction RGB(rouge, vert, bleu) [paramètre de chaque composante de 0 à 255]).

Pour le reste, je te met de côté, demande du temps de répondre...

Rapidement, je ne t'embête pas d'avantage pour aujourd'hui.

J'ai conscience que ça prendrait du temps.

Et je ne critique pas ta solution de suppression / refonte au chargement des règles de MFC car ça fonctionne, et j'ai d'ailleurs déjà rechargé 2 fois aujourd'hui mon " vrai " document, donc ça m'aide vraiment !!!

Ma remarque / requête c'est juste qu'en l'état, ton code lié aux variables est moins explicite que l'expression citée précédemment. Donc sans te demander de changer de solution, si c'est faisable à tes heures perdues d'étoffer un jour le même principe de refonte de MFC, ça serait cool. (Je vais être honnête, puisque t'es le seul à m'avoir proposé ça, je n'ai jamais cherché sur la toile ! ... peut-être qu'un truc exhaustif existe déjà).

'************************************************************************
'       *   MFC 0   *   MFC 1   *      MFC 2        *      MFC 3        *
'************************************************************************
' tx    * problème  *  prévoir  *     attente       *        OK         *  texte testé
'************************************************************************
' bld   *   True    *   False   *       True        *       False       *  Police Gras ou non
'************************************************************************
' clr   *   vbRed   *   vbRed   *  RGB(226,107,10)  *  RGB(118,147,60)  *  Couleur Police
'************************************************************************

En commentaire au-dessus de la proc.

Tu as sous les yeux un tableau de composition de tes MFC et le contenu des variables tableaux en lignes !


Bonjour.

L'entête du code est plus explicite, mais ce n'est pas ça que je n'ai pas compris.

Je tourne en rond depuis l'autre jour, donc je suis désolé d'insister, mais je réclame encore votre aide ...

Par souci de simplification, je vais me passer de tous les autres formatages que j'ai cité plus haut.

Sauf un ... serait-il possible d'ajouter une 4eme variable pour la couleur de remplissage !?

J'ai essayé de déclarer
Dim clr, bld, tx, remplissage, i%
remplissage = Array(vbWhite, vbWhite, vbWhite, vbWhite)

Mais je ne sais pas où mettre le
Interior.Color = remplissage(i)

Par avance, merci.

Pourquoi veux-tu remplir tes cellules en blanc ?

Elles n'ont pas de couleur initialement et apparaissent donc en blanc.

Les mettre en blanc n'y change rien, sauf te faire disparaître le quadrillage écran et alourdir ton fichier.

De plus un tableau avec 4 fois la même valeur n'a pas d'intérêt. C'est que tu mets partout alors, le mettre directement sans intermédiaire !

Bonjour.

Pourquoi veux-tu remplir tes cellules en blanc ?

héhé, non ... suis pas c*n au point de vouloir ajouter une variable pour mettre 4 fois du blanc.

Je me permets de recopier ce que j'avais répondu au début du sujet :

Plutôt qu’une solution ponctuelle dédiée à 1 classeur ; je préférerai si possible du code avec une « section » que je modifierai moi-même au grès de mes besoins dans les prochaines années

Ce que j'essaye d'expliquer depuis le début (y compris en 2015...) c'est que je ne veux pas emmerder quelqu'un sur un forum à chaque fois que j'ai une MFC à faire. Je cherche une solution compréhensible et adaptable à mon niveau. L'idée de fermer le fichier et de le relancer pour que le code efface et recrée les règles est intéressante. Mais en l'état, ta solution (sans doute la plus synthétique et optimale) m'est inexploitable car je n'arrive pas à faire des ajouts.

Afin que ça soit plus clair, j'ai effacé le code (qui efface au chargement) et j'ai mis les règles de MFC qui m'intéressent pour ce classeur.

Aurais-tu le temps et l'amabilité de transcrire ça en vba ?

Et si oui, peut-être que j'arriverai à me débrouiller seul par la suite.

Question subsidiaire, si le problème est "connu" n'existe-il pas de module complémentaire (même payant ...) qui permet l'exportation / importation des règles de MFC ?

Euh .... UP ?

Salut,

J'ai un peu de mal à m'y retrouver pour répondre à tout... Hier j'étais sous le coup de somnolences liées à un comprimé calmant que j'avais avalé le matin (et dont je sais que l'effet est toujours particulièrement soporifique pour moi), et il y avait des séquelles aujourd'hui (enfin hier maintenant, je perds le fil...). Mais ça viendra !

Afin que ça soit plus clair, j'ai effacé le code (qui efface au chargement) et j'ai mis les règles de MFC qui m'intéressent pour ce classeur.

Aurais-tu le temps et l'amabilité de transcrire ça en vba ?

Plus clair, dis-tu !? Il y en a 5 qui ressemblent assez étrangement à celles que tu m'as fait coder en VBA...

Il y en a 6 autres... ! que je ne veux même pas toucher avec des pincettes ! C'est n'importe quoi !

Sur les 5 ressemblant à des MFC rationnellement établies, la seule différence avec le codage antérieur porte sur la plage d'application.

Pour l'une on va jusqu'à J au lieu de S. Pour les autres on étend à U au lieu de R.

Transcrire ça en VBA, c'est justement ce que j'ai déjà fait ! Tu es tout de même capable de changer une lettre de colonne dans une référence de plage de S à J ou de R à U ! Pas d'autre changement ! Le code est donc déjà écrit !

Je ne comprends plus vraiment ce que tu demandes !

Ce que je demande ?

1/ une solution accessible

(personne ne m'en a proposé une depuis des années, même en échange d'un p'tit geste paypal ...)

2/ à défaut, j'utilise ta solution de suppression des MFC et réécriture au lancement

L'inconvénient c'est que pour ajouter une règle, il faut l'ajouter au code VBA

3/ un exemple concret d'ajout d'une MFC supplémentaire sur une autre plage

4/ le code à ajouter pour remplir une cellule (et le code couleur pour "aucun remplissage")

5/ le code pour des règles d'un type différent

Si on teste OK dans une cellule, son fond est rempli ... Mais comment faire pour remplir la cellule juste à droite ?

Exemple, une règle est une formule de test sur la colonne P et s'applique à P et Q

J'ai commencé à regarder, mais euh .......

'                    MFC 0             MFC 1     MFC 2            MFC 3             MFC 4              MFC 5            MFC 6
'                    Tableau           Tableau   Tableau          Tableau           dossier ok ?       Étude            MOe
'                    G:R               G:R       G:R              G:R               O:O                P:Q              R:S
'   Texte testé      problème          prévoir   attente          OK                OK                 OK               OK
'   Police (gras)    True              True      True             False             False              False            False
'   Police (couleur) vbred             vbred     RGB(226,107,10)  RGB(118,147,60)   RGB(118,147,60)    RGB(118,147,60)  RGB(118,147,60)
'   Remplissage      xlColorIndexNone  vbYellow  xlColorIndexNone xlColorIndexNone  RGB(216, 228, 188) RGB(153,204,102) RGB(153,204,102)

Private Sub Workbook_Open()
    Dim tx, bld, clr, fond, i%
    tx = Array("problème", "prévoir", "attente", "OK")
    bld = Array(True, False, True, False)
    clr = Array(vbRed, vbRed, RGB(226, 107, 10), RGB(118, 147, 60))
   fond = Array(vbWhite, vbYellow, vbWhite, vbWhite)

    With Worksheets("DOSSIERS en cours")
'********************************************************************************************
  With .Range("C2:T999")
  .FormatConditions.Delete
  End With
'********************************************************************************************
        With .Range("C2:N999")
            With .FormatConditions.Add(xlExpression, , "=MOD(LIGNE();2)")
                .Interior.Color = RGB(216, 228, 188)
                .Borders(xlTop).LineStyle = xlContinuous
                .Borders(xlBottom).LineStyle = xlContinuous
                .StopIfTrue = False
            End With
        End With
'********************************************************************************************

        With .Range("G2:R999")
            For i = 0 To 3
                With .FormatConditions.Add(xlTextString, String:=tx(i), TextOperator:=xlContains)
                    With .Font
                        .Color = clr(i): .Bold = bld(i)
                    End With
                    With .Interior.Color = fond(i)
                    End With
                    .StopIfTrue = False
                End With
            Next i
        End With

'********************************************************************************************

        With .Range("O2:O999")
            For i = 4 To 4
                With .FormatConditions.Add(xlTextString, String:=tx(i), TextOperator:=xlContains)
                    With .Font
                        .Color = clr(i): .Bold = bld(i)
                    End With
                    With .Interior.Color = fond(i)
                    End With
                    .StopIfTrue = False
                End With
            Next i
        End With

'********************************************************************************************

        With .Range("P2:Q999")
            For i = 5 To 5
                With .FormatConditions.Add(xlTextString, String:=tx(i), TextOperator:=xlContains)
                    With .Font
                        .Color = clr(i): .Bold = bld(i)
                    End With
                    With .Interior.Color = fond(i)
                    End With
                    .StopIfTrue = False
                End With
            Next i
        End With

'********************************************************************************************

        With .Range("R2:S999")
            For i = 6 To 6
                With .FormatConditions.Add(xlTextString, String:=tx(i), TextOperator:=xlContains)
                    With .Font
                        .Color = clr(i): .Bold = bld(i)
                    End With
                    With .Interior.Color = fond(i)
                    End With
                    .StopIfTrue = False
                End With
            Next i
        End With

'********************************************************************************************
    End With
End Sub

Bonjour,

je viens de "retrouver" un fichier que j'avais fait pour une personne...

Sur la feuille système une série de cellule qui sert de "référence" aux MFC du tableau "Base de données".

Ci joint :

12mfc-loureed.xlsm (201.06 Ko)

Voir si une idée comme celle-là peut vous contenir...

L'idée ? Avoir une feuille système avec le code VBA de mise en place des MFC, et modifications des MFC directement sur la feuille système avec les critères adéquate de fonctionnement.

A vous tester et d'adapter

@ bientôt

LouReeD

Salut LouReed !

Ton idée est intéressante, d'une feuille permettant de définir les critères de MFC à prendre en compte dans une procédure...

Elle devrait pouvoir convenir à notre ami en la simplifiant un peu !

Ce qu'il y a quand même, c'est que quelle que soit la méthode, il convient de mieux maîtriser la construction des MFC...

-D'abord le dimensionnement des plages d'application, un minimum de rationalité doit être observé en la matière. Le dimensionnement en lignes dans celles que j'ai reprises dans la première procédure (la seule d'ailleurs, j'en ai fait qu'une ! ) allait de la ligne 2 à 999. Si cela est maintenu, il convient de s'y tenir pour toutes ! Et pas de faire varier le dimensionnement au petit bonheur ! On peut définir le dimensionnement autrement, voir le rendre variable, mais les critères de définition doivent être arrêtés un bonne fois !...

-Ensuite, on avait au départ un lot de 5 MFC (une reposant sur une formule [xlExpression], les 4 autres sur une partie du contenu [xlContains]). On en ajoute, qui relèvent à priori de formules. Les diverses catégories de MFC (dont la construction n'est pas identique) doivent être un tant soit peu maîtrisées par l'intéressé. Et il faut tout de même prévoir que les modifications que l'on est susceptible d'introduire par la suite doivent être prévues dès le départ. C'est à dire que l'on doit déterminer les critères de variations pour chaque catégorie de MFC...

  • Les éléments à mémoriser alors seraient donc :
  • -le type : xlContains ou xlExpression ou...(si on en ajoute)
  • -la plage d'application
  • -le critère testé : aisé pour xlContains car il s'agit d'un mot clé dont on teste la présence, plus délicat dans la autres cas pour lesquels il faudra en coder la façon de l'exprimer pour pouvoir l'interpréter ensuite sans erreur...
  • -les paramètres de mise en forme : tous ceux susceptibles d'être définis doivent être pris en compte, on laisse vide si n'intervient pas dans la mise en forme, sinon on le définit...
  • --couleur police (couleur)
  • --police gras
  • --couleur de fond (couleur)
il peut y en avoir d'autres...

-Je pense par contre qu'il conviendrait d'éviter la définition de priorité (et faire en sorte que toutes les MFC puissent s'appliquer, on le peut en principe avec formules si la formule est suffisamment complète pour éviter toute ambiguïté). Pour celles ne reposant pas sur des formules, le problème ne se pose en principe pas dans la mesure où 2 mots-clés ne sont pas présents simultanément dans la même cellule. Et mettre systématiquement StopIfTrue à False...

Cordialement.

Merci LouReed pour ce classeur !

Je n'interférerai pas dans les remarques de MFerrand ... d'ailleurs je ne sais même pas si elles me sont adressées ou si ce sont des remarques génériques sur un optimisation possible du code !?

J'ai donc repris le MFC_LouReeD que j'ai vidé puis rempli d'après mon classeur.

J'ai toutefois quelques questions.

- Est-il possible d'y ajouter la règle qui applique du "vert" une ligne sur 2 ?

=MOD(LIGNE();2)

- Les règles s'appliquent de la ligne 1 à la ligne 3 (donc entête +2)

Comment faire pour que les règles générées le soit de la ligne 2 à 999 (ou au pire de 1 à 999, je peux m'arranger pour renommer mes "titres" qui seraient concernés par des tests de MFC)

- Dans l'exemple en pièce jointe, j'ai rempli en rouge une ligne remplie par erreur.

Avec ce classeur, peut-on faire supprimer ou insérer des lignes (descendre/monter cellules) ?

Ou si jamais j'ai 40 MFC et que j'ai envie d'en intercaler une entre la 22e et la 23e, faut copier / coller mais surtout ne rien supprimer

- En bidouillant un peu, je ne comprends pas : colonne de référence / première colonne test / colonne début / colonne fin ...

J'aimerai pour remplacer la formule de ma précédente règle de MFC, faire en sorte que :

R = colonne testée

R = première colonne remplie si R contient " x "

S = dernière colonne remplie si R contient " x "

Mais je n'y parviens pas.

Par avance, merci.

Bonsoir,

- Est-il possible d'y ajouter la règle qui applique du "vert" une ligne sur 2 ?

=MOD(LIGNE();2)

ma solution : passer votre plage de données en tableau nommé Excel :

sélectionnez une cellule de la plage de données, menu insertion du ruban, insérer tableau, mon tableau comporte une entête, OK.

Voilà votre plage de données est un tableau Excel !

L'avantage ? Dans le menu "outils de tableau" "création" sur la droite vous pouvez créer votre mise en forme, sur le fichier joint j'ai choisi le format prédéfini d'une ligne sur deux en vert... Mais il y a l'option "mise en forme personnalisée"...

- Les règles s'appliquent de la ligne 1 à la ligne 3 (donc entête +2)

Comment faire pour que les règles générées le soit de la ligne 2 à 999 (ou au pire de 1 à 999, je peux m'arranger pour renommer mes "titres" qui seraient concernés par des tests de MFC)

ma solution ? elle est déjà expliquée juste au dessus : dans un tableau Excel, les mise en formes se recopies sur toutes les lignes... du coup une fois les MFC forcées par le bouton de la feuille système, toutes les lignes du tableaux sont mises en forme.

EDIT ! En fait le code ne prend pas en compte le fait que ce soit un tableau... pour corriger la zone il faut remplacer dans le code le 3 par un 2 ou un 1 si vous voulez ou pas que la ligne d'entête prenne les même conditions...

        Range(Sheets("Système").Cells(Ligne, 16).Value & "2:" & Sheets("Système").Cells(Ligne, 17).Value & Derligne).Select
        Range(Sheets("Système").Cells(Ligne, 16).Value & "2:" & Sheets("Système").Cells(Ligne, 17).Value & Derligne).Activate

Voilà, le fait que ce soit un tableau il doit y avoir une écriture "plus simple" ou du moins différente... je ne sais pas... FIN EDIT

- Dans l'exemple en pièce jointe, j'ai rempli en rouge une ligne remplie par erreur.

Avec ce classeur, peut-on faire supprimer ou insérer des lignes (descendre/monter cellules) ?

Ou si jamais j'ai 40 MFC et que j'ai envie d'en intercaler une entre la 22e et la 23e, faut copier / coller mais surtout ne rien supprimer

En effet, vous pouvez supprimer cette ligne rouge mais en gardant le principe d'une ligne vide avant et après chaque mise en forme, donc pour supprimer la ligne rouge il faut sélectionner cette ligne et celle du dessous, puis de décaler vers le haut. Visuellement il y a un décalage de cadre sur la dernière ligne mais ces cadres ne servent qu'à repérer où on doit mettre en forme les cellules.

Les lignes "blanches" entre chaque ligne de Mise en forme servent à différencier les bordures d'une cellule par rapport à une autre.

- En bidouillant un peu, je ne comprends pas : colonne de référence / première colonne test / colonne début / colonne fin ...

J'aimerai pour remplacer la formule de ma précédente règle de MFC, faire en sorte que :

R = colonne testée

R = première colonne remplie si R contient " x "

S = dernière colonne remplie si R contient " x "

là il me faut me replonger dans le code... car cela fait un petit moment que je ne l'ai plus "lu"...

fichier joint modifié en Tableau Excel :

@ bientôt

LouReeD

Rechercher des sujets similaires à "fusionner codes orientes mfc vba"