Boucle For lente

Non il y a que la colonne M avec des formules.

Lisez dans le fichier la ligne 2 j'ai mis les colonnes remplies de données (E,F,G,H,P,Q,R,S) et j'ai oublié de préciser la colonne L et W sont aussi remplie, j'ai enlevé les données juste pour le forum car le fichier était trop lourd

En complément des efforts de Dan, je vais regarder la piste que je propose pour descendre à moins d'une minute.

Ca serait super Steelson et pour les colonnes remplie de données vous mettez 10 par exemple comme valeur dedans

et j'ai oublié de préciser la colonne L et W sont aussi remplie, j'ai enlevé les données juste pour le forum car le fichier était trop lourd

Ah ...comment voulez vous que l'on fasse le code correct si vous ne mettez pas toutes les données. SI le fichier est trop lourd, supprimez des lignes plutot que des données de colonnes dont on a besoin pour proposer quelque chose.

Ce serait mieux que vous postiez un fichier avec 5000 lignes par exemple et ce, avec des 1 et 0 en colonne M.

Il faudra certainement abandonner les boucles actuelles et mettre tout cela en tableau (array, Ubound....) dont Steelson a parlé dans un post.

Edit : desolé Steelson, je n'avais pas vu que tu avais posté

Désolé aussi car je prends le fil en cours de route.

Il y a en colonne N des nombres qui sont en texte (je ne pense pas que cela gêne), mais quid des cases vierges en N !! on les ignore ??

Je voulais avoir le plus de lignes possible pour voir a quel points l'exécution est longue mais voici un extrait plus court en PJ et j'ai enlevé les nombres qui étaient en texte

7classeur-forum2.zip (618.67 Ko)

Edit : j'ai convertis les nombres en texte en valeur numérique, pas enlevé

puisque le but pour le moment est un test de vitesse

  • je poursuis avec le gros fichier puisque j'ai commencé
  • je vais compléter les trous par les valeurs précédentes

c'est un peu pointu dans les décalages à opérer, donc je pense que je sortirai quelque chose demain matin à la fraîche, à mon avis cela mettra quelques secondes !

correction ci-dessous ...

Reste à vérifier quand même en détail

Option Explicit

Sub aligner()
' hypothèse, les données sont bien triées
Dim tbl1(), tbl2()
Dim n As Double, p As Double, m As Double, j%, derL1 As Double, derL2 As Double, x As Double, maxi As Double, tps As Date
Sheets(1).Select
tps = Now
derL1 = Range("C" & Rows.Count).End(xlUp).Row
derL2 = Range("N" & Rows.Count).End(xlUp).Row
tbl1 = Range("C3:K" & derL1)
tbl1 = Application.Transpose(tbl1)
tbl2 = Range("N3:V" & derL2)
tbl2 = Application.Transpose(tbl2)

maxi = Application.Max(tbl1(1, UBound(tbl1, 2)), tbl2(1, UBound(tbl2, 2)))

x = 0 ' indicateur d'arrêt = plus grande valeur
n = 0 ' progression
Do Until x = maxi
    n = n + 1
    x = tbl1(1, n)
    If tbl1(1, n) <> tbl2(1, n) Then
        m = 1
        If tbl1(1, n) < tbl2(1, n) Then
            x = tbl1(1, n)
            Do
                m = m + 1
            Loop While tbl1(1, n) = tbl1(1, n + m)
            ReDim Preserve tbl2(1 To UBound(tbl2), 1 To UBound(tbl2, 2) + m)
            For p = UBound(tbl2, 2) - m To n Step -1
                For j = 1 To UBound(tbl2)
                    tbl2(j, p + m) = tbl2(j, p)
                    tbl2(j, p) = ""
                Next
                'tbl2(1, p) = tbl1(1, n)
            Next
        ElseIf tbl2(1, n) < tbl1(1, n) Then
            x = tbl2(1, n)
            Do
                m = m + 1
            Loop While tbl2(1, n) = tbl2(1, n + m)
            ReDim Preserve tbl1(1 To UBound(tbl1), 1 To UBound(tbl1, 2) + m)
            For p = UBound(tbl1, 2) - m To n Step -1
                For j = 1 To UBound(tbl1)
                    tbl1(j, p + m) = tbl1(j, p)
                    tbl1(j, p) = ""
                Next
                'tbl1(1, p) = tbl2(1, n)
            Next
        End If
        n = n + m
    End If
