Remplacement formules par un code VBA

bonjour le forum,

bonjour à tous;

je sollicite votre expertise pour améliorer ce fichier que j'utilise depuis 2 ans mais qui s'alourdit de mois en mois et devient très lent vers juillet-août-septembre jusqu'à la fin de l'année.

évidemment, je mets ici un exemple très allégé.

l'objectif c'est d'arriver à avoir un code VBA qui remplace les formules de C3 à BD220.

A - en colonne C et ainsi de suite vers le bas = exemple : C3 = SOMME E3:BD3

B - en colonne E et ainsi de suite jusqu'en colonne BD

Ba - les lignes impairs = exemple : en fonction du code en B3, on cherche les lignes ou on a le même code sur la feuille "SORTIES" en

colonne H et on somme les quantités en colonne J par sorte (P ou C)

--> 1/ somme de tous les 'P' multiplié par le chiffre en colonne D de la feuille "DONNEES" sur la ligne qui correspond au code.

--> 2/ somme de tous les 'C' multiplié par le chiffre en colonne H de la feuille "DONNEES" sur la ligne qui correspond au code.

--> 3/ SOMME des 2 Resultats.

Bb - les lignes pairs = exemple : en fonction du code en B3, on cherche les lignes ou on a le même code sur la feuille "ENTREES" en

colonne I et on somme les quantités en colonne F.

merci d'avance pour votre intérêt.

cordialement.

Moutchec.

14classeur2.xlsm (496.21 Ko)

Salut moutchec,

quelque chose comme ça?

Pour initialiser 'MVTS' avec les valeurs VBA :

  • intégrer dans UNE COPIE de ton fichier de travail (teste d'abord !) les macros de chaque feuille ;
  • effacer les formules en [E:BD] excepté les formules Totaux en fin de tableau.
  • les Sub Worksheet_SelectionChange sont "sous commentaire" donc inopérantes en l'état : elles servent, via un simple clic sur chacune de ces deux feuilles à recalculer tes sommes selon les critères énoncés... sauf erreur de ma part, bien sûr!
Pour leur permettre de s'exécuter, enlever les apostrophes de début de ligne.

Le traitement prend quelques (nombreuses) secondes. Ensuite, SUPPRIMER ces macros sinon, à chaque clic, le calcul reprendra de plus belle!

Le calcul ne s'effectue que sur les lignes pour lesquelles la macro trouve une correspondance entre les n° de code produit.

Ci-dessous, le calcul en SORTIES.

If Not Intersect(Target, Range("J:J")) Is Nothing And Cells(iRow, 1) > 0 And Cells(iRow, 8) > 0 Then
    iRow1 = Range("A:A").Find(what:=Cells(iRow, 1), lookat:=xlWhole, searchdirection:=xlNext).Row
    iRow2 = Range("A:A").Find(what:=Cells(iRow, 1), lookat:=xlWhole, searchdirection:=xlPrevious).Row
    sWk1.Cells(sWk1.Range("B:B").Find(what:=Cells(iRow, 8), lookat:=xlWhole).Row, 4 + Cells(iRow, 1)) = _
        WorksheetFunction.SumIfs(Range("J" & iRow1 & ":J" & iRow2), Range("H" & iRow1 & ":H" & iRow2), Cells(iRow, 8), Range("K" & iRow1 & ":K" & iRow2), "P") * _
        sWk2.Range("A:A").Find(what:=Cells(iRow, 8), lookat:=xlWhole).Offset(0, 3) + _
        WorksheetFunction.SumIfs(Range("J" & iRow1 & ":J" & iRow2), Range("H" & iRow1 & ":H" & iRow2), Cells(iRow, 8), Range("K" & iRow1 & ":K" & iRow2), "C") * _
        sWk2.Range("A:A").Find(what:=Cells(iRow, 8), lookat:=xlWhole).Offset(0, 7)
        sWk2.Range("E:BD").AutoFit

A+

9moutchec.xlsm (383.52 Ko)

Bonjour, Bonjour curulis57

1-

je pense que, déjà, si tu enlevais les INDIRECT, car après tout les onglets ne sont pas vraiment des variables, ils ne sont que 2 (ENTREES et SORTIES)

cela permettrait de rester en excel sans macro

2-

autre méthode : tu as XL2016, pense à Power Query

3-

dernière solution ... un petit coup de TCD, voire 2, un entrées et un sorties et faire appel aux valeurs par LIREDONNEESTABCROISDYNAMIQUE

RE,

je ne m'y connais pas trop en macro mais je vois que c'est très compliqué à faire.

les résultats ne sont pas bons et ça prend plus de temps de calcul qu'avec formule, la question de la rapidité est la motivation première de l'idée VBA.

merci beaucoup pour votre intervention.

sincères salutations.

Moutchec.

Salut moutchec,

Pas d'accord!

J'ai mis ton 1er fichier à côté du mien, libéré des formules.

Qu'il puisse y avoir des erreurs, sans doute, ce serait trop beau, mais je constate que :

  • les valeurs en SORTIES sont pratiquement toutes équivalentes (je n'ai pas regardé toutes les lignes, non plus!) ;
  • que tes formules mettent un temps fou à se calculer là où VBA est instantané!
  • que tes formules 'ENTREES'... ne se calculent pas!? Là, je ne comprends pas!

A toi à essayer encore de trouver où le bât blesse!

Je continue ce soir à chercher ce qui pourrait clocher!

A+

RE,

voici le fichier avec les résultats attendus pour les semaines 1 à 5. en fait je pense avoir oublié de mentionner que les calculs doivent se faire par semaine, la colonne E correspondant à la semaine 1 et la colonne BD à la semaine 52.

les numéros de semaines sont en colonne A des feuilles ENTREES et SORTIES.

merci bcp pour votre intérêt.

Moutchec.

8moutchec.xlsm (394.17 Ko)

Bonjour Bonjour, Bonjour curulis57

Je ne partage pas vraiment le fait de calculer par macro

La macro peut automatiser certaines tâches comme actualiser des TCD

Je verrai donc plutôt une forme comme celle-ci (mais désolé, je me suis perdu dans les formules -bravo à vous deux, je n'ai pas eu le courage !- surtout que je retrouve pas du tout les valeurs), à partir de 2 TCD à réactualiser dans lesquels on va puiser les infos !

D'abord, la macro se contentera si nécessaire d'actualiser les TCD.

Ensuite, les calculs sont pris en charge par le TCD et n'alourdissent en rien le fichier. Si c'est cela l'objectif, il est alors atteint.

6classeur2.xlsm (399.44 Ko)

Salut moutchec,

pige plus trop ton calcul...

Beaucoup sont corrects tant en sortie qu'en entrée et d'autres...

A toi de vérifier certaines choses dans ton propre fichier... que je te renvoie, les feuilles SORTIES et ENTREES étant triées pour plus de facilité lors des tests.

J'ai recopié les colonnes de quantités sur le côté, histoire de retrouver les valeurs d'origine pour tests.

Prenons le produit 221410

- SORTIES semaine 3

10 pc. X 780 (P) = 7800

45 pc. X 65 (C) = 2925

Total = 11505 là où tu attends 8340

- ENTREES semaine 1

16175 là tu attends 8407

A te lire.

A+

6moutchec.xlsm (411.21 Ko)

bonjour le forum,

bonjour @Steelson,

bonjour @Curulis57,

je suis le premier étonné de constater ce matin que certains de mes résultats sont mauvais depuis 2 ans!!! vous avez en effet raison, sans doute imprécision au niveau des formules.

je me suis aussi gouré sur la colonne pour les "C" (colonne K) de la feuille SORTIES, il faut multiplier par colonne G de la feuille DONNEES et non "H".

Par contre, j'ai un BUG sur cette ligne du code de la feuille ENTREES :

Range("A2:I5267").Sort key1:=Range("A2"), order1:=xlAscending, key2:=Range("I2"), order2:=xlAscending, Orientation:=xlTopToBottom

pas de souci sur votre exemple, mais dans mon fichier toutes les colonnes de A à M sont remplies (non vides) et je pense que le problème vient de là.

merci bcp.

cordialement.

Moutchec.

Salut moutchec,

la ligne de code à problème dont tu parles n'existera pas dans ton fichier final : elle n'est là que pour faciliter les tests!

Je corrige en ce qui concerne le swap entre 'DONNEES' [G:H].

les résultats ne sont pas bons et ça prend plus de temps de calcul

J'ai droit à quel pourcentage pour la correction de tes chiffres d'entreprise?

Donc, c'est bon et on peut lancer la machine ?

A+

RE,

c'est ok.

comme quoi c'est toujours très bon d'avoir une autre approche des choses, de confronter....

Salut moutchec,

voilà le fichier avec les corrections demandées et améliorations diverses.

Suivre les instructions du post de hier, 18:22...

Petite nouveauté : dans la 'SORTIES' Sub Worksheet_SelectionChange(), après les lignes sous commentaire (voir instructions ci-dessus), se trouve un code destiné à créer une liste de validation "_ , C , P" en 'SORTIES' [K:K], histoire de faciliter l'encodage des "C,P" sans quitter la souris des mains. Ne pas effacer, évidemment... sauf si ça ne t'intéresse pas!

If Not Intersect(Target, Range("K:K")) Is Nothing Then
    With Selection.Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
        xlBetween, Formula1:="_,C,P"
        .IgnoreBlank = True
        .InCellDropdown = True
    End With
End If

Le caractère "_" représente le vide si tu veux éliminer le C ou P affiché.

A quoi sert le bouton rouge que tu as créé dans 'MVTS' ?

A+

7moutchec.xlsm (388.45 Ko)

RE,

le bouton rouge sert à exécuter ce code : (je m'exerce petit à petit en apprenant sur le forum)

For z = 2 To Sheets("DONNEES").Range("A" & Rows.Count).End(xlUp).Row

For y = 3 To Sheets("MVTS").Range("A" & Rows.Count).End(xlUp).Row

If CStr(Sheets("DONNEES").Range("A" & z)) = CStr(Sheets("MVTS").Range("B" & y)) Then

Sheets("MVTS").Range("A" & y) = Sheets("DONNEES").Range("B" & z)

End If

Next

Next

le résultat s'affiche en colonne A de la feuille MVTS = va chercher les désignations en solonne B de la feuille DONNEES selon correspondance des codes en colonnes A des feuilles MVTS et DONNEES.

je viens de tester et le résultat est Nickel, c'est vraiment du haut niveau.

je vous remercie très sincèrement.

Moutchec.

Salut moutchec,

le code de ton bouton!

'
Application.EnableEvents = False
Application.ScreenUpdating = False
'
With Worksheets("DONNEES")
    For x = 3 To Range("B" & Rows.Count).End(xlUp).Row Step 2
        For y = 2 To .Range("A" & Rows.Count).End(xlUp).Row
            If Cells(x, 2) = .Cells(y, 1) Then
                Cells(x, 1) = .Cells(y, 2)
                Exit For
            End If
        Next
    Next
End With
'
Application.EnableEvents = True
Application.ScreenUpdating = True
'

Et n'oublie pas...

A+

RE, je crois que je ne finirai pas de vous remercier.

avant de clôturer, je vous soumets une idée que je viens d'avoir :

je me disais qu'il n'était pas utile pour les codes d'aller chercher toutes les semaines sur les feuilles ENTREES et SORTIES, donc à chaque fois de la ligne 1 à x.

alors je me demandais s'il n'était pas possible que je saisisse un chiffre en D2 de la feuille MVTS et que les codes commencent par la première ligne ou ce chiffre est représenté.

exemple si je saisis 4 en D2, alors sur la feuille ENTREES, le code de la feuille commence à la ligne 4766 et sur la feuille SORTIES le code de la feuille commence à la ligne 953.

ainsi seules les semaines 4 et 5 seraient mises à jour, j'imagine que le résultat s'afficherait plus rapidement.

si c'est possible, je pense qu'en semaine 30, ça éviterait de recalculer inutilement les premières semaines de l'année .

je sais que je demande bcp pour le coup!!! dsl.

merci d'avance.

Moutchec.

Avec les autres demandes, ma nuit est faite !

Salut moutchec,

voici les changements demandés!

Tu as maintenant 2 boutons :

- le rouge pour la MAJ des résultats par semaine (code ci-dessous).

Tu es invité à encoder les n° de semaine souhaités séparés par un "/".

Quelques vérifications empêchent d'encoder n'importe quoi.

- l'autre pour la MAJ des noms de produits.

Application.ScreenUpdating = False
'
sRep = Application.InputBox("Quelles semaines souhaitez-vous mettre à jour ?", "MAJ", "1/2/3")
If sRep = "Faux" Or sRep = "" Then Exit Sub
tSplit = Split(sRep, "/")
'
On Error Resume Next
For x = 0 To UBound(tSplit)
    If IsNumeric(tSplit(x)) Then
        If CInt(tSplit(x)) >= 1 And CInt(tSplit(x)) <= Cells(2, Cells(2, Columns.Count).End(xlToLeft).Column) Then
            For y = 1 To 2
                lRow1 = 0
                lRow2 = 0
                With Worksheets(Choose(y, "ENTREES", "SORTIES"))
                    lRow1 = .Range("A:A").Find(what:=tSplit(x), lookat:=xlWhole, searchdirection:=xlNext).Row
                    lRow2 = .Range("A:A").Find(what:=tSplit(x), lookat:=xlWhole, searchdirection:=xlPrevious).Row
                    If lRow1 > 0 And lRow2 > 0 Then
                        If y = 1 Then
                            iRowA = Range("A" & Rows.Count).End(xlUp).Row
                            Cells(3, 4 + CInt(tSplit(x))).Resize(iRowA - 2) = ""
                        End If
                        For Z = lRow1 To lRow2
                            .Cells(Z, Choose(y, 6, 10)) = .Cells(Z, Choose(y, 6, 10)) + 0
                        Next
                    Else
                        MsgBox "Les données de la semaine " & tSplit(x) & " en '" & Choose(y, "ENTREES", "SORTIES") & " sont introuvables!", vbInformation + vbOKOnly, "MAJ - Info"
                    End If
                End With
            Next
        End If
    End If
Next
On Error GoTo 0
'
Application.ScreenUpdating = True

A tester maintenant en situation réelle!

A+

9moutchec.xlsm (405.15 Ko)

bonjour @Curulis57,

c'est incroyable ce que vous avez fait, soyez-en remerciééééééééééééé.

c'est au delà de tout ce que je pouvais espérer quand j'ai pensé à explorer la piste VBA, c'est tout simplement génial, parfait et GENTIL.

merci à vous et aux promoteurs de ce site.

bien à vous.

Moutchec.

Bonjour @curulis57

je reviens encore vous remercier pour votre travail sur ce fichier, j'ai testé dans tous les sens hier en remontant jusqu'en 2017, c'est très réussi. merci.

Moutchec.

Salut Moutchec,

très heureux de ce retour et d'apprendre que tout baigne!

Et merci à toi pour cette appréciation de mon travail très agréable à lire!

Bon travail!

A+

Rechercher des sujets similaires à "remplacement formules code vba"