Optimiser mon programme

bonjour à tous,

je début en VBA et j'ai un devoir à rendre, aucun soucis le travail n'est pas complexe.

Seulement quand je lance ma macro elle ne met pas moins de 9 min à se réaliser.

Voici mon code pour la question 1 se trouvant sur la droite de la feuille BasePro.

Avez-vous une solution pour que se code s'exécute plus rapidement ?

Je vous remercie !

32vba-project-1.zip (606.30 Ko)
Sub exo2()

    Dim seniority As Single, bonus As Single, taxe As Single, company As String, ttlsalary As Long, hire As Date, lasterow As Integer, rate As Single

    Sheets("BasePro").Select         'on selectionne la feuille que l'on veut traiter
    Range("A2").Select                    'on selectionne un case pour permettre de compter le nombre de ligne dans l'instruction suivante

    For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row  'on créer une boucle pour traiter le donnée de ligne en ligne (ligne = i)

        hire = Sheets("BasePro").Cells(i, 6).Value  'on détermine la date d'embauche

        seniority = Int((Date - hire) / 365.25)     'on calcul l'ancienneté
        Sheets("BasePro").Cells(i, 7).Value = seniority   'on renvoie la valeursur la feuille

        taxe = (Sheets("BasePro").Cells(i, 4).Value) * 0.2  'on calcul la taxe qui est de 20%
        Sheets("BasePro").Cells(i, 10).Value = taxe  'on renvoie la valeur dans la feuille

        Sheets("Param").Activate  'on active la feuille param pour aller chercher le rate en fonction de l'anciennete
        Range("Anciennete").Select     'on selection la range avecles donnée qui sont nécessaire

               For j = 0 To 10   'on créer une boucle pour trouver le bon rate en fonction de l'anciennete

                    If ActiveCell.Offset(1, 0).Value <= seniority Then   'si l'ancienneté de la case d'en-dessous est inférieur ou égale

                       ActiveCell.Offset(1, 0).Select   'alors on la selectionne

                    End If

                    rate = ActiveCell.Offset(0, 1).Value    'on defini notre rate qui est la case à droite de celle qui est selectionnée

                    salary = Sheets("BasePro").Cells(i, 4).Value   'on défini la variable salairequi est donné dans la feuille Base Pro
                    bonus = rate * salary    'on calcul le bonus

                    Sheets("BasePro").Cells(i, 8).Value = bonus     'on renvoie la valeur du bonus sur la feuille

                Next j    'fin de la deuxième boucle

    Next i     'fin de la première boucle

End Sub

Bonjour,

Je pense que vous faites fausse route

Il n'est absolument pas indiqué d'utiliser VBA pour faire les calculs, pour moi des formules doivent pour suffirent

Faudrait -il comprendre l'articulation du fichier

ahahah ça serait trop facile.

C'est mon code VBA qui sera examiné sur ce devoir

Bonjour,

S'agissant d'un devoir il est difficile de vous répondre sans connaître le stade actuel de l'apprentissage :

Il est facile d'accélérer ce code en utilisant les techniques appropriées, seulement cela trahirait immédiatement que ce n'est pas vous qui avez fait l'exo.

Sans vouloir porter de jugement de valeur sur ce que vous avez fait, il semble que vous n'ayez eu aucune base de programmation avancée : Seulement quelques notions de bases sur le déroulement d'un programme.

