Formule - macro

Résolu
Bonjour,

Dans la colonne N de ma feuille1 que j’ai nommée Produits j’ai cette formule,

=SI(NB.VIDE(I2)=1;"";SI(I2/G2<0.97;"NCR";"OK"))

J’aurais voulu savoir si c’était possible de mettre cette formule dans une macro ?
Et quel serait le code a mettre si tel est le cas ?

Merci de votre aide…
Configuration: Windows 2000
Internet Explorer 6.0

35 réponses

Résumé de la discussion

La problématique porte sur l’intégration d’une formule dans une macro Excel pour automatiser son calcul dans une colonne lors de l’insertion de données dans une feuille. Plusieurs réponses proposent d’utiliser Range.Formula pour appliquer la même condition sur une plage jusqu’à 15000 lignes, avec des ajustements selon que le calcul se fasse dans la feuille ou dans la macro. Des échanges évoquent aussi le besoin que le calcul s’effectue automatiquement lors de l’insertion via un UserForm, et non pas uniquement lorsque les données existent déjà en cellule. En cas de difficultés, des précisions sur les opérateurs et les cas NCR apparaissent, et des tests montrent que la macro peut nécessiter des ajustements selon les valeurs vides et les cas d’erreur.

Bobot (l’IA à votre service)
  1. Contributeur
    Bonjour,
    Range("A1").Formula = "=SI(NB.VIDE(I2)=1;"";SI(I2/G2<0.97;"NCR";"OK")) "
    Remarque tu met NB.Vide pour une seule cellule, tu peu remplacer par VIDE(I2) ou I2<>""
    A+
    0
    1. Bonjour lermite222,

      Merci pour cette réponse rapide,

      j'avais mal formulé ma question, ce que je voudrais, c'est que la formule ne s'applique pas juste à la ligne 2 mais à tout le tableau, et que lorsque j'insère mes données dans ma feuille, ça se calcul automatiquement...
      0
      1. Contributeur
        Je ne comprend pas bien, en mettant NB.VIDE = ? ça peu changer donc ce serra presque toujours NON.
        Explique un peu plus.
        A+
        0
        1. Non en fait ta réponse est juste mais ne s’applique pas a toute la colonne N mais juste a la ligne 2.

          Ce que je voudrais c’est que ça s’applique a toute la colonne N
          0
          1. Contributeur
            Cette fois, si j'ai compris, tu veux vérifier si toute la colonne est vide sauf la ligne 2
            dans ce cas, faut mettre une plage de cellule
            "=SI(NB.VIDE(I2:i100)=1
            par exemple
            Mais tu ne serra jamais certain que c'est la ligne 2 qui n'est pas vide !
            dans ce cas...
            =SI(ET(I2;NB.VIDE(I3:i100)=0);
            0
            1. Non, désolé, je ne parlais pas de la fonction NB.VIDE mais de la macro,

              Range("A1").Formula = "=SI(NB.VIDE(I2)=1;"";SI(I2/G2<0.97;"NCR";"OK"))

              Cette ligne fonctionne mais je voudrais qu’elle s’applique a toute ma feuille ou, par exemple, de

              =SI(NB.VIDE(I2)=1;"";SI(I2/G2<0.97;"NCR";"OK")) jusqu’à
              =SI(NB.VIDE(I15000)=1;"";SI(I15000/G15000<0.97;"NCR";"OK"))

              et que lorsque je rentre des données dans ma feuille ça se calcule automatiquement avec la macro, un peu comme ce que vous m’aviez fait la dernière fois, lorsque je rentre une date, l’année, la semaine, le temps de passage…. Tout se calculait automatiquement…
              0
              1. Contributeur
                Range("J2").Copy 'à adapter à la colonne où se trouve la formule

                Range("J3:J15000").Select 'à adapter à la colonne où se trouve la formule
                ActiveSheet.Paste
                Tu dit...
                Mais comme je dit plus haut, SI(I2: suffit
                Autre remarque, si G est vide fait une erreur DIV/0
                faudrait mettre
                SI(ET(I2;G2); ...
                A+
                0
                1. Je 'arrive pas a faire comme tu dis, si des fois, voici le fichier (simplifié) en question.
                  Merci encore...

                  http://www.cijoint.fr/cjlink.php?file=cj200811/cij35BaCg6.xls
                  0
                  1. Contributeur
                    OK, faut inverser la 1ère condition...
                    =SI(ET(G2;I2);SI(I2/G2<0,97;"NCR";"Ok");"")

                    Et oublie pas le End Sub dans ta sub Calc.
                    0
                    1. Voilà ce que ça donne alors.

                      mais la ligne de formule se met en rouge ==> Range("A1").Formula = "=SI(NB.VIDE(I2)=1;"";SI(I2/G2<0.97;"NCR";"OK"))

                      Private Sub calc()

                      Range("A1").Formula = "=SI(NB.VIDE(I2)=1;"";SI(I2/G2<0.97;"NCR";"OK"))

                      Range("N2").Copy 'à adapter à la colonne où se trouve la formule

                      Range("N3:N15000").Select 'à adapter à la colonne où se trouve la formule
                      ActiveSheet.Paste

                      End Sub
                      0
                      1. Contributeur
                        Y a effectivement un problème, tu à des colonnes cachée, des cellules sont verrouillées, cahée, format conditionel...etc
                        Excel ne veux pas accepter la formule et je ne trouve pas pourquoi
                        el la formule tel quel ne va pas.. après test, la formule serrait
                            =SI(ET(G2<>"";I2<>"");SI(I2/G2<0,97;"NCR";"Ok");"")

                        elle fonctionne parfaitement quand je la met en N2 mais quand je veux l'entrer par VBA excel refuse,
                        pour info,
                        en VBA j'ai dédoublé les " (guillements) et elle ne s'inscrit plus en rouge.
                        donne toujours Erreur 1004, ce qui veux rien dire.

                        Dans un premier temps tu la copie en N2
                        et dans un module GENERAL (pas module de feuille) tu met
                        Public Sub calc()
                            Sheets("Produits").Select
                            Range("N2").Copy
                            Range("N3:N15000").Select 
                            ActiveSheet.Paste
                        End Sub

                        ça ca va,
                        Si entretemps, un autre intervenant trouve la solution !!
                        A+
                        0
                    2. d'accord merci de ton aide, ça ça fonctionne, mais effectivement, ce que moi je voudrais, c'est que le calcul se fasse dans la macro et non pas dans ma feuille..

                      Merci quand même pour ta précieuse aide.
                      0
                      1. Contributeur
                        Si le calcul doit se faire dans la macro C'EST BEAUCOUP PLUS SIMPLE.
                        Autre possibilité, faire une fonction personnalisée
                        Tu dit
                        0
                    3. que le calcul se fasse dans la macro alors; si c'est plus simple et pas trop difficile a paramétrer en cas de modification..
                      0
                      1. Contributeur
                        IMPOSSIBLE de faire quoi que ce soit sur ta feuille, toutes les cellules sont verrouillées mais toujours est-il que ni une fonction personnalisée; ni une fonction générale ne fonctionne, pas de possibilité d'accéder à la feuille produits par code.
                        Pas possible de mettre la fonction personnalisée par code...
                        Je n'ai jamais rencontré ça, peu être Eric ?? ou un autre intervenant ?
                        En déverrouillant toutes les cellules, cette macro fonctionne mais c'est pas pratique, il faut la rappeler chaque fois que des lignes sont ajoutées où modifiées
                        j'ai aussi tenter FormulaR1C1, mais idem.
                        Sub Resultat()
                        Dim Lig As Long
                        Dim Col As Integer
                            Sheets("Produits").Select
                            For Lig = 2 To Range("C65536").End(xlUp).Row
                            If Cells(Lig, 7) And Cells(Lig, 9) Then
                                If (Cells(Lig, 9) / Cells(Lig, 7)) < 0.97 Then
                                    Cells(Lig, 14) = "NCR"
                                Else
                                    Cells(Lig, 14) = "OK"
                                End If
                            Else
                                Cells(Lig, 14) = ""
                            End If
                            Next Lig
                        End Sub


                        Sais pas ce qui se passe sur ce classeur. Y a un truc...
                        A+
                        0
                        1. Contributeur
                          Re,

                          ben il a désactivé le calcul automatique, c'est vrai que ça surprend...
                          Faut prévenir tchulio, quand c'est comme ça !!! ;-)
                          0
                      2. d'accord ben merci pour la macro... je vais essaye de comprendre ce qui arrive sur ce classeur.... bonne soirée
                        0
                        1. je viens d'essayer la macro, donc c'est bon ça fonctionne, par contre si la valeur en I est trop faible par rapport à G, il n'y a rien qui s'affiche, normalement il devrait s'afficher "NCR" en colonne N.

                          Prenons par exemple 100 en colonne G et que j'en ai que 10 en colonne I, il n'y a rien qui s'affiche, par contre si j'en ai 20 en I, il y a NCR...

                          Je ne vois pas ce que ça peut être....
                          MErci
                          0
                          1. Contributeur
                            Bonjour,

                            en l'absence de lermite...
                            remplace le 1er test par :
                            If Cells(Lig, 7).Value > 0 And Cells(Lig, 9).Value > 0 Then
                            car 100d and 10d = 1100100 and 1010 = 0
                            eric
                            0
                        2. ok ben là ça marche mais si la valeur en I est égale à "0" ce qui arrive souvent, là il n'y a toujours rien qui s'affiche...
                          0
                          1. En fait c'est réglé je n'avais qu'à mettre >=. Je vais faire quelques test, merci beaucoup l'aide accordée :)
                            0
                            1. Bon j'ai regardé dans mon classeur, ça fonctionne parfaitement (pour 6000 lignes) donc c'est cool !

                              Pour contre je n'avais pas pensé. Ce code est bien pour calculer une feuille, mais en fait pour insérer mes données j'utilise un USF avec ce code, est ce qu'il y aurait possibilité de faire pour que ça calcule juste la ligne que j'insère et pas toute la feuille :

                              Private Sub NEW_VALID()

                              'Pose la question lorsque l'on clique sur Valider'
                              If TextBox11 <> 0 Then
                              Dim Msg, Style, Ctxt, Response
                              Msg = "Voulez vous vraiment enregistrer ce contrôle?"
                              Style = vbYesNo + vbCritical + vbDefaultButton2
                              Response = MsgBox(Msg, Style)
                              If Response = vbYes Then

                              Dim ligne As Integer
                              Dim rw As Long
                              'je retrouve la ligne concernée par les modifications en bouclant de 1 à 65000
                              For rw = 1 To 10000
                              If Worksheets("produits").Range("A" & rw) = Val(UserForm8.ComboBox1) Then
                              ligne = rw
                              Exit For
                              End If
                              Next

                              UserForm4.Show

                              Application.Worksheets("produits").Cells(ligne, 9) = TextBox1.Value
                              Application.Worksheets("produits").Cells(ligne, 12) = TextBox_visa.Value
                              Application.Worksheets("produits").Cells(ligne, 10) = CheckBox1.Value
                              Application.Worksheets("produits").Cells(ligne, 13) = Textbox2.Value
                              Application.Worksheets("produits").Cells(ligne, 21) = TextBox3.Value
                              Application.Worksheets("produits").Cells(ligne, 19) = TextBox5.Value
                              Application.Worksheets("produits").Cells(ligne, 20) = TextBox7.Value
                              Application.Worksheets("produits").Cells(ligne, 18) = TextBox9.Value
                              Application.Worksheets("produits").Cells(ligne, 17) = TextBox10.Value
                              Application.Worksheets("produits").Cells(ligne, 11) = CDate(TextBox11.Value)
                              Application.Worksheets("produits").Cells(ligne, 22) = ComboBox2
                              Application.Worksheets("produits").Cells(ligne, 24) = Format(Now, "DD/MM/YY HH:MM:SS")
                              Application.Worksheets("produits").Cells(ligne, 23) = Application.UserName
                              Application.Worksheets("produits").Cells(ligne, 25) = TextBox12.Value
                              Application.Worksheets("produits").Cells(ligne, 8) = ""

                              Unload Me
                              Range("AN1:AT1").Calculate
                              UserForm1.Show

                              End If
                              End If
                              End Sub
                              0
                              1. Contributeur
                                Bonjour, merci eric d'avoir pris la relève, j'ai été absent hier.
                                Mais ça m'énervait de pas trouver la solution et je crois que la solution suivante est beaucoup plus pratique.
                                CAR J'AI ENFIN TROUVE LE NOEUD DU PROBLEME.
                                Tes réf articles commence par des réf à des cellules et Excel les concidères comme tel et en déduit des réf circulaires, il faut mettre toute la colonne au format TEXTE et ça roule...oufffff ont peu enfin revenir à un exemple plus concret
                                Une fonction personnalisée est plus complète.
                                Dans un module général tu copie...
                                Function RetNCR_OK()
                                Dim Lig As Long
                                    Application.Volatile
                                    Lig = Application.Caller.Row
                                    If Cells(Lig, 7) > 0 Then
                                        If Cells(Lig, 9) = "" Or Cells(Lig, 9) = 0 Then
                                            RetNCR_OK = "NCR"
                                        ElseIf (Cells(Lig, 9) / Cells(Lig, 7)) < 0.97 Then
                                            RetNCR_OK = "NCR"
                                        Else
                                            RetNCR_OK = "OK"
                                        End If
                                    Else
                                        RetNCR_OK = ""
                                    End If
                                End Function

                                Tu peu aussi mettre ce code, maintenant ça fonctionne...
                                Private Sub calc()
                                    Range("N2").Formula = "=RetNCR_OK()"
                                    Range("N2").Copy 'à adapter à la colonne où se trouve la formule
                                    Range("N2:N15").Select 'à adapter à la colonne où se trouve la formule
                                    ActiveSheet.Paste
                                End Sub

                                Il n'est plus besoin de modifier la formule en cas de modification des données, mais tu doit soit recalculer (F9) ou mettre le calcul en automatique.
                                et tu peu simplifier la fin de ta macro par...
                                    With Sheets("produits")
                                        .Cells(ligne, 9) = TextBox1.Value
                                        .Cells(ligne, 12) = TextBox_visa.Value
                                        .Cells(ligne, 10) = CheckBox1.Value
                                        .Cells(ligne, 13) = Textbox2.Value
                                        .Cells(ligne, 21) = TextBox3.Value
                                        .Cells(ligne, 19) = TextBox5.Value
                                        .Cells(ligne, 20) = TextBox7.Value
                                        .Cells(ligne, 18) = TextBox9.Value
                                        .Cells(ligne, 17) = TextBox10.Value
                                        .Cells(ligne, 11) = CDate(TextBox11.Value)
                                        .Cells(ligne, 22) = ComboBox2
                                        .Cells(ligne, 24) = Format(Now, "DD/MM/YY HH:MM:SS")
                                        .Cells(ligne, 23) = Application.UserName
                                        .Cells(ligne, 25) = TextBox12.Value
                                        .Cells(ligne, 8) = ""
                                    End With

                                A+

                                0
                                1. Donc j'ai regardé, ça fonctionne.

                                  Le problème avec cette solution, c'est qu'il y a des formules. Car moi dans mon tableau, j'ai environ 7000 lignes, et des stats avec des TCD, et des fonctions sommeprod.
                                  Tu va donc comprendre que moins j'ai de formules, mieux ça tourne.

                                  En fait avec la macro que tu m'avais faites ça marchait parfaitement pour le calcul de la feuille,

                                  Sub Resultat()
                                  Dim Lig As Long
                                  Dim Col As Integer
                                  Sheets("Produits").Select
                                  For Lig = 2 To Range("C65536").End(xlUp).Row
                                  If Cells(Lig, 7).Value > 0 And Cells(Lig, 9).Value > 0 Then
                                  If (Cells(Lig, 9) / Cells(Lig, 7)) < 0.97 Then
                                  Cells(Lig, 14) = "NCR"
                                  Else
                                  Cells(Lig, 14) = "OK"
                                  End If
                                  Else
                                  Cells(Lig, 14) = ""
                                  End If
                                  Next Lig
                                  End Sub

                                  Ce qu'il m'aurait juste fallu en suplément c'est que lorsque je clique sur mon bouton Valider, a la fin des instructions pour rentrer mes valeurs:

                                  With Sheets("produits")
                                  .Cells(ligne, 9) = TextBox1.Value
                                  .Cells(ligne, 12) = TextBox_visa.Value
                                  .Cells(ligne, 10) = CheckBox1.Value
                                  .Cells(ligne, 13) = Textbox2.Value
                                  .Cells(ligne, 21) = TextBox3.Value
                                  .Cells(ligne, 19) = TextBox5.Value
                                  .Cells(ligne, 20) = TextBox7.Value
                                  .Cells(ligne, 18) = TextBox9.Value
                                  .Cells(ligne, 17) = TextBox10.Value
                                  .Cells(ligne, 11) = CDate(TextBox11.Value)
                                  .Cells(ligne, 22) = ComboBox2
                                  .Cells(ligne, 24) = Format(Now, "DD/MM/YY HH:MM:SS")
                                  .Cells(ligne, 23) = Application.UserName
                                  .Cells(ligne, 25) = TextBox12.Value
                                  .Cells(ligne, 8) = ""
                                  End With

                                  Que j'ait un code pour que ce calcul se fasse juste sur la ligne que j'insère... Avec un Row.source ou je sais pas si c'est possible,,,,

                                  MErci encore
                                  0
                                  • 1
                                  • 2

                                  Discussions similaires

                                  exo pix

                                  2 réponses