Macro trop lente à s'executer

Bonjour,

Je me permets de venir demander de l'aide car j'ai créé un code qui fonctionne bien mais qui est très long à s'exécuter. Je suis loin d'etre un pro de vba et je pense qu'il serait peut-etre possible d'arriver au meme resultat avec un code moins long à s'executer.

Sub NombreTestsValides()

Dim MaValeur As Integer, i As Integer, j As Integer, k As Integer, DerC As Integer, DerZ As Integer, l As Integer
Dim m As Integer

Application.ScreenUpdating = False

DerC = Worksheets("InfoZQM67").Cells(Application.Rows.Count, 1).End(xlUp).Row
DerZ = Worksheets("Détails des tests").Cells(Application.Rows.Count, 1).End(xlUp).Row

k = 0
l = 0
m = 0

For i = 2 To DerC

    For j = 2 To DerZ

        If Worksheets("InfoZQM67").Range("A" & i) = Worksheets("Détails des tests").Range("A" & j) Then
        k = k + 1

            If Worksheets("Détails des tests").Range("E" & j) <> "" Then
            l = l + 1
            End If

            If Worksheets("Détails des tests").Range("F" & j) <> "" Then
            m = m + 1
            End If

        Else:
        Worksheets("InfoZQM67").Range("B" & i).Value = k
        Worksheets("InfoZQM67").Range("C" & i).Value = l
        Worksheets("InfoZQM67").Range("D" & i).Value = m

        End If

Next j

k = 0
l = 0
m = 0

Next i

Worksheets("InfoZQM67").Range("A1").Value = "Batch"
Worksheets("InfoZQM67").Range("B1").Value = "Nombre de lignes totales"
Worksheets("InfoZQM67").Range("C1").Value = "Nombre de lignes encodées"
Worksheets("InfoZQM67").Range("D1").Value = "Nombre de lignes validées"

Application.ScreenUpdating = True

End Sub

Est-ce que quelqu'un à une idée ?

Merci d'avance

Hello,

Je ne sais pas combien tu as de lignes dans tes onglets mais, pour chaque ligne de ton onglet "InfoZQM67" tu vas repasser sur l'ensemble des lignes du deuxième onglet pour déterminer combien de fois tu as ta correspondance... ça doit être hyper consommateur si t'as pleins de lignes

As tu essayé avec des nb.si ou nb.si.ens pour déterminer tes valeurs k, l, m ? Je pense que tu pourrais faire sauter la boucle "j" avec ces formules

Hello,

En effet, c'est super long... car j'ai plus de 20000 lignes dans mon autre onglet...

Je vais essayer de voir comment je peux faire avec les fonctions que tu proposes, mais je ne les ai jamais utilisé encore.

En tous cas, merci pour ta réponse !

Hello,

Envoie ton fichier avec un nombre limité de ligne je regarderai :)

@+

Bonjour,

Tu peux essayer ça :

Sub Galopin()
Dim ArrI, ArrD, iRI%, iRD%, cptA%, cptE%, cptF%
With Worksheets("InfoZQM67")
    .Range("A1").Value = "Batch"
    .Range("B1").Value = "Nombre de lignes totales"
    .Range("C1").Value = "Nombre de lignes encodées"
    .Range("D1").Value = "Nombre de lignes validées"
Set ArrI = .Cells(1).CurrentRegion.Value
Set ArrD = Worksheets("Détails des tests").Cells(1).CurrentRegion.Value
For iRI = 2 To UBound(ArrI)
    For iRD = 2 To UBound(ArrD)
        If iLRI(iRI, 1) = iLRD(iRD, 1) Then
        cptA = cptA + 1
            If iLRD(iRD, 5) <> "" Then cptE = cptE + 1
            If iLRD(iRD, 6) <> "" Then cptF = cptF + 1
        Else
            iLRI(iRI, 2) = cptA
            iLRI(iRI, 3) = cptE
            iLRI(iRI, 3) = cptF
        End If
    Next j
    cptA = 0
    cptE = 0
    cptF = 0
Next
.Range("A1").Resize(UBound(ArrI), UBound(ArrI, 2)) = ArrI
End With
End Sub

Sinon joindre un fichier pour tester...

A+

9a-tester.zip (683.57 Ko)

Voici le fichier, dites moi si vous avez besoin de plus d'infos !

Un grand merci a vous deux

(Je teste ton code de suite)

J'ai un message d'erreur pour la fonction suivante:

iLRI

image

La macro corrigée :

Sub Galopin()
Dim ArrI, ArrD, iRI%, iRD%, cptA%, cptE%, cptF%
With Worksheets("InfoZQM67")
    .Range("A1").Value = "Batch"
    .Range("B1").Value = "Nombre de lignes totales"
    .Range("C1").Value = "Nombre de lignes encodées"
    .Range("D1").Value = "Nombre de lignes validées"
