Limite boucle For
Bonjour à tous !
j'ai un petit soucis sur un Macro que vous trouverez ci-dessous. J'ai 2 fichiers Excel et je cherche à ce que ma macro compare une ligne d'un fichier de 1000 ligne avec un fichier de 25000 lignes.
Seul problème, elle marchait bien avec un fichier de 9000 lignes mais quand je passe à 25000 lignes, ma macro s'arrête à 6558. Avez-vous des solutions ?
For j = 5 To 1000
recherche = Cells(j, 5)
recherche2 = Cells(j, 6)
recherche3 = Cells(j, 12)
Workbooks("aaa.xlsm").Worksheets("aaaa").Activate
For i = 1 To 25000
If Cells(i, 3) Like "*" & recherche & "*" & recherche2 & "*" & recherche3 & "*" Then
compteur = compteur + 1
Merci par avance !!
Salut Padam,
tu as oublié de poster la boule de cristal avec ton merveilleux fichier, si complet!
A+
hello Curulis57 !
Si j'avais une boule de cristal, je ne serais pas venu demander conseil
Comme je dis, ma macro fonctionne mais s'arrête à 6558, je pensais pas que ma demande était si complexe. De quelles autres informations auriez-vous besoin ?
Bonjour,
Ce que veut dire curulis57, c'est que sans fichier ça va être difficile de t'aider
Tu n'utilises peut être pas la bonne méthode
P.
Bonjour padam, curulis57
@padam
Je n'aime pas les boules de cristal (trop fragile à mon sens) mais comme je ne sais pas lire dans les pensées, donc
curulis57 et patrick1957 et moi a écrit :Ce que veut dire curulis57, c'est que sans fichier ça va être difficile de t'aider
https://forum.excel-pratique.com/annonces/explications-et-regles-a-respecter-t13.html article 6 !
Bonjour padam,
Dans le code de ton 1er message : For j = [b][i][color=#FF0000]5[/color][/i][/b] To [b][i][color=#FF0000]1000[/color][/i][/b]
puis For i = [b][i][color=#FF0000]1[/color][/i][/b] To [b][i][color=#FF0000]25000[/color][/i][/b]
➯ les 3 points qui suivent :
a) nombre de « tours » pour la 1ère boucle j : 1 000 - 5 + 1 = 996
b) nombre de « tours » pour la 2ème boucle i : 25 000 - 1 + 1 = 25 000
c) nombre de tours au total : 996 × 25 000 = 24 900 000
Alors même si tu as déclaré j et i en Integer, et que ça plante pas,
ça risque de durer drôlement longtemps, non ?
Es-tu vraiment sûr qu'il y a besoin de faire autant de boucles ?
Si je me suis trompé dans mon analyse, merci de l'indiquer !
Cordialement
re,
En effet, il est sûrement possible de faire autrement avec boucle et find sur 24 900 000 cellules
Une matrice serait plus rapide, il y a ici assez de connaisseurs qui te guideront pour ce faire, mais comme tu fais là , tu n'est pas sorti de l'auberge
P.
Bonjour patrick1957, merci d'avoir confirmé mon analyse. Cordialement
Bonjour le fil
Debut:
Toujours pas de fichier en vue...
Pour l'instant nous ne pouvons qu'émettre des hypothèses et pour l'instant toutes sont bonnes !
@patrick1957
Si par matrice tu entends tableaux VBA assurément je suis d'accord avec toi et très adepte
Mais pour l'instant Goto Debut
@dhany
24 900 000 en gros même avec un processeur à 1Mhz ça fait 25 secondes
à moins que dans la boucle il y ait des calculs et il faudrait parler en Flop et plus en Hertz
Avant que ça ne deviennent trop compliqué Goto Debut
@NCC 1701 : ah bon ! c'est que je me suis trompé, alors ! désolé, je pensais vraiment que ça allait durer super longtemps !
Merci à vous pour les derniers posts qui m'éclairent sur le sujet ! Il y a effectivement 2/3 petits calculs par boucle donc j'imagine maintenant qu'avec 24 900 000, c'est déjà un peu long à réaliser (même si pour le coup je ne lance qu'une fois ma matrice).
Je ne suis pas sûr du tout qu'il faille réaliser autant de boucles, je suis relativement novice en VBA. Il faut que j'étudie l'histoire des matrices (tableaux VBA) !
(Ce sont des fichiers pro qui ne peuvent pas forcément se trimbaler sur internet, c'est aussi pour ça que je partage pas forcément)
Voici le code complet !
Dim recherche As String
Dim recherche2 As String
Dim recherche3 As String
Dim compteur As Integer
Dim i As Integer
Dim j As Integer
Dim k As Integer
Sub NombreDeDocuments()
Range("EO4:GZ1001").ClearContents
Range("J4:J1001").ClearContents
For j = 5 To 1001
Cells(j, 10).Activate
recherche = Cells(j, 5)
recherche2 = Cells(j, 6)
recherche3 = Cells(j, 12)
If recherche = "" Or recherche2 = "" Then
Else
Workbooks("aaaa.xlsm").Worksheets("aaaa").Activate
For i = 1 To 25000
If Cells(i, 3) Like "*" & recherche & recherche2 & "-" & recherche3 & "*" & ".pdf" & "*" Then
compteur = compteur + 1
Cells(i, 3).Select
Selection.Copy
Windows("bbbb.xlsm").Activate
k = 145
While Cells(j, k) <> ""
k = k + 1
Wend
Cells(j, k).Select
ActiveSheet.Paste
Columns("EO:FZ").EntireColumn.AutoFit
Windows("aaaa.xlsm").Activate
End If
Next
Windows("bbbb.xlsm").Activate
Cells(j, 10) = compteur
compteur = 0
End If
Next
End Sub
Bonjour le fil
Voici une transformation (rapide - juste corrective au niveau de la syntaxe du code, je n'ai pas vraiment cherché à comprendre le pourquoi du comment) qui devrait accélérer un peu le traitement
on doit pouvoir encore améliorer un remplacement les Windows().Activate par des Set
Dim recherche As String
Dim recherche2 As String
Dim recherche3 As String
Dim compteur As Integer
Dim i As Integer
Dim j As Integer
Dim k As Integer
Sub NombreDeDocuments()
Dim recherche4
Dim celAcopier
Range("EO4:GZ1001").ClearContents
Range("J4:J1001").ClearContents
' pour accelerer !!!
Application.ScreenUpdating = False
For j = 5 To 1001
' Cells(j, 10).Activate => inutile !!!
recherche = Cells(j, 5)
recherche2 = Cells(j, 6)
recherche3 = Cells(j, 12)
If recherche = "" Or recherche2 = "" Then
' inutile !!!
Else
Workbooks("aaaa.xlsm").Worksheets("aaaa").Activate
' 1 operation en moins dans la boucle !!!
recherche4 = "*" & recherche & recherche2 & "-" & recherche3 & "*" & ".pdf" & "*"
For i = 1 To 25000
If Cells(i, 3) Like recherche4 Then
compteur = compteur + 1
' Plus rapide !!!
celAcopier = Cells(i, 3)
'Cells(i, 3).Select
'Selection.Copy
Windows("bbbb.xlsm").Activate
k = 145
While Cells(j, k) <> ""
k = k + 1
Wend
' Plus rapide suite !!!
Cells(j, k) = celAcopier
'Cells(j, k).Select
'ActiveSheet.Paste
Columns("EO:FZ").EntireColumn.AutoFit
Windows("aaaa.xlsm").Activate
End If
Next
Windows("bbbb.xlsm").Activate
Cells(j, 10) = compteur
compteur = 0
End If
Next
' ne pas oublier !!!
Application.ScreenUpdating = True
End Sub
@NCC 1701 : je t'avais laissé un message, mais tu ne l'as pas vu !
sur le sujet de scottish1234, j'ai répondu à ton message d'hier à 07:50
Bonjour le fil
Debut :
si tu fouilles un peu sur le forum tu te rendras vite compte que peu sont ceux qui ne sont pas dans ton cas !padam a écrit :(Ce sont des fichiers pro qui ne peuvent pas forcément se trimbaler sur internet, c'est aussi pour ça que je partage pas forcément)
Il suffit de rendre le fichier anonyme
Tu penses bien que nous ne savons pas du tout comment sont construit tes données, tes fichiers et encore moins ton programme ou ton besoin.
Par contre je t'assure que ta méthode est excessivement gourmande en traitements inutiles ! mes dernières améliorations rapides, devraient permettre de rendre la chose légèrement plus rapide.
Tablo :
Je te confirme que l'utilisation de tableaux serait nettement plus rapide, et tu n'as pas idée à quel point !
Cependant je t'invite à relire le début de ce message pour nous permettre de t'aider à résoudre ton problème de temps.
Comme je le disais dans un précédent message Goto Debut
Pour l'instant il y a une chose qui est chronovore c'est le temps que tu mets à nous montrer ce que tu veux vraiment. Il peut même suffire de quelques lignes significatives et représentatives de ce que tu as et d'une explication claire ou un résultat à obtenir pour le résultat tant attendu.
Goto Tablo
Salut Padam,
Salut l'équipe,
j'ai tenté un petit travail en postulant une confusion chez notre hôte entre classeur et feuilles (ça arrive tellement souvent).
En effet, ici...
Selection.Copy
Windows("bbbb.xlsm").Activate
k = 145
... aucune mention d'une feuille spécifique dans le supposé classeur 'bbbb'.
Je ne suis sûr de rien : j'essaie de faire avancer le Shimililimi... le Shlinimili... enfin, le truc, quoi... avant d'employer les tableaux pour accélérer le traitement.
Sub NombreDeDocuments()
'
Dim sWkAAA As Worksheet, sWkBBB As Worksheet
Dim sData As String, sData1 As String
Dim compteur As Integer, i As Integer, j As Integer, k As Integer
'
Set sWkAAA = Worksheets("AAA")
Set sWkBBB = Worksheets("BBB")
'
Range("EO4:GZ1001").ClearContents
Range("J4:J1001").ClearContents
With sWkBBB
For j = 5 To .Range("E" & Rows.Count).End(xlUp).Row
sData = .Cells(j, 5) & .Cells(j, 6)
If sData <> "" Then
sData1 = .Cells(j, 12)
With sWkAAA
For i = 1 To .Range("C" & Rows.Count).End(xlUp).Row
If .Cells(i, 3) Like "*" & sData & "-" & sData1 & "*" & ".pdf" & "*" Then
compteur = compteur + 1
iCol = sWkBBB.Cells(j, Columns.Count).End(xlToLeft).Column + 1
sWkBBB.Cells(j, iCol) = .Cells(i, 3)
End If
Next
End With
.Cells(j, 10) = compteur
compteur = 0
End If
Next
End With
sWkAAA.Columns("EO:FZ").AutoFit
'
End Sub
A ne pas utiliser en l'état, n'est-ce pas, Padam!?
A+
Bonjour le fil
@curulis57
Ta remarque est très pertinente, en particulier lorsque tu parles de confusion entre classeur et feuille !
Pour ma part, je n'ai pas osé m'attaquer à ce problème là, ne comprenant pas du tout ce que notre hôte cherche à faire, c'est pour cette raison que j'ai juste conseillé d'utiliser des "Set" sans préciser le reste.
Merci beaucoup pour votre aide à mieux comprendre mon programme, tout marche parfaitement
Bonjour padam, le fil
Très heureux d'avoir contribuer à te mettre sur la voie
Et merci pour
padam a écrit :Merci beaucoup pour votre aide à mieux comprendre mon programme, tout marche parfaitement