Optimisation Code
Résolu/Fermé
Frabian
Messages postés
9
Date d'inscription
lundi 15 juin 2015
Statut
Membre
Dernière intervention
20 juillet 2015
-
Modifié par NHenry le 15/06/2015 à 20:38
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 - 17 juin 2015 à 11:28
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 - 17 juin 2015 à 11:28
A voir également:
- Optimisation Code
- Optimisation pc - Accueil - Utilitaires
- Code asci - Guide
- Code puk bloqué - Guide
- Code telephone oublié - Guide
- Code activation windows 10 - Guide
4 réponses
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
3 310
Modifié par michel_m le 16/06/2015 à 07:57
Modifié par michel_m le 16/06/2015 à 07:57
Bonjour
Difficile de rentrer dans "le pourquoi du omment" vu la complexité
Déjà
place Application.screenupdating=false en début de code, pas besoin de le remettre à False en fin de macro
tu peux effectivement gagner pas de temps en supprimant des boucles. Evite au maximum des cellules en boucle particulièrement chronophages
en piochant un peu par hasard dans ton code:
deviendrait
transpose permettant la création d'une variable tableau à une dimension+ facile à manier
pour restituer
Les variables-tableaux à 1 dimension sont en quelque sorte "horizontaux" d'où encore le "transpose"
--
En ce qui concerne la présence d'une donnée d'un tableau dans un autre, tu as un outil magique qui est l'objet "Dictionary". je cherche dans mon grenier un exemple d'utilisation dans la comparaison de 2 colonnes et te le mettrais en pJ
Michel
Difficile de rentrer dans "le pourquoi du omment" vu la complexité
Déjà
place Application.screenupdating=false en début de code, pas besoin de le remettre à False en fin de macro
tu peux effectivement gagner pas de temps en supprimant des boucles. Evite au maximum des cellules en boucle particulièrement chronophages
en piochant un peu par hasard dans ton code:
For i = 1 To derniere_ligne
TableauDestination(i) = Ws_Feuille_destination.Cells(i, 6)
TableauDestinationTarget(i) = Ws_Feuille_destination.Cells(i, 7) '
Next
deviendrait
TableauDestination=application.transpose(range("F1:F" & dernière ligne))
transpose permettant la création d'une variable tableau à une dimension+ facile à manier
pour restituer
Ws_Feuille_Identifiant.Cells(i, 1) = TableauValeurIdentifiant(i)
à remplacer par
Ws_Feuille_Identifiant.range("A1").resize(ubound(TableauValeurIdentifiant),1)=application.transpose(TableauValeurIdentifiant)
Les variables-tableaux à 1 dimension sont en quelque sorte "horizontaux" d'où encore le "transpose"
--
En ce qui concerne la présence d'une donnée d'un tableau dans un autre, tu as un outil magique qui est l'objet "Dictionary". je cherche dans mon grenier un exemple d'utilisation dans la comparaison de 2 colonnes et te le mettrais en pJ
Michel
pijaku
Messages postés
12263
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
4 janvier 2024
2 752
16 juin 2015 à 08:41
16 juin 2015 à 08:41
Bonjour,
Je rejoins Michel, que je salue au passage, sur deux points :
1- beaucoup de boucles pas forcément très utiles, exemple cette boucle peut directement être supprimée :
2- L'utilisation de l'objet Dictionary va te permettre de gérer directement les doublons sans double boucles.
Par contre, attention avec la fonction Transpose qui est limitée à 65 536 "lignes". Ici tu parles de 150 000, il faudra s'en passer...
Si tu peux simplement nous décrire les actions que doit réaliser ta macro.
Je rejoins Michel, que je salue au passage, sur deux points :
1- beaucoup de boucles pas forcément très utiles, exemple cette boucle peut directement être supprimée :
For i = 1 To derniere_ligne TableauTargetSource(i) = "" TableauValeurSource(i) = "" TableauIdSource(i) = "" Next
2- L'utilisation de l'objet Dictionary va te permettre de gérer directement les doublons sans double boucles.
Par contre, attention avec la fonction Transpose qui est limitée à 65 536 "lignes". Ici tu parles de 150 000, il faudra s'en passer...
Si tu peux simplement nous décrire les actions que doit réaliser ta macro.
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
3 310
16 juin 2015 à 09:28
16 juin 2015 à 09:28
Salut Frank
Connaissais pas transpose limité à 65536 (curiosité: tu as trouvé cela où?)
je viens de faire un petit test sur 150 000 lignes et le code ci-dessous a l'air OK
tu dis au cas où
amicalement,
Connaissais pas transpose limité à 65536 (curiosité: tu as trouvé cela où?)
je viens de faire un petit test sur 150 000 lignes et le code ci-dessous a l'air OK
Sub essai_sans_transpose()
Dim cellule As Range
Columns("A:D").Clear
Application.ScreenUpdating = False
Randomize
For Each cellule In Range("A1:A150000")
nbre = Int(Rnd * 5)
cellule = nbre
Next cellule
tablo = Range("A1:A150000")
xx = UBound(tablo)
Range("D1").Resize(UBound(tablo), 1) = tablo
End Sub
tu dis au cas où
amicalement,
pijaku
Messages postés
12263
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
4 janvier 2024
2 752
>
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
16 juin 2015 à 10:12
16 juin 2015 à 10:12
Salut Michel,
Je ne connaissais pas non plus avant d'y être confronté pour un internaute.
En effet, la solution que tu proposes est certainement la mieux adaptée.
A noter toutefois que la syntaxe :
Je ne connaissais pas non plus avant d'y être confronté pour un internaute.
En effet, la solution que tu proposes est certainement la mieux adaptée.
A noter toutefois que la syntaxe :
tablo = Range("A1:A150000")renvoie un tableau à 2 dimensions tablo(1 To 150000, 1 To 2).
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
3 310
>
pijaku
Messages postés
12263
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
4 janvier 2024
16 juin 2015 à 10:29
16 juin 2015 à 10:29
renvoie un tableau à 2 dimensions tablo(1 To 150000, 1 To 2).
Oui, j'avais vu avec debogage espion
mais à ma heureuse et grande surprise, la restitution fonctionne
Range("D1").Resize(UBound(tablo), 1) = tablo
Mine de rien, ca ca simplifier pas mal de chose
Oui, j'avais vu avec debogage espion
mais à ma heureuse et grande surprise, la restitution fonctionne
Range("D1").Resize(UBound(tablo), 1) = tablo
Mine de rien, ca ca simplifier pas mal de chose
pijaku
Messages postés
12263
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
4 janvier 2024
2 752
>
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
16 juin 2015 à 10:33
16 juin 2015 à 10:33
Mine de rien, ca va simplifier pas mal de chose
+1000
Oui, en effet.
En fait, l'explication tiens dans le fait que Transpose est une fonction de feuille (une formule quoi ;-). Ces fonctions n'ont pas évolués avec les versions d'Excel 2007 pour un souci, je pense, de transportabilité.
Du coup, Application.Transpose dépends encore (et dépendra toujours) des spécificités en nombre de lignes d'Excel 2003.
+1000
Oui, en effet.
En fait, l'explication tiens dans le fait que Transpose est une fonction de feuille (une formule quoi ;-). Ces fonctions n'ont pas évolués avec les versions d'Excel 2007 pour un souci, je pense, de transportabilité.
Du coup, Application.Transpose dépends encore (et dépendra toujours) des spécificités en nombre de lignes d'Excel 2003.
Frabian
Messages postés
9
Date d'inscription
lundi 15 juin 2015
Statut
Membre
Dernière intervention
20 juillet 2015
16 juin 2015 à 10:17
16 juin 2015 à 10:17
En premier lieux, merci à vous deux, pour le temps que vous m'accordez et pour la gentillesse de vos réponses.
En ce moment le programme tourne et il me faut des premiers résultats pour ce début d'après-midi donc je testerai vos propositions en milieux d'après midi.
Pour la fonction transpose, je ne la connaissais pas, même après avoir rechercher comment enregistrer mes tableaux plus rapidement. J'avais essayé d'utiliser la fonction
Je vais essayé d'apporter beaucoup plus de précision mais n'ayant pas l'habitude de faire ça, je m'excuse d'avance pour les oublies qu'il y aura.
1) J'ai dans une colonne des phrases( beaucoup de phrase !!) et je veux pouvoir les exporter vers une autre colonne sans doublon. C'est mon premier bout de code qui fait ça. C'est pour ça que je n'ai pas utiliser la fonction "dictionary" car il me semble que c'est uniquement pour des mots seul.
En résumé, le premier point me permet de gérer les phrases doublons. Pour cela, j'avais pensé passer par les fonction "each" car j'avais lu que c'était plus rapide mais je n'y suis pas arrivé.
2) A côté de la première colonne, j'en ai une autre, des noms d'auteurs en réalité. Et donc je peux avoir de temps en temps la même phrase mais avec un nom d'auteur différent. Ainsi, dans une autre feuille (et ça c'est impératif si je veux pouvoir exploiter mes résultats par la suite), il faut que j'ai, sur une même ligne, la phrase (colonne A), l'auteur (colonne B) et le nombre de fois que l'auteur à répéter la phrase (colonne C). Petite info qui est peut être utile, les phrases sont trier par auteurs !
En tout cas je vous remercie énormément, avec ce que vous m'avais donné, je vais pouvoir bien avancer
En ce moment le programme tourne et il me faut des premiers résultats pour ce début d'après-midi donc je testerai vos propositions en milieux d'après midi.
Pour la fonction transpose, je ne la connaissais pas, même après avoir rechercher comment enregistrer mes tableaux plus rapidement. J'avais essayé d'utiliser la fonction
Tableau = Columns("F").Valuemais j'avais une erreur plus loin.
Je vais essayé d'apporter beaucoup plus de précision mais n'ayant pas l'habitude de faire ça, je m'excuse d'avance pour les oublies qu'il y aura.
1) J'ai dans une colonne des phrases( beaucoup de phrase !!) et je veux pouvoir les exporter vers une autre colonne sans doublon. C'est mon premier bout de code qui fait ça. C'est pour ça que je n'ai pas utiliser la fonction "dictionary" car il me semble que c'est uniquement pour des mots seul.
En résumé, le premier point me permet de gérer les phrases doublons. Pour cela, j'avais pensé passer par les fonction "each" car j'avais lu que c'était plus rapide mais je n'y suis pas arrivé.
2) A côté de la première colonne, j'en ai une autre, des noms d'auteurs en réalité. Et donc je peux avoir de temps en temps la même phrase mais avec un nom d'auteur différent. Ainsi, dans une autre feuille (et ça c'est impératif si je veux pouvoir exploiter mes résultats par la suite), il faut que j'ai, sur une même ligne, la phrase (colonne A), l'auteur (colonne B) et le nombre de fois que l'auteur à répéter la phrase (colonne C). Petite info qui est peut être utile, les phrases sont trier par auteurs !
En tout cas je vous remercie énormément, avec ce que vous m'avais donné, je vais pouvoir bien avancer
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
3 310
16 juin 2015 à 10:33
16 juin 2015 à 10:33
Envoie nous un extrait ( 1000 lignes) de tes colonnes phrase-auteur (avec des cas même phrase-autre auteur)
Le problème m'intéresse et vu la météo, pas envie de mettre le nez dehors
Le problème m'intéresse et vu la météo, pas envie de mettre le nez dehors
Frabian
Messages postés
9
Date d'inscription
lundi 15 juin 2015
Statut
Membre
Dernière intervention
20 juillet 2015
Modifié par Frabian le 16/06/2015 à 10:54
Modifié par Frabian le 16/06/2015 à 10:54
Si j'avais pu je l'aurais fait avec plaisir, le soucis c'est que ces informations sont confidentiel et qu'en aucun cas je peux les fournir à une tierce personne.
Cependant je peux donner une structure par exemple,
Il fait beau Balzac
Il fait beau Voltaire
Genre ta mère Proust
Par contre, il y a un moyen, je ne peux pas transmettre de fichier car la mon programme tourne et qu'excel est inutilisable mais ! Chaque phrase aura un numéro (dans ce que j'obtiens ça va jusqu'à environ 70.000) et de même pour les auteurs (allant jusqu'à 18). Et donc a la fin, je n'ai plus que des chiffres. Il est possible de travailler avec cette base non ? Ce ne sera plus des phrases mais ce sera peut être plus simple de passer par cette intermédiaire ?
Cependant je peux donner une structure par exemple,
Il fait beau Balzac
Il fait beau Voltaire
Genre ta mère Proust
Par contre, il y a un moyen, je ne peux pas transmettre de fichier car la mon programme tourne et qu'excel est inutilisable mais ! Chaque phrase aura un numéro (dans ce que j'obtiens ça va jusqu'à environ 70.000) et de même pour les auteurs (allant jusqu'à 18). Et donc a la fin, je n'ai plus que des chiffres. Il est possible de travailler avec cette base non ? Ce ne sera plus des phrases mais ce sera peut être plus simple de passer par cette intermédiaire ?
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
3 310
Modifié par michel_m le 16/06/2015 à 12:07
Modifié par michel_m le 16/06/2015 à 12:07
J'ai commencé une maquette sur 1000 lignes avec 25 auteurs, donc je vais bosser la dessus... :o)
Edit 12h
https://www.cjoint.com/c/EFqkgG5t2lz
Edit 12h
https://www.cjoint.com/c/EFqkgG5t2lz
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
3 310
16 juin 2015 à 12:13
16 juin 2015 à 12:13
voir message ci dessus (11:08 avec Edit 12h
Frabian
Messages postés
9
Date d'inscription
lundi 15 juin 2015
Statut
Membre
Dernière intervention
20 juillet 2015
Modifié par Frabian le 16/06/2015 à 14:50
Modifié par Frabian le 16/06/2015 à 14:50
Je te remercie grandement pour ton aide. Cependant, j'ai un soucis, je n'arrive pas à lire le fichier avec mon navigateur. Je pense que c'est due à la version obsolète du navigateur obligatoire de mon entreprise. Il y aurait un autre moyen pour que je le récupère ?
Merci d'avance
Edit : C'est étrange, autant j'arrive à prendre le premier fichier, autant le dernier il m'est impossible de l'obtenir...
Merci d'avance
Edit : C'est étrange, autant j'arrive à prendre le premier fichier, autant le dernier il m'est impossible de l'obtenir...
pijaku
Messages postés
12263
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
4 janvier 2024
2 752
17 juin 2015 à 07:54
17 juin 2015 à 07:54
Bonjour,
@ Frabian : 1,8 secondes pour 151 770 lignes c'est très impressionnant en effet. Merci de ton retour à ce sujet.
En ce qui concerne l'élément de séparation, effectivement si présence de tiret dans les données initiales, il convient de changer deux lignes de codes pour que cela fonctionne.
En remplaçant le "-" par ce que tu veux.
Si le sujet est résolu, il t'appartient de le fermer maintenant, en cliquant sur le lien "marquer comme résolu" dans ton premier message.
@ Michel : Le test
Dans le cas présent, on peut donc remplacer :
par :
Le test If n'étant pas chronophage, le gain de temps en soi est minime (de l'ordre de 0,3-0,4 secondes pour 150 000 lignes). C'est surtout ici plutôt de l'ordre esthétique ;-)
@ Frabian : 1,8 secondes pour 151 770 lignes c'est très impressionnant en effet. Merci de ton retour à ce sujet.
En ce qui concerne l'élément de séparation, effectivement si présence de tiret dans les données initiales, il convient de changer deux lignes de codes pour que cela fonctionne.
Ref = T_in(Cptr, 1) & "-" & T_in(Cptr, 2) '.... 'et '.... Separe = Split(T_phrase_auteur(Cptr), "-")
En remplaçant le "-" par ce que tu veux.
Si le sujet est résolu, il t'appartient de le fermer maintenant, en cliquant sur le lien "marquer comme résolu" dans ton premier message.
@ Michel : Le test
If Not Dico.exists(Ref) Thenn'est pas nécessaire. L'objet Dictionary, contrairement à une collection, ne plante ni en présence de doublon, ni lorsqu'il n'existe pas.
Dans le cas présent, on peut donc remplacer :
For Cptr = 1 To UBound(T_in) 'concaténète Ref = T_in(Cptr, 1) & "-" & T_in(Cptr, 2) If Not Dico.exists(Ref) Then 'inédit et nombre=1 Dico.Add Ref, 1 Else 'incrémentation du nombre de doublons Dico.Item(Ref) = Dico.Item(Ref) + 1 End If Next
par :
For Cptr = 1 To UBound(T_in) Ref = T_in(Cptr, 1) & "-" & T_in(Cptr, 2) 'Incrémentation du nombre de doublons Dico.Item(Ref) = Dico.Item(Ref) + 1 Next
Le test If n'étant pas chronophage, le gain de temps en soi est minime (de l'ordre de 0,3-0,4 secondes pour 150 000 lignes). C'est surtout ici plutôt de l'ordre esthétique ;-)
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
3 310
17 juin 2015 à 11:22
17 juin 2015 à 11:22
Bonjour,
tu as certainement raison raison mais je n'aime pas sans le If Not Dico.exists(Ref) : ca me tranquilise, cad que je ne pose pas de question style "et si ca existe, que fais-t-on"
que veux tu, à mon âge....
:o)
On coche résolu ou pas ?
tu as certainement raison raison mais je n'aime pas sans le If Not Dico.exists(Ref) : ca me tranquilise, cad que je ne pose pas de question style "et si ca existe, que fais-t-on"
que veux tu, à mon âge....
:o)
On coche résolu ou pas ?
pijaku
Messages postés
12263
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
4 janvier 2024
2 752
17 juin 2015 à 11:28
17 juin 2015 à 11:28
ca me tranquilise, cad que je ne pose pas de question style "et si ca existe, que fais-t-on"
Je procède également comme cela pour d'autres syntaxes...
On coche résolu ou pas ?
C'est fait, par le demandeur.
Il y a un bug qui fait que l'affichage en vert dans "Mes discussions suivies" apparait quelques heures après la mise en résolu...
Bonne journée à toi et au plaisir.
Je procède également comme cela pour d'autres syntaxes...
On coche résolu ou pas ?
C'est fait, par le demandeur.
Il y a un bug qui fait que l'affichage en vert dans "Mes discussions suivies" apparait quelques heures après la mise en résolu...
Bonne journée à toi et au plaisir.
Modifié par michel_m le 16/06/2015 à 08:35
en sortie :
listes de uniques colonne1, uniques colonne2, communs aux 2 colonnes restituées en 3/10 de seconde
https://www.cjoint.com/c/EFqgDwQ2l3z