ArrI = .Range("A1").CurrentRegion.Value
ArrD = Worksheets("Détails des tests").Range("A1").CurrentRegion.Value
For iRI = 2 To UBound(ArrI)
    For iRD = 2 To UBound(ArrD)
        If ArrI(iRI, 1) = ArrD(iRD, 1) Then
        cptA = cptA + 1
            If ArrD(iRD, 5) <> "" Then cptE = cptE + 1
            If ArrD(iRD, 6) <> "" Then cptF = cptF + 1
        Else
            ArrI(iRI, 2) = cptA
            ArrI(iRI, 3) = cptE
            ArrI(iRI, 3) = cptF
        End If
    Next
    cptA = 0
    cptE = 0
    cptF = 0
Next
.Range("A1").Resize(UBound(ArrI), UBound(ArrI, 2)) = ArrI
End With
End Sub

A=

Merci :) Je la teste de suite !

Il y a encore une petite erreur vers la fin ...

            ArrI(iRI, 2) = cptA
            ArrI(iRI, 3) = cptE
            ArrI(iRI, 4) = cptF '<= ici !
        End If
    Next
    cptA = 0
    cptE = 0
    cptF = 0
Next
.Range("A1").Resize(UBound(ArrI), UBound(ArrI, 2)) = ArrI
End With
End Sub

A+

C'est génial !!! La rapidité est folle par rapport a ce que j'avais fait !!!

Il y avait juste une petite coquille dans le code, mais je l'ai corrigée:

Sub Galopin()
Dim ArrI, ArrD, iRI%, iRD%, cptA%, cptE%, cptF%
With Worksheets("InfoZQM67")
    .Range("A1").Value = "Batch"
    .Range("B1").Value = "Nombre de lignes totales"
    .Range("C1").Value = "Nombre de lignes encodées"
    .Range("D1").Value = "Nombre de lignes validées"
ArrI = .Range("A1").CurrentRegion.Value
ArrD = Worksheets("Détails des tests").Range("A1").CurrentRegion.Value
For iRI = 2 To UBound(ArrI)
    For iRD = 2 To UBound(ArrD)
        If ArrI(iRI, 1) = ArrD(iRD, 1) Then
        cptA = cptA + 1
            If ArrD(iRD, 5) <> "" Then cptE = cptE + 1
            If ArrD(iRD, 6) <> "" Then cptF = cptF + 1
        Else
            ArrI(iRI, 2) = cptA
            ArrI(iRI, 3) = cptE
            ArrI(iRI, 4) = cptF
        End If
    Next
    cptA = 0
    cptE = 0
    cptF = 0
Next
.Range("A1").Resize(UBound(ArrI), UBound(ArrI, 2)) = ArrI
End With
End Sub

Au niveau de

Else
            ArrI(iRI, 2) = cptA
            ArrI(iRI, 3) = cptE
            ArrI(iRI, 4) = cptF

La dernière ligne était notée:

 ArrI(iRI, 3) = cpt

C'est vraiment super en tous cas !!!

Je vais essayer de comprendre le code maintenant :)

Une bonne journée à vous !!!

Oui j'avais d'ailleurs corrigé dans ma réponse précédente... C'est l'inconvénient de travailler avec une boule de cristal...

Pour comprendre c'est simple : au lieu de travailler sur Excel, on travaille en mémoire sur des tableaux virtuels qui ont exactement les mêmes dimension que la partie utile (CurrentRegion)

C'est la raison pour laquelle j'ai défini les entêtes de colonne tout de suite afin que la ligne une soit prise en compte.

Le travail sur les Array est beaucoup plus rapide (20 fois env...) que sur Excel car on s'occupe que des valeurs. Les Arrays n'ont pas de couleurs, pas de police, ni de largeur : rien. Donc on n'a rien d'autre à s'occuper que de ce qui nous intéresse...

On les adresse de la même manière que les Cells dans Excel (par leur indice de ligne et de colonne). Dans cette situation :

Arr(1,1) est la cellule A1...

Arr(5,2) est la cellule B5...

A+

OK je vois, j'ai d'autres codes ou je fais des choses assez similaires, je vais pouvoir essayer d'utiliser les Array !

Tu as du voir dans mon fichier d'ailleurs tout le code :)

J'avoue que je tatouille encore...

C'est génial !!! Je me coucherai vraiment moins bête ce soir !!!

Je convertis toutes mes macros en utilisant les Array, c'est magique !!!

UN ENORME MERCI !!!!!!!!!!!!!!!

Rechercher des sujets similaires à "macro trop lente executer"