Loop

fin:
Sheets(2).Select
Range("C3").Resize(UBound(tbl1, 2), UBound(tbl1)) = Application.Transpose(tbl1)
Range("N3").Resize(UBound(tbl2, 2), UBound(tbl2)) = Application.Transpose(tbl2)
MsgBox "Déjà terminé ! ... " & Format(Now - tps, "hh:mm:ss")

End Sub

Désolé, en recherchant une solution plus rapide, je me suis aperçu que j'avais oublié de trier les données (cela peut s'intégrer dans la macro).

Il est super ton programme ! j'ai testé le fichier de ce matin, il c est exécuté en une dizaine de secondes

C est ce que je voulais merci

J ai pas compris ta oublié de trier quoi ?

J'avais en réalité trié sur une autre colonne car je voulais intégrer dans la macro un tri pour prendre en compte les cas de listes non triées ... et ce faisant je l'ai oublié. Mais cela m'a permis quand même de corriger certains aspects car il y avait beaucoup plus de "ruptures" et d'écarts entre les 2 listes tout en restant sous la barre de la minute.

Cela démontre une fois de plus qu'en cas de lenteur, une des causes est la trop grande interaction entre le code et la feuille ... il vaut mieux emmener toutes les données dans un tableau et travailler dessus. Du même coup, on ne fait pas non plus ni rafraichissement ni calcul sur la feuille.

La difficulté de cet exercice "intellectuel" est qu'il faut réfléchir en "horizontal" et pas en "vertical" (*) : les lignes sont des colonnes dans le tableau. Pourquoi, parce que le redimensionnement du tableau avec préservation des données (redim preserve) ne s'applique qu'à la deuxième (dernière) dimension du tableau. On ne peut donc pas augmenter la taille du premier indice mais du second. D'où la nécessité d'effectue une transposition (transpose).

(*) au figuré aussi car la nuit porte conseil !

Tu peux maintenant clore le sujet en cliquant sur et en remerciant aussi Dan pour son implication, et curulis -bref mes amis outre-quiévrains- qui manie très bien les tableaux.

Bonjour merci à vous Dan, Curulis Eric et Steelson d'avoir pu proposer des réponses à ce sujet

Si j'ai bien compris la fonction transpose permet de transposer une colonne en une ligne mais après je vois pas bien la différence entre comparer des données en verticale ou horizontale. Le gain de temps est du à cette fonction transposer qui travaille dans la mémoire au lieu de travailler sur la feuille c'est bien ça ?

Le gais de temps est seulement lié au fait de travailler en mémoire sans interférence avec la feuille. Même si la macro indiquait ScreenUpdating = False.

Transpose c'est différent.

  • Si on connait d'avance le nombre de lignes du tableau à 2 dimensions (lignes et colonnes), alors on n'en a pas besoin.
  • Si on a besoin d'ajouter des lignes en cours de macro, ce n'est pas possible car on ne peut ajouter que des colonnes en préservant les données déjà présentes dans le tableau. Donc on fait un transpose pour pouvoir augmenter le nombre de ;.. colonnes ! et à la fin on refait transpose pour coller le tableau dans la feuille

en complément, j'aurais pu définir a priori un array dont le nombre de lignes et la somme des lignes des 2 tableaux, cela aurait évité le transpose

Ok merci, je comprends mieux maintenant

Rechercher des sujets similaires à "boucle lente"