Optimisation code VBA pour remplissage d'une page

Signaler
Messages postés
4
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
25 juin 2009
-
Messages postés
4
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
25 juin 2009
-
Bonjour,

je suis novice en developpement dans VBA pour Excel et j'ai un probleme de temps de traitement sur le code suivant:

1) Je fais mes calculs a partir des donnees de ma page (code sans grande importance, je pense, car le temps de traitement est OK pour cette partie):

        Dim i, j, k As Integer
        Dim NOMX As Variant
        Dim nomy As Variant
        Dim TABprev(300, 300) As Variant
     
    For i = 3 To 173
        For j = 8 To 64
        NOMX = Cells(i, j).Value
        nomy = 0
        l = Int((j - 8) / 3)
            For v = 65 + l To 83
                If NOMX > 1 And l < 18 Then
                    NOMX = NOMX - 1
                    nomy = nomy + Cells(i, v + 1).Value
                Else
                    nomy = Round(nomy + NOMX * Cells(i, v + 1).Value)
                    NOMX = 0
                    Exit For
                End If
            Next v
        TABprev(i, j + 76) = nomy
      Next j
    Next i

2) Puis, comme je recupere tous mes resultats de calcul dans le tableau TABprev, je voudrais les reinscrire dans ma page dans des cellules precises:

    For i = 3 To 173
      For j = 84 To 140
        Cells(i, j) = TABprev(i, j)
      Next j
    Next i

... Et la, probleme, le temps de traitement explose (plus de 200min pour remplir 10000 cellules, sans le moindre calcul!!!). Mon code doit vraiment etre mauvais et je ne sais pas comment l'ameliorer (je code habituellement pour Access ou je n'ai aucun probleme de ce genre...)

Merci d'avance pour votre aide et desolee de vous deranger pour un probleme surement tres mineur...

Violette

6 réponses

Messages postés
2814
Date d'inscription
mardi 15 avril 2003
Statut
Membre
Dernière intervention
2 juin 2020
36
Bonjour,

As-tu essayé en remplissant tes cellules directement dans ta première boucle ? Cela peut te faire gagner un peu de temps...

En même temps tu rempli un grand nombre de cellules, il est normal que cela prenne du temps. Tu passe par  une double boucle et un tableau à deux dimensions pour ton remplissage, cela aussi est assez lent, si tu le faisait avec une simple boucle et un tableau à une dimension, tu aurais forcément un traitement pour retrouver les coordonnées de ta cellule, je ne sais pas vraiment su tu gagnerais au change...

@+ Mayzz.
                                                                              
Si le déboguage est l'art d'enlever les bogues, la programmation doit être l'art de les créer. <
Messages postés
682
Date d'inscription
vendredi 6 avril 2007
Statut
Membre
Dernière intervention
4 août 2012
6
ton TABprev étant dimmensioné 300 par 300
tu peux le copier en une seule ligne de code
en faisant comme ceci :
Range(Cells(3, 84), Cells(303, 384) = TABprev()

cette opération prend moins d'une seconde quelque soit la taille

[reglement.aspx ]si c'est la solution, penser : REPONSE ACCEPTEE
Messages postés
1835
Date d'inscription
vendredi 13 mai 2005
Statut
Membre
Dernière intervention
20 novembre 2013
9
Salut,

tu en fais, quoi de cette variable tableau TABprev ? est-ce pour transféré des données d'une feuille à une autre ?

si oui ceci devrait faire l'affaire:

ici je suppose que tu travails sur 2 feuilles distincte

1er exemple la plage de destination est srictement placé au meme endroit que la plage source mais dans une autre feuille (evidemment):
Sheets("Feuille Destination").Range(Cells(3,84),Cells(173,140)).Value = Sheets("Feuille Source").Range(Cells(3,84),Cells(173,140)).Value

2ieme exemple la plage de destination est placé differemment:
Dim MaPlageSource As Range, MaplageDestination As Range
With Worksheets("Feuille Source")
    Set MaPlageSource = .Range(.Cells(3, 84), .Cells(173, 140))
End With
With Worksheets("Feuille Destination")
    Set MaplageDestination = .Range(.Cells(1, 1), .Cells(MaPlageSource.Rows.Count, MaPlageSource.Columns.Count))
End With
MaplageDestination.Value = MaPlageSource.Value

2ieme exemple (bis)
Dim MaPlageSource As Range
With Worksheets("Feuille Source")
    Set MaPlageSource = .Range(.Cells(2, 2), .Cells(5, 5))
End With
MaPlageSource.Copy Destination:=Worksheets("Feuille Destination").Range("A1")

Note que ce type de declaration Dim i, j, k As Integer ne fonctionne pas ! En effet ici seul k est declaré en integer les autres sont Variant.
La bonne methode est :

Dim i As Integer, j As Integer, etc

A+
Messages postés
4
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
25 juin 2009

Bonjour Mayzz,

en fait, j'ai deja essaye de mettre le remplissage des cellules directement dans la boucle de calcul, mais ca ne change pas grand chose au temps de traitement... Je pensais que sortir cette partie permettrait meme de le diminuer, mais visiblement non.

Je vais essayer avec un tableau a un dimension.

Merci pour ton aide, je te tiens au courant.

Violette
Messages postés
4
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
25 juin 2009

Bonjour Pile_poil,


je crois qu'avec ta methode j'y suis presque, ca tourne effectivement tres vite, mais, j'ai rien qui s'affiche dans les cases specifiees dans Range.


Or, j'ai bien verifie que mon tableau TABprev etait bien rempli. Et si je fais un truc du genre:

Range(Cells(3, 84), Cells(303, 384)) = TABprev(3, 84)
ca marche, en 1 sec, mais j'ai toutes mes cellules remplies avec la valeur de TABprev(3, 84), ce qui est logique, mais pas ce dont j ai besoin... Bref, on n'est pas loin, mais le TABprev() ne semble pas ecrire les valeurs...
Je continue dans cette direction. Si tu as une idee du pourquoi et ce que je peux faire, merci d'avance!

Violette
Messages postés
4
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
25 juin 2009

Bonjour Bigfish,

cette variable TABprev est un tableau intermediaire dans lequel je place les resultats d'un calcul un peu complique qui prend en entree des valeurs de cette meme page. Ce calcul 'un peu complique' se trouve dans la partie 1) de mon code et le remplissage avec les resultats, dans la meme page, avec les valeurs calculees dans la partie 1), se trouve dans la partie 2). Je ne transfers donc pas des donnees d'une zone a une autre.

Maintenant, peut-etre que la solution de placer mes resultats dans un tableau intermediaire n'est pas la meilleure (j'ai l'habitude de faire comme ca quand je code pour Access, mais c'est peut-etre une mauvaise habitude ) , s'il y a une autre facon d'inscrire directement les resultats dans les cellules cibles, je suis preneuse...

Merci pour le conseil sur les declarations (quand je parlais de mauvaises habitudes...  )

Violette