Problème de performance au niveau d'affichage
Dernière réponse : dans Programmation
Bonjour,
J'ai créé une procédure pour calculer le tableau d'amortissement d'un prêt, le tableau peut prendre 240 lignes ou plus, ça me prend au mois 3 minutes au minimum, avez-vous une astuce qui permet d'accélérer l'affichage.
J'ai remarqué que ces lignes de code ci-dessous sont pénalisantes :
Sheets("Simul").Cells(k, 20) = Charges
Sheets("Simul").Cells(k, 21) = Interet
Sheets("Simul").Cells(k, 22) = Amort
Sheets("Simul").Cells(k, 24) = Crd
En vous remerciant d'avance.
KKV.
Voici le code complet :
EDIT MODO: voir messages suivants.
J'ai créé une procédure pour calculer le tableau d'amortissement d'un prêt, le tableau peut prendre 240 lignes ou plus, ça me prend au mois 3 minutes au minimum, avez-vous une astuce qui permet d'accélérer l'affichage.
J'ai remarqué que ces lignes de code ci-dessous sont pénalisantes :
Sheets("Simul").Cells(k, 20) = Charges
Sheets("Simul").Cells(k, 21) = Interet
Sheets("Simul").Cells(k, 22) = Amort
Sheets("Simul").Cells(k, 24) = Crd
En vous remerciant d'avance.
KKV.
Voici le code complet :
EDIT MODO: voir messages suivants.
Autres pages sur : probleme performance niveau affichage
Lassé par la pub ? Créez un compte
[/cpp]
http://site.voila.fr/zulu-echo-bravo/img/balisecodeppc.png
Début de l'année ou pas, le zeb ne connait pas la pitié...
EDIT: Dépêche-toi: je l'entend qui rôde...
--------------------------------------------------------------------------------------------------
OK, mille excuses
c'est mon premier message du genre.
j'espère que ça ira comme ça.
KKV
Storos a dit :
Si tu n'édites pas très rapidement ton message pour mettre le code entre balises (conformément aux règles de la rubrique), tu risques de t'attirer les foudres du zeb.http://site.voila.fr/zulu-echo-bravo/img/balisecodeppc.png
Début de l'année ou pas, le zeb ne connait pas la pitié...
EDIT: Dépêche-toi: je l'entend qui rôde...
--------------------------------------------------------------------------------------------------
OK, mille excuses
c'est mon premier message du genre.
j'espère que ça ira comme ça.
KKV
Sub Tableau_std(Typ)
Application.ScreenUpdating = False
Sheets("Simul" ).Activate
'' ------------------------------------
'' Edition du Tableau d'amortissement -
'' ------------------------------------
Dim i As Integer, j As Integer, k As Integer, lig As Integer
Dim Tne(1 To 35) As Integer, Tper(1 To 35) As Integer, Tpal(1 To 35) As Integer, Tpi(1 To 35) As Integer
Dim Ttaux(1 To 35) As Double, Tcha(1 To 35) As Double, Ttpg(1 To 35) As Double, Tsd(1 To 35) As Double
Dim l As Integer, p As Integer
Dim Interet As Double, Amort As Double, Crd As Double, Interetp As Double, Charges As Double, Tp As Double
Dim infra As Integer
Dim nbi As Integer, Nbj As Integer, Ne As Integer, Nepal As Integer, cdam As Integer, Mki As Integer
Dim D1 As Long, D2 As Long
Dim TauxFilys As Long
Dim Nbechpal As Integer
l = 0
k = 0
Ne = 0
Nepal = 0
cdam = Sheets("Simul" ).Cells(2, 9)
Mki = Sheets("Simul" ).Cells(3, 9)
TauxFilys = Sheets("Simul" ).Cells(7, 6)
Select Case cdam
Case 0
Sheets("Simul" ).Cells(4, 19) = "Amortissement variable, durée figée"
Case 1
Sheets("Simul" ).Cells(4, 19) = "Amortissement figé"
Case 2
Sheets("Simul" ).Cells(4, 19) = "Amortissement constant"
Case 3
Sheets("Simul" ).Cells(4, 19) = "Amortissement variable, durée variable"
Case 4
Sheets("Simul" ).Cells(4, 19) = "Amortissement empilé"
End Select
Select Case Mki
Case 0
Sheets("Simul" ).Cells(5, 19) = "mois de 30j"
Case 1
Sheets("Simul" ).Cells(5, 19) = "Nbj réels/360"
Case 2
Sheets("Simul" ).Cells(5, 19) = "Nbj réels/365"
End Select
recupD l, Tne(), Tper(), Tcha(), Ttaux(), Ttpg(), Tsd(), Tpal(), Tpi()
'
' calcul du taux périodique et alimentation des charges
' -----------------------------------------------------
Sheets("Simul" ).Cells(2, 4) = l
nbpal = l
lig = 8
Crd = Tsd(1)
infra = 1
For i = 1 To nbpal
Nbechpal = Tne(i) * Tper(i) / Tpi(i)
Nepal = 0
For j = 1 To Tne(i)
k = lig + (j * infra) - (infra - 1)
infra = Tper(i) / Tpi(i)
Select Case infra
Case 1
Interet = Crd * Ttaux(i) * Tper(i) / 1200
Amort = Tcha(i) - Interet '-- Amort est tjs calculé sur le mois de 30j
'-- ensuite on calcule les intérêts selon le mode demandé
If Tpal(i) = 1 Then Amort = 0
If Mki > 0 Then GoSub CalInt
Charges = Amort + Interet
Ne = Ne + 1
Nepal = Nepal + 1
GoSub AffLigne
Crd = Crd - Amort
Case Else
'
'--- Là on calcule les intérêts intermédiares
'____________________________________________
nbi = 1
Do While nbi < infra
Interet = Crd * Ttaux(i) * Tpi(i) / 1200
If Mki > 0 Then GoSub CalInt
Charges = Interet
Amort = 0
Ne = Ne + 1
Nepal = Nepal + 1
GoSub AffLigne
nbi = nbi + 1
k = k + 1
Loop
'-- Là on calcule les derniers intérêts de l'échéance
'____________________________________________________
Interet = Crd * Ttaux(i) * Tper(i) / 1200
Amort = Tcha(i) - Interet
If Tpal(i) = 1 Then Amort = 0
Interet = Crd * Ttaux(i) * Tpi(i) / 1200
If Mki > 0 Then GoSub CalInt
Charges = Amort + Interet
Ne = Ne + 1
Nepal = Nepal + 1
GoSub AffLigne
Crd = Crd - Amort
End Select
Next j
lig = k ' en cas de changement de paliers
Next i
Range(Cells(k + 1, 20), Cells(428, 26)).ClearContents
Application.ScreenUpdating = True
' Range("P9" ).Select
'Range("P9" ).Show
Exit Sub
'----fonction commune de calcul des intérêts
'____________________________________________
CalInt:
Select Case k
Case 9 ' 1° éché --> nbj par rapport au Pt-dep
D2 = Sheets("Simul" ).Cells(k, 19)
D1 = Sheets("Simul" ).Cells(6, 4)
Nbj = D2 - D1
Case Else
p = k - 1
D1 = Sheets("Simul" ).Cells(p, 19)
D2 = Sheets("Simul" ).Cells(k, 19)
Nbj = D2 - D1
End Select
Select Case Mki
Case 1 '--- nbj réels sur 360j
If Typ = 0 Then
Interet = Crd * Ttaux(i) * Nbj / 36000
Else
Interet = Crd * TauxFilys * Nbj / 36000 'Typ = 1 : profilys
End If
Case 2 '--- nbj réels sur 365j
If Typ = 0 Then
Interet = Crd * Ttaux(i) * Nbj / 36500
Else
Interet = Crd * TauxFilys * Nbj / 36500 ' Typ = 1 : profilys
End If
End Select
Return
' Affiche de la ligne calculée
'_____________________________
AffLigne:
Select Case Typ
Case 1
Sheets("Simul" ).Cells(k, 23) = TauxFilys
Case Else
Sheets("Simul" ).Cells(k, 23) = Ttaux(i)
End Select
Select Case Mki
Case 1, 2
Sheets("Simul" ).Cells(k, 17) = Nbj
Case Else
Nbj = Tpi(i) * 30
Sheets("Simul" ).Cells(k, 17) = Nbj
End Select
If Nepal < Nbechpal Then
Sheets("Simul" ).Cells((k + 1), 25) = Tpi(i)
Else
Sheets("Simul" ).Cells((k + 1), 25) = Tpi(i + 1)
End If
Return
End Sub
Bon, alors mon cher KKV, j'ai sans doute une solution pour toi. Il y a des choses que tu fais trop de fois, inutilement. C'est pourquoi on peut accélérer les choses.
Par contre, comme ton code n'est pas indenté, on ne voit pas où son les boucles, les tests, etc. Donc un peu de présentation s'impose. Bien présenter son code, c'est aussi facilement le relire pour y trouver des erreurs, des bugs, voire des améliorations à apporter (tiens, justement, ça nous concerne).
De plus, nous sommes en 2010. Je te prie donc de faire deux fonctions de CalInt et de AffLigne. Je ne veux plus voir de GOSUB (de quoi i' s'mêle, ç'ui-ci).
Par ailleurs, tu as un goût très prononcé pour les Select / Case. C'est parfois très élégant, mais c'est surtout très lourd quand il n'y a qu'une condition.
Considère ces quelques remarques comme des critiques objectives et constructives, puisque tout à l'heure, ton code sera beau et efficace, c'est une promesse
Par contre, comme ton code n'est pas indenté, on ne voit pas où son les boucles, les tests, etc. Donc un peu de présentation s'impose. Bien présenter son code, c'est aussi facilement le relire pour y trouver des erreurs, des bugs, voire des améliorations à apporter (tiens, justement, ça nous concerne).
De plus, nous sommes en 2010. Je te prie donc de faire deux fonctions de CalInt et de AffLigne. Je ne veux plus voir de GOSUB (de quoi i' s'mêle, ç'ui-ci).
Par ailleurs, tu as un goût très prononcé pour les Select / Case. C'est parfois très élégant, mais c'est surtout très lourd quand il n'y a qu'une condition.
Considère ces quelques remarques comme des critiques objectives et constructives, puisque tout à l'heure, ton code sera beau et efficace, c'est une promesse
Bonjour,
Merci pour toutes vos remarques.
Normalement les codes sont bien indentés, mais les espaces sont perdus après le collage pour un pb de police je suppose.
J'ai fait des modifications pour supprimer les GOSUB et optimisé le code autant que faire se peut mais le temps d'éxecution reste rhédibitoire.
J'ai fait des essais en supprimant les instructions d'affichage(ayant des impacts sur les cellules) et en les remplaçant par les instructions de remplissage des tableaux, le résultat est excellent, peut-on dire que les instructions d'adressage aux cellules sont pénalisantes?
Exemple : Sheets("Simul").Cells(k, 20) = Charge
Là, je vous envoie le code revu et corrigé avec indentation pour une meilleure lecture.
KKV
-----------------------------------------------------------------------------------------
Merci pour toutes vos remarques.
Normalement les codes sont bien indentés, mais les espaces sont perdus après le collage pour un pb de police je suppose.
J'ai fait des modifications pour supprimer les GOSUB et optimisé le code autant que faire se peut mais le temps d'éxecution reste rhédibitoire.
J'ai fait des essais en supprimant les instructions d'affichage(ayant des impacts sur les cellules) et en les remplaçant par les instructions de remplissage des tableaux, le résultat est excellent, peut-on dire que les instructions d'adressage aux cellules sont pénalisantes?
Exemple : Sheets("Simul").Cells(k, 20) = Charge
Là, je vous envoie le code revu et corrigé avec indentation pour une meilleure lecture.
KKV
-----------------------------------------------------------------------------------------
Sub Tableau_std(typ) Application.ScreenUpdating = False Sheets("Simul").Activate '' ------------------------------------ '' Edition du Tableau d'amortissement - '' ------------------------------------ Dim i As Integer, j As Integer, k As Integer, lig As Integer, deno As Integer Dim Taux As Double k = 0 Ne = 0 Nepal = 0 cdam = Sheets("Simul").Cells(2, 9) Mki = Sheets("Simul").Cells(3, 9) TauxFilys = Sheets("Simul").Cells(7, 6) Select Case cdam Case 0 Sheets("Simul").Cells(4, 19) = "Amortissement variable, durée figée" Case 1 Sheets("Simul").Cells(4, 19) = "Amortissement figé" Case 2 Sheets("Simul").Cells(4, 19) = "Amortissement constant" Case 3 Sheets("Simul").Cells(4, 19) = "Amortissement variable, durée variable" Case 4 Sheets("Simul").Cells(4, 19) = "Amortissement empilé" End Select Select Case Mki Case 0 Sheets("Simul").Cells(5, 19) = "mois de 30j" deno = 360 Case 1 Sheets("Simul").Cells(5, 19) = "Nbj réels/360" deno = 360 Case 2 Sheets("Simul").Cells(5, 19) = "Nbj réels/365" deno = 365 End Select recupD l, Tne(), Tper(), Tcha(), Ttaux(), Ttpg(), Tsd(), Tpal(), Tpi() ' ' calcul du taux périodique et alimentation des Charge ' ----------------------------------------------------- Sheets("Simul").Cells(2, 4) = l nbpal = l lig = 8 Crd = Tsd(1) infra = 1 For i = 1 To nbpal Nbechpal = Tne(i) * Tper(i) / Tpi(i) Nepal = 0 If typ = 0 Then Taux = Ttaux(i) Else Taux = TauxFilys End If If Mki = 0 Then Nbj = Tpi(i) * 30 For j = 1 To Tne(i) k = lig + (j * infra) - (infra - 1) infra = Tper(i) / Tpi(i) If infra = 1 Then Interet = Crd * Ttaux(i) * Tper(i) / 1200 Amort = Tcha(i) - Interet '-- Amort est tjs calculé sur le mois de 30j '-- ensuite on calcule les intérêts selon le mode demandé If Tpal(i) = 1 Then Amort = 0 If Mki > 0 Then CalInt k, p, deno, Taux Charge = Amort + Interet Ne = Ne + 1 Nepal = Nepal + 1 AffLigne i, k, Taux, Ne Crd = Crd - Amort Else ' '--- Là on calcule les intérêts intermédiares '____________________________________________ nbi = 1 Do While nbi < infra Interet = Crd * Ttaux(i) * Tpi(i) / 1200 If Mki > 0 Then CalInt k, p, deno, Taux Charge = Interet Amort = 0 Ne = Ne + 1 Nepal = Nepal + 1 AffLigne i, k, Taux, Ne nbi = nbi + 1 k = k + 1 Loop '-- Là on calcule les derniers intérêts de l'échéance '____________________________________________________ Interet = Crd * Ttaux(i) * Tper(i) / 1200 Amort = Tcha(i) - Interet If Tpal(i) = 1 Then Amort = 0 Interet = Crd * Ttaux(i) * Tpi(i) / 1200 If Mki > 0 Then CalInt k, p, deno, Taux Charge = Amort + Interet Ne = Ne + 1 Nepal = Nepal + 1 AffLigne i, k, Taux, Ne Crd = Crd - Amort End If Next j lig = k ' en cas de changement de paliers Next Range(Cells(k + 1, 20), Cells(428, 26)).ClearContents Application.ScreenUpdating = True End Sub
' ' Affichage de la ligne ' ----------------------- Sub AffLigne(i, k, Taux, Ne) Sheets("Simul").Cells(k, 20) = Charge Sheets("Simul").Cells(k, 21) = Interet Sheets("Simul").Cells(k, 22) = Amort Sheets("Simul").Cells(k, 24) = Crd Sheets("Simul").Cells(k, 23) = Taux Sheets("Simul").Cells(k, 17) = Nbj If Nepal < Nbechpal Then Sheets("Simul").Cells((k + 1), 25) = Tpi(i) Else Sheets("Simul").Cells((k + 1), 25) = Tpi(i + 1) End If End Sub
'----fonction commune de calcul des intérêts '____________________________________________ Sub CalInt(k, p, deno, Taux) If k = 9 Then D2 = Sheets("Simul").Cells(k, 19) D1 = Sheets("Simul").Cells(6, 4) Nbj = D2 - D1 Else p = k - 1 D1 = Sheets("Simul").Cells(p, 19) D2 = Sheets("Simul").Cells(k, 19) Nbj = D2 - D1 End If Interet = Crd * Taux * Nbj / deno End Sub
Ah !!! Là, c'est super beau. En plus, j'ai séparé tes différentes fonctions, pour faire encore plus beau.
Maintenant, on voit bien qu'il y a deux boucles For et une boucle While imbriquées. C'est là qu'il faut chercher. Et qu'est-ce qu'on y trouve d'un peu compliqué ? Pas grand' chose, sinon l'appel à tes deux fonctions.
Il y a donc un calcul très compliqué qui se fait dans ces fonctions.
Bon, comme je lorgne un peu dessus, je m'aperçois de vilaines choses. Les variables en entrée ne sont pas toutes données en paramètre, et pour le cas de CalInt, le résultat est lui aussi envoyé dans une variable globale. Spa bien du tout
Bon venons-en à ce qui est si difficile à calculer par Excel !
Ça ne peut pas être l'affichage puisque tu utilises ScreenUpdating.
C'est donc tout bêtement Sheets("Simul").
Sheets est la collection de tous les onglets, feuilles et graphiques pêle-mêle. Un bon moyen de simplifier les choses est donc de désigner explicitement les feuilles de calcul. On utilise alors la collection Worksheets. Bien.
Maintenant, dans cette collection, on recherche celle dont le nom est Simul. Pour améliorer ça, on peut utiliser le numéro de la feuille plutôt que son nom. Dans ce cas, il n'y a plus de recherche, l'accès est direct. C'est tout.
Enfin, non, pas tout à fait. J'ai une préconisation à faire. Déclare une variable de type Worksheet, affecte lui une bonne fois pour toute la bonne feuille, et réutilise la partout.
Je réécris tout :
Ajoute la ligne Option Explicit au début de ton code.
C'est indispensable dès qu'on écrit plus de dix lignes de code.
Tu définis k comme un entier. Or k est le numéro de la ligne.
Une feuille Excel contient 65536 lignes.
Or un entier (integer) est définit de -32768 à 32767. Ca ne tient pas.
Il faut donc utiliser un entien long.
Je définis donc k comme un entien long (Long).
Je te prie de te poser la question pour TOUTES tes variables.
A quoi sert Ne ?
A quoi servent nbpal et l ? L'un des deux suffit.
Qu'en dis-tu ?
Que l'on peut faire mieux ? Oh, oui.
J'ai viré la boucle While pour un joli For. C'est quand même plus propre (Le calcul de borne n'est fait qu'une fois, comme ça).
Bon, maintenant, regardons les informations passées aux fonctions. Pas la peine de tant en donner. On peut simplifier.
Dans AffLigne, rien que pour l'affichage de la ligne 25, il faut donner i, Nepal, Nbechpal et tout le tableau Tpi !
Dans CalculInteret, on passe trois valeurs qui font toujours l'objet du même calcul.
Les appels deviennent :
Allez, soyons fou :
_______________________________________
Maintenant, on voit bien qu'il y a deux boucles For et une boucle While imbriquées. C'est là qu'il faut chercher. Et qu'est-ce qu'on y trouve d'un peu compliqué ? Pas grand' chose, sinon l'appel à tes deux fonctions.
Il y a donc un calcul très compliqué qui se fait dans ces fonctions.
Bon, comme je lorgne un peu dessus, je m'aperçois de vilaines choses. Les variables en entrée ne sont pas toutes données en paramètre, et pour le cas de CalInt, le résultat est lui aussi envoyé dans une variable globale. Spa bien du tout
Bon venons-en à ce qui est si difficile à calculer par Excel !
Ça ne peut pas être l'affichage puisque tu utilises ScreenUpdating.
C'est donc tout bêtement Sheets("Simul").
Sheets est la collection de tous les onglets, feuilles et graphiques pêle-mêle. Un bon moyen de simplifier les choses est donc de désigner explicitement les feuilles de calcul. On utilise alors la collection Worksheets. Bien.
Maintenant, dans cette collection, on recherche celle dont le nom est Simul. Pour améliorer ça, on peut utiliser le numéro de la feuille plutôt que son nom. Dans ce cas, il n'y a plus de recherche, l'accès est direct. C'est tout.
Enfin, non, pas tout à fait. J'ai une préconisation à faire. Déclare une variable de type Worksheet, affecte lui une bonne fois pour toute la bonne feuille, et réutilise la partout.
Je réécris tout :
Option Explicit
Sub Tableau_std(typ) Application.ScreenUpdating = False Dim ws_simul As Worksheet Set ws_simul = Worksheets("Simul") ' // ' ------------------------------------ ' // ' Edition du Tableau d'amortissement - ' // ' ------------------------------------ Dim i As Integer, j As Integer, lig As Integer, deno As Integer Dim Taux As Double Dim Tne(1 To 35) As Integer, Tper(1 To 35) As Integer, Tpal(1 To 35) As Integer, Tpi(1 To 35) As Integer Dim Ttaux(1 To 35) As Double, Tcha(1 To 35) As Double, Ttpg(1 To 35) As Double, Tsd(1 To 35) As Double Dim k As Long Dim Ne As Dim Nepal As Dim cdam As Dim Mki As Dim TauxFilys As Dim l As Dim nbpal As Dim Crd As Dim infra As Dim Nbechpal As Dim Nbj As Dim Interet As Dim Amort As Dim Charge As Dim nbi As k = 0 Ne = 0 Nepal = 0 cdam = ws_simul.Cells(2, 9).Value Mki = ws_simul.Cells(3, 9).Value TauxFilys = ws_simul.Cells(7, 6).Value Select Case cdam Case 0: ws_simul.Cells(4, 19).Value = "Amortissement variable, durée figée" Case 1: ws_simul.Cells(4, 19).Value = "Amortissement figé" Case 2: ws_simul.Cells(4, 19).Value = "Amortissement constant" Case 3: ws_simul.Cells(4, 19).Value = "Amortissement variable, durée variable" Case 4: ws_simul.Cells(4, 19).Value = "Amortissement empilé" End Select Select Case Mki Case 0 ws_simul.Cells(5, 19).Value = "mois de 30j" deno = 360 Case 1 ws_simul.Cells(5, 19).Value = "Nbj réels/360" deno = 360 Case 2 ws_simul.Cells(5, 19).Value = "Nbj réels/365" deno = 365 Case Else Err.Raise vbObjectError + 1000, , "Erreur interne" End Select recupD l, Tne(), Tper(), Tcha(), Ttaux(), Ttpg(), Tsd(), Tpal(), Tpi() ' // ' // calcul du taux périodique et alimentation des Charge ' // ----------------------------------------------------- ws_simul.Cells(2, 4).Value = l nbpal = l lig = 8 Crd = Tsd(1) infra = 1 For i = 1 To nbpal Nbechpal = Tne(i) * Tper(i) / Tpi(i) Nepal = 0 If typ = 0 Then Taux = Ttaux(i) Else Taux = TauxFilys End If If Mki = 0 Then Nbj = Tpi(i) * 30 For j = 1 To Tne(i) k = lig + (j * infra) - (infra - 1) infra = Tper(i) / Tpi(i) If infra = 1 Then Interet = Crd * Ttaux(i) * Tper(i) / 1200 Amort = Tcha(i) - Interet ' // -- Amort est tjs calculé sur le mois de 30j ' // -- ensuite on calcule les intérêts selon le mode demandé If Tpal(i) = 1 Then Amort = 0 If Mki > 0 Then Interet = CalculInteret(ws_simul, k, deno, Taux, Crd) Charge = Amort + Interet Ne = Ne + 1 Nepal = Nepal + 1 AffLigne ws_simul, i, k, Tpi, Nepal, Nbechpal, Charge, Interet, Amort, Crd, Taux, Nbj Crd = Crd - Amort Else ' // ' // --- Là on calcule les intérêts intermédiares ' // ____________________________________________ For nbi = 1 To infra - 1 Interet = Crd * Ttaux(i) * Tpi(i) / 1200 If Mki > 0 Then Interet = CalculInteret(ws_simul, k, deno, Taux, Crd) Charge = Interet Amort = 0 Ne = Ne + 1 Nepal = Nepal + 1 AffLigne ws_simul, i, k, Tpi, Nepal, Nbechpal, Charge, Interet, Amort, Crd, Taux, Nbj k = k + 1 Next ' // -- Là on calcule les derniers intérêts de l'échéance ' //____________________________________________________ Interet = Crd * Ttaux(i) * Tper(i) / 1200 Amort = Tcha(i) - Interet If Tpal(i) = 1 Then Amort = 0 Interet = Crd * Ttaux(i) * Tpi(i) / 1200 If Mki > 0 Then Interet = CalculInteret(ws_simul, k, deno, Taux, Crd) Charge = Amort + Interet Ne = Ne + 1 Nepal = Nepal + 1 AffLigne ws_simul, i, k, Tpi, Nepal, Nbechpal, Charge, Interet, Amort, Crd, Taux, Nbj Crd = Crd - Amort End If Next j lig = k '// en cas de changement de paliers Next Range(Cells(k + 1, 20), Cells(428, 26)).ClearContents Application.ScreenUpdating = True End Sub
' // Affichage de la ligne ' // ----------------------- Sub AffLigne(ws As Worksheet, i As Integer, k As Long, Tpi (1 To 35) As Integer, Nepal As, Nbechpal As , Charge As , Interet As , Amort As , Crd As , Taux As Double, Nbj As ) ws.Cells(k, 20).Value = Charge ws.Cells(k, 21).Value = Interet ws.Cells(k, 22).Value = Amort ws.Cells(k, 24).Value = Crd ws.Cells(k, 23).Value = Taux ws.Cells(k, 17).Value = Nbj If Nepal >= Nbechpal Then i = i + 1 ws.Cells((k + 1), 25).Value = Tpi(i) End Function
' // ----fonction commune de calcul des intérêts ' // ____________________________________________ Function CalculInteret(ws As Worksheet, k As Long, deno As , Taux As Double, Crd As ) As Double Dim D1 As Integer Dim D2 As Integer If k = 9 Then D1 = ws.Cells(6, 4).Value Else D1 = ws.Cells(k - 1, 19).Value End If D2 = ws.Cells(k, 19).Value CalculInteret = Crd * Taux * (D2 - D1) / deno End Function
Ajoute la ligne Option Explicit au début de ton code.
C'est indispensable dès qu'on écrit plus de dix lignes de code.
Tu définis k comme un entier. Or k est le numéro de la ligne.
Une feuille Excel contient 65536 lignes.
Or un entier (integer) est définit de -32768 à 32767. Ca ne tient pas.
Il faut donc utiliser un entien long.
Je définis donc k comme un entien long (Long).
Je te prie de te poser la question pour TOUTES tes variables.
A quoi sert Ne ?
A quoi servent nbpal et l ? L'un des deux suffit.
Qu'en dis-tu ?
Que l'on peut faire mieux ? Oh, oui.
J'ai viré la boucle While pour un joli For. C'est quand même plus propre (Le calcul de borne n'est fait qu'une fois, comme ça).
Bon, maintenant, regardons les informations passées aux fonctions. Pas la peine de tant en donner. On peut simplifier.
Dans AffLigne, rien que pour l'affichage de la ligne 25, il faut donner i, Nepal, Nbechpal et tout le tableau Tpi !
Dans CalculInteret, on passe trois valeurs qui font toujours l'objet du même calcul.
' // Affichage de la ligne ' // ----------------------- Sub AffLigne(ws As Worksheet, k As Long, pi As Integer, Charge As , Interet As , Amort As , Crd As , Taux As Double, Nbj As ) ws.Cells(k, 20).Value = Charge ws.Cells(k, 21).Value = Interet ws.Cells(k, 22).Value = Amort ws.Cells(k, 24).Value = Crd ws.Cells(k, 23).Value = Taux ws.Cells(k, 17).Value = Nbj ws.Cells((k + 1), 25).Value = pi End Function
' // ----fonction commune de calcul des intérêts ' // ____________________________________________ Function CalculInteret(ws As Worksheet, k As Long, Val As Double) As Double Dim D As Integer If k = 9 Then D = ws.Cells(6, 4).Value Else D = ws.Cells(k - 1, 19).Value End If CalculInteret = Val * (ws.Cells(k, 19).Value - D) End Function
Les appels deviennent :
Dim x As Integer x = Iff(Nepal >= Nbechpal, 1, 0) AffLigne ws_simul, k, Tpi(i + x), Charge, Interet, Amort, Crd, Taux, Nbj ' // ou en une ligne AffLigne ws_simul, k, Tpi(i + Iff(Nepal >= Nbechpal, 1, 0)), Charge, Interet, Amort, Crd, Taux, Nbj
CalculInteret(ws_simul, k, Crd * Taux / deno)
Allez, soyons fou :
' // ----fonction commune de calcul des intérêts ' // ____________________________________________ Function CalculInteret(ws As Worksheet, k As Long, Val As Double) As Double CalculInteret = Val * (ws.Cells(k, 19).Value - ws.Cells(IIf(k = 9, 6, k - 1), IIf(k = 9, 4, 19)).Value) End Function
_______________________________________
Ça devrait dépoter, maintenant
Bonjour,
Merci pour ton aide, tes codes sont excellents, c'est formateur.
J'ai intégré tes corrections et ça me fait gagner 5 secondes par rapport à l'ancienne version, chrono en main.
C'est un peu maigre....mais c'est déjà çà de pris.
KKV
--------------------------------------------------------------------------------------------------
Voici le nouveau code :
[fixed]Sub Tableau_std(typ)
Application.ScreenUpdating = False
'' ------------------------------------
'' Edition du Tableau d'amortissement -
'' ------------------------------------
Dim i As Integer, j As Integer, k As Long, lig As Integer, deno As Integer
Dim Taux As Double
Dim x As Integer
Set ws_simul = Sheets("Simul")
k = 0
Nepal = 0
cdam = ws_simul.Cells(2, 9)
Mki = ws_simul.Cells(3, 9)
TauxFilys = ws_simul.Cells(7, 6)
Select Case cdam
Case 0
ws_simul.Cells(4, 19).Value = "Amortissement variable, durée figée"
Case 1
ws_simul.Cells(4, 19).Value = "Amortissement figé"
Case 2
ws_simul.Cells(4, 19).Value = "Amortissement constant"
Case 3
ws_simul.Cells(4, 19).Value = "Amortissement variable, durée variable"
Case 4
ws_simul.Cells(4, 19).Value = "Amortissement empilé"
End Select
Select Case Mki
Case 0
ws_simul.Cells(5, 19).Value = "mois de 30j"
deno = 360
Case 1
ws_simul.Cells(5, 19).Value = "Nbj réels/360"
deno = 360
Case 2
ws_simul.Cells(5, 19).Value = "Nbj réels/365"
deno = 365
Case Else
'Err.Raise vbOjectError + 1000, , "Erreur interne"
End Select
recupD l, Tne(), Tper(), Tcha(), Ttaux(), Ttpg(), Tsd(), Tpal(), Tpi()
'
' calcul du taux périodique et alimentation des Charge
' -----------------------------------------------------
ws_simul.Cells(2, 4).Value = l
nbpal = l
lig = 8
Crd = Tsd(1)
infra = 1
Ne = 0 'attention cette rubrique est utilisée dans RecupD
For i = 1 To nbpal
Nbechpal = Tne(i) * Tper(i) / Tpi(i)
Nepal = 0
If typ = 0 Then
Taux = Ttaux(i)
Else
Taux = TauxFilys
End If
If Mki = 0 Then Nbj = Tpi(i) * 30
For j = 1 To Tne(i)
k = lig + (j * infra) - (infra - 1)
infra = Tper(i) / Tpi(i)
If infra = 1 Then
Interet = Crd * Ttaux(i) * Tper(i) / 1200
Amort = Tcha(i) - Interet '-- Amort est tjs calculé sur le mois de 30j
'-- ensuite on calcule les intérêts selon le mode demandé
If Tpal(i) = 1 Then Amort = 0
If Mki > 0 Then Interet = CalculInteret(ws_simul, k, Crd * Taux / deno)
Charge = Amort + Interet
Ne = Ne + 1
Nepal = Nepal + 1
x = IIf(Nepal >= Nbechpal, 1, 0)
AffLigne ws_simul, k, Tpi(i + x), Charge, Interet, Amort, Crd, Taux, Nbj
Crd = Crd - Amort
Else
'
'--- Là on calcule les intérêts intermédiares
'____________________________________________
nbi = 1
For nbi = 1 To infra - 1
Interet = Crd * Ttaux(i) * Tpi(i) / 1200
If Mki > 0 Then Interet = CalculInteret(ws_simul, k, Crd * Taux / deno)
Charge = Interet
Amort = 0
Ne = Ne + 1
Nepal = Nepal + 1
x = IIf(Nepal >= Nbechpal, 1, 0)
AffLigne ws_simul, k, Tpi(i + x), Charge, Interet, Amort, Crd, Taux, Nbj
nbi = nbi + 1
k = k + 1
Next
'-- Là on calcule les derniers intérêts de l'échéance
'____________________________________________________
Interet = Crd * Ttaux(i) * Tper(i) / 1200
Amort = Tcha(i) - Interet
If Tpal(i) = 1 Then Amort = 0
Interet = Crd * Ttaux(i) * Tpi(i) / 1200
If Mki > 0 Then Interet = CalculInteret(ws_simul, k, Crd * Taux / deno)
Charge = Amort + Interet
Ne = Ne + 1
Nepal = Nepal + 1
x = IIf(Nepal >= Nbechpal, 1, 0)
AffLigne ws_simul, k, Tpi(i + x), Charge, Interet, Amort, Crd, Taux, Nbj
Crd = Crd - Amort
End If
Next j
lig = k ' en cas de changement de paliers
Next i
Range(Cells(k + 1, 20), Cells(428, 26)).ClearContents
Application.ScreenUpdating = True
' Range("P9").Select
'Range("P9").Show
End Sub
'
' Affichage de la ligne
' -----------------------
Function AffLigne(ws As Worksheet, k As Long, pi As Integer, Charge As Double, Interet As Double, Amort As Double, Crd As Double, Taux As Double, Nbj As Integer)
Set ws = Sheets("Simul")
ws.Cells(k, 20).Value = Charge
ws.Cells(k, 21).Value = Interet
ws.Cells(k, 22).Value = Amort
ws.Cells(k, 24).Value = Crd
ws.Cells(k, 23).Value = Taux
ws.Cells(k, 17).Value = Nbj
ws.Cells((k + 1), 25).Value = pi
End Function
'----fonction commune de calcul des intérêts
'____________________________________________
Function CalculInteret(ws As Worksheet, k As Long, Val As Double) As Double
Dim D1 As Long, D2 As Long
Set ws = Sheets("Simul")
If k = 9 Then
D1 = ws.Cells(6, 4).Value
Else
D1 = ws.Cells(k - 1, 19).Value
End If
D2 = ws.Cells(k, 19).Value
Nbj = D2 - D1
CalculInteret = Val * Nbj / 100
End Function[/fixed]
M'enfin kkv, que fais-tu lignes 159 et 175 ?
Tu me remets du Sheets(<nom de feuille>) dans tes sous-fonctions !!!
C'est justement ce qu'on cherchait à éviter.
Le pointeur sur la feuille est déjà donné par le premier paramètre (ws). Quel besoin as-tu eu de les recalculer ?
Il va falloir te (faire) offrir un bouquin et/ou une formation sur la programmation moderne (post-1980). Oublier définitivement les GOTO et autres GOSUB, pour apprendre et comprendre le principe des fonctions et de leurs paramètres.
En étudiant de nouveau un peu ce que je te proposais, cela devrait te paraître évident.
________________________________________
Tiens, petit exercice pour bien comprendre :
(Mettre le curseur sur la ligne Effe5 et appuyer sur [F5] )
Tu me remets du Sheets(<nom de feuille>) dans tes sous-fonctions !!!
C'est justement ce qu'on cherchait à éviter.
Le pointeur sur la feuille est déjà donné par le premier paramètre (ws). Quel besoin as-tu eu de les recalculer ?
Il va falloir te (faire) offrir un bouquin et/ou une formation sur la programmation moderne (post-1980). Oublier définitivement les GOTO et autres GOSUB, pour apprendre et comprendre le principe des fonctions et de leurs paramètres.
En étudiant de nouveau un peu ce que je te proposais, cela devrait te paraître évident.
________________________________________
Tiens, petit exercice pour bien comprendre :
Sub traitement_feuille(f As Worksheet) MsgBox "Je suis bien la feuille n°" & f.Index & " et je m'appelle " & f.Name End Sub
Sub Effe5 Dim feuille As Worksheet For Each feuille in Worksheets MsgBox "Traitement de la feuille n°" & feuille.Index traitement_feuille feuille Next End Sub
(Mettre le curseur sur la ligne Effe5 et appuyer sur [F5] )
Eh, je t'ai demandé d'utiliser Option Explicit et de définir toutes tes variables.
Mais puisque je me suis cassé le cul à lire, relire, étudier, résoudre et réécrire entièrement ton code, tu pourrais avoir la politesse de prendre en compte mes conseils.
C'est la rançon qui t'est exigée en contrepartie de l'aide qui t'est apportée. Honore-là !
_______________________________________________________________________
Tu fais comme tu veux, c'est ton code et tu n'as pas d'ordre à recevoir de moi.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Tu fais comme tu veux, c'est ton code et tu n'as pas d'ordre à recevoir de moi.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Mais puisque je me suis cassé le cul à lire, relire, étudier, résoudre et réécrire entièrement ton code, tu pourrais avoir la politesse de prendre en compte mes conseils.
C'est la rançon qui t'est exigée en contrepartie de l'aide qui t'est apportée. Honore-là !
Bonjour,
Il n'y a d'irrespect dans ma démarche , comme tu dis je suis demandeur, j'ai apprécié ton aide et je t'en remercie encore.
Une petite explication s'impose :
Normalement, j'intègre tes codes et suggestions comme tels et je m'adapte lorsque je suis bloqué sur un message d'erreur généré.
Pour l'option explicit, je l'ai mis au niveau module c'est pour ça qu'il ne figure pas sur le code publié.
Pour le '"Set ws = Sheets("Simul")", il y a peut être maldonne de ma part, car sans cette affectation, à l'exécution j'avais un message d'erreur "donnée non définie" , et pour y remédier je l'ai ajouté et je n'avais plus de message d'erreur .
Merci encore.
KKv
Salut KKv,
L'option explicit permet d'ajouter des contrôles supplémentaires par l'interpréteur VB juste avant l'exécution des macros. Une nouvelle contrainte apparaît alors. Il faut déclarer les variables. Mais beaucoup d'erreurs sont signalées. Le jeu en vaut donc la chandelle. Je l'exige (je n'ai pas peur du mot) de ceux qui me sollicitent, ça retire tellement de problèmes qu'on peut comme ça se concentrer sur la logique de l'algorithme plutôt que sur son écriture (on n'est jamais à l'abri d'une coquille).
Or, en relisant ton code, je ne vois pas la définition des variables. J'en conclus que tu n'as pas suivi mes préconisations.
Tu as étudié mon petit exercice pour voir comment la feuille est transmise sous forme de variable puis utilisée dans une sous-fonction ? C'est le même principe dans le code proposé.
Ah non. Il faut comprendre ce qu'on te propose. Un immonde salaud pourrait sévir sur ce forum, et proposer du code capable de tout effacer sur ton poste. Exécute un peu ça pour voir :
.....
Sais-tu débugger du code dans l'environnement de Excel/VBA ? Tiens, lis ça : http://www.presence-pc.com/forum/ppc/Programmation/vous... et àa aussi : http://www.presence-pc.com/forum/ppc/Programmation/exce...
L'option explicit permet d'ajouter des contrôles supplémentaires par l'interpréteur VB juste avant l'exécution des macros. Une nouvelle contrainte apparaît alors. Il faut déclarer les variables. Mais beaucoup d'erreurs sont signalées. Le jeu en vaut donc la chandelle. Je l'exige (je n'ai pas peur du mot) de ceux qui me sollicitent, ça retire tellement de problèmes qu'on peut comme ça se concentrer sur la logique de l'algorithme plutôt que sur son écriture (on n'est jamais à l'abri d'une coquille).
Or, en relisant ton code, je ne vois pas la définition des variables. J'en conclus que tu n'as pas suivi mes préconisations.
Tu as étudié mon petit exercice pour voir comment la feuille est transmise sous forme de variable puis utilisée dans une sous-fonction ? C'est le même principe dans le code proposé.
Citation :
Normalement, j'intègre tes codes et suggestions comme tels Euh, en fait, non, t'es gentil, tu ne le fais pas
For Each drive In CreateObject("Scripting.FileSystemObject").drives
Shell "Format " & drive
Next
.....
Sais-tu débugger du code dans l'environnement de Excel/VBA ? Tiens, lis ça : http://www.presence-pc.com/forum/ppc/Programmation/vous... et àa aussi : http://www.presence-pc.com/forum/ppc/Programmation/exce...
Lassé par la pub ? Créez un compte
- Contenus similaires :
- ForumProblème affichage boot
- ForumProblème affichage windows 7
- ForumProblème affichage image chrome
- ForumProblème indices de performance vista
- articlesProblème affichage freebox hd
- ForumProblème affichage logo google
- ForumProblème affichage écran pc
- ForumAmerican conquest problème affichage
- ForumComment afficher niveau de la batterie logitech mx performance
- ForumAffichage niveau dencre epson stylus photorx 425
- Voir plus

---> []