Pour répondre à votre question, il faudrait utiliser simultanément les notions suivantes.

  • Ne pas sélectionner les feuilles ni les plages à traiter (Pas de select ni d'offset)
  • Ne pas travailler sur les plages considérées mais sur des Array (Copie "valeur" des plages considérées)
  • Effectuer les calculs sur ces Array. (C'est à dire travailler en mémoire et non sur les feuilles)
  • Puis déverser in-fine le résultat de ces calculs sur la feuille traitée.

Durée total de ce processus : probablement quelques secondes (je n'ai pas essayé...)

Comme vous n'utilisez aucune de ces techniques on peut considérer qu'on ne vous en à jamais parlé.

De ce fait il est bien difficile d'améliorer la situation sauf à la marge :

Si on doit se contenter des connaissances de bases (A supposer qu'on vous en ait déjà parlé) vous devez :

Utiliser Option Explicit puis déclarer toutes les variables : Vous déclarez "lastrow" mais vous ne l'utilisez pas. Par contre vous utilisez "i" et "j" non déclarés...

Geler l'affichage écran (ScreenUpdating = False) pendant toute la durée de la macro.

Cette simple instruction devrait déjà réduire le temps de traitement de manière significative.

Ne pas utiliser Offset mais utiliser des variables.

Nota : La deuxième boucle For... Next ne sert à rien : Juste à faire 10 fois le même travail ("j" n'est jamais utilisé !) Seule la promenade avec des offset est réalisé ainsi que les calculs. C'est certain qu'au bout de 10 fois ça doit pas améliorer le temps de traitement !

D'ailleurs il est question à plusieurs reprise d'ActiveCell dans cette boucle sans qu'on sache réellement de quelles cellules on parle... Si vos calculs sont exact cela relève du miraculeux !

A+

Merci beaucoup pour ces pistes, je me penche dessus

rebonjour,

j'ai un nouveau code, qui est certe plus rapide mais ce n'est pas la folie non plus.

pourriez-vous me guidez une fois de plus svp.

Toujours pour la même question sur le même fichier

Sub tablo()

    ScreenUpdating = False

    Sheets("BasePro").Select
    Range("G2").Select
    Range(Selection, Selection.End(xlDown)).Select
    Range(Selection, Selection.End(xlToRight)).Select
    Selection.ClearContents

    Sheets("Param").Activate

    Dim Responsable(5) As String
    Dim RespActivity(5) As String
    Dim Anciennete(10) As Byte
    Dim Rate(10)
    Dim a As Integer
    Dim b As Integer

    For a = 0 To 5
        Responsable(a) = Range("A" & a + 2)
        MsgBox Responsable(a)
        RespActivity(a) = Range("B" & a + 2)
        MsgBox RespActivity(a)
    Next a

    For b = 0 To 10
        Anciennete(b) = Range("D" & b + 2)
        MsgBox Anciennete(b)
        Rate(b) = Range("E" & b + 2)
        MsgBox Rate(b)
    Next b

    'Définit le type de données pour le tableau.

    Dim Company() As String
    Dim Salary() As Variant
    Dim Hire() As Date
    Dim Seniority() As Byte
    Dim Bonus() As Variant
    Dim Activity() As String
    Dim Taxe() As Variant

    Dim i As Integer, j As Integer

    Sheets("BasePro").Activate
    i = (Cells(Rows.Count, 1).End(xlUp).Row) - 1
    'Définit la taille du tableau

    ReDim Company(i)
    ReDim Salary(i)
    ReDim Hire(i)
    ReDim Seniority(i)
    ReDim Bonus(i)
    ReDim Activity(i)
    ReDim Taxe(i)

    'Alimente les éléments du tableau
    For j = 1 To UBound(Company)

        Company(j) = Range("B" & j + 1)
        Salary(j) = Range("D" & j + 1)
        Hire(j) = Range("F" & j + 1).Value
        Seniority(j) = Int((Date - Hire(j)) / 365.25)

        For b = 0 To 10
            If Seniority(j) >= Anciennete(b) Then
                Bonus(j) = Rate(b)
            Else: Exit For
            End If
        Next b

        For a = 0 To 5
            If Company(j) = Responsable(a) Then
                Activity(j) = RespActivity(a)
                Exit For
            End If
        Next a

        Taxe(j) = Salary(j) * 0.2

        Range("G" & j + 1) = Seniority(j)
        Range("H" & j + 1) = Bonus(j)
            Range("H2:H" & j + 1).Select
            Selection.NumberFormat = "0.00%"
        Range("I" & j + 1) = Activity(j)
        Range("J" & j + 1) = Taxe(j)

    Next j

End Sub

Le gain de temps obtenu est du au ScreenUpdating, après l'essentiel serait de ne pas travailler sur des Activate, Select mais si o ne vous a pas appris à travailler sur des instances vous n'avez pas à vous en faire...

Les Dim se déclarent en principe en début de macro.

Je ne peux pas préjuger de la validité du programme : Je n'ai pas traité le sujet. Mais vous pouvez vérifier ces résultats avec les mêmes effectués avec des formules Excel.

Bonne continuation;

A+

Rechercher des sujets similaires à "optimiser mon programme"