Plantage excel, nombre de calcul trop important ?

Fermé
Yderian Messages postés 7 Date d'inscription jeudi 21 mai 2015 Statut Membre Dernière intervention 22 mai 2015 - 22 mai 2015 à 12:39
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 - 26 mai 2015 à 10:45
Bonjour,

J'ai un soucis avec mon programme, j'essaie de faire un tri des doublons à partir d'une base de donnée (on va dire tableau1) vers le tableau2. Mon soucis c'est qu'à l'origine, mon tableau2 est vide. Ainsi j'ai trois cas de figure :
- La comparaison entre la ligne X du tableau1 est différente de la ligne Y du tableau => Il ne se passe rien, on regarde la ligne Y+1 (hypothèse implicite qui n'apparait pas dans le code)
- On observe que la ligne X du tableau1 est égale à la ligne Y+1 du tableau 2 => On place un compteur à côté pour compter le nombre de doublon
- Dans le cas ou on n'a aucune des options précédente, c'est que la ligne du tableau2 est vide et donc on la rempli par la ligne X du tableau1

Alors la comparaison et tout le tatoin j'arrive à le faire avec les moyens du bords. le problème, c'est que excel plante au bout de 30sec de moulinage. Soit c'est mon pc (vive les pc de bureau !) soit c'est mon programme. On va partir du principe que c'est mon programme qui n'est pas bon. Pouvez-vous m'aider à voir ce qui ne va pas ?


    derniere_ligne = Sheets("Feuil2").Range("A1").End(xlDown).Row
    derniere_ligne2 = Sheets("Resultats").Range("A2").End(xlDown).Row
    derniere_colonne = Sheets("Feuil3").Range("G3").End(xlDown).Row

Dim TableauSource(0) As String 'TableauSource est le tableau duquel on tire les informations
    Dim TableauCible() As String 'TableauCible est le tableau dans lequel on mets les informations et qui va nous servir de comparateur
    Dim i As Double
    Dim j As Double
    Dim v As Double
    Dim w As Double
    w = 1
ReDim TableauCible(derniere_ligne) 'on definei la taille de la matrice qui doit être égale au nombre de ligne que l'on a dans le premier tableau
For i = 1 To 100 'On donne la dimension du tableau en fonction du nombre de ligne que l'on va étudier
                TableauSource(0) = Ws_Feuille_destination.Cells(i, 6) 'ici on prends la valeur que l'on veut comparer
  For j = 1 To w                     
                    TableauCible(w) = Ws_feuille_Gephi.Cells(j, 1) 'On attribut une valeur à la matrice 

'                    Ws_feuille_Gephi.Cells(j + 1, 1) = TableauCible(j)
                        If TableauSource(0) = TableauCible(w) Then
                            n = Ws_feuille_Gephi.Cells(i + 1, 3)
                            n = n + 1
                            Ws_feuille_Gephi.Cells(i + 1, 3) = n '
                            Verification = True
                        ElseIf TableauCible(w) = "" Then
                            Ws_feuille_Gephi.Cells(i, 1) = TableauSource(0)
                            Ws_feuille_Gephi.Cells(i, 2) = Ws_Feuille_comparaison.Cells(3, 8)
                            Ws_feuille_Gephi.Cells(i, 3) = 1

                            w = w + 1



                    Next j
           Next


Ce code devrait à terme comparer un nombre de cellule assez important. Pour l'instant j'en ai plus de 7000 et ça peut augmenter drastiquement. Cependant, j'ai pu voir sur d'autre poste que certains ont plusieurs centaines de millier de ligne. Je pense donc que ça devrait pouvoir être réalisable.

Bien cordialement
Yderian

A voir également:

2 réponses

Yderian Messages postés 7 Date d'inscription jeudi 21 mai 2015 Statut Membre Dernière intervention 22 mai 2015
22 mai 2015 à 14:06
Voici la suite,

Finalement, l'ordinateur a réussi à faire tourner le programme sans planter. Donc c'est un problème du programme. Je viens d'effectuer plusieurs amélioration et maintenant j'aimerais savoir comment l'optimiser. Pour l'instant, comme je l'ai dis, je n'ai que 7000 lignes en entré et ça prends déjà pas mal de temps sur mon pc. Auriez-vous des idées ?

Voici le code qui fait ce qu'on lui demande ^_^
derniere_ligne = Sheets("Feuil2").Range("A1").End(xlDown).Row
    derniere_ligne2 = Sheets("Resultats").Range("A2").End(xlDown).Row
    derniere_colonne = Sheets("Feuil3").Range("G3").End(xlDown).Row

    Dim Verification As Boolean

    Dim Verification2 As Boolean
    Ws_feuille_Gephi.Cells(1, 1) = "Source"
    Ws_feuille_Gephi.Cells(1, 2) = "Target"

Dim TableauSource() As String
    Dim TableauCible() As String
    Dim i As Double
    Dim j As Double
    Dim v As Double
    Dim w As Double
    w = 1
    ReDim TableauCible(derniere_ligne)
    ReDim TableauSource(derniere_ligne)
 
'    For v = 1 To derniere_colonne
'        TableauSource(1) = Ws_Feuille_comparaison.Cells(v + 2, 8)
            For i = 1 To derniere_ligne 'On donne la dimension du tableau en fonction du nombre de ligne que l'on va étudier
                TableauSource(i) = Ws_Feuille_destination.Cells(i, 6)

                    For j = 1 To w
                        Verification = False
                    TableauCible(w) = Ws_feuille_Gephi.Cells(j + 1, 1)
'MsgBox (TableauCible(w))
'MsgBox (TableauSource(i))

'                    Ws_feuille_Gephi.Cells(j + 1, 1) = TableauCible(j)
                        
                        
                        If TableauSource(i) = TableauCible(w) Then
                            n = Ws_feuille_Gephi.Cells(j + 1, 3)
                            n = n + 1
                            Ws_feuille_Gephi.Cells(j + 1, 3) = n '
                            Verification = True
'MsgBox ("OK")
                        ElseIf TableauCible(w) = "" And Verification = False Then
                            Ws_feuille_Gephi.Cells(j + 1, 1) = TableauSource(i)
                            Ws_feuille_Gephi.Cells(j + 1, 2) = Ws_Feuille_comparaison.Cells(3, 8)
                            Ws_feuille_Gephi.Cells(j + 1, 3) = 1
Verification = True

                            w = w + 1
'                            MsgBox ("Vide")
                        ElseIf TableauCible(w) <> TableauSource(0) Then
'                        MsgBox ("PasOk")
                        End If
                        If Verification = True Then
                            Exit For
                        End If

                    Next j
           Next



Bien cordialement,
Yderian
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 303
Modifié par michel_m le 22/05/2015 à 17:23
Bonjour
commentaire uniquement de procédure car je n'ai pas trop pigé ce que tu voulais faire.!
1/Dommage que tu nous donnes pas le début de la macro car je n'ai pas vu
application.screenupdating=false
qui fige le défilement de l'écran: confort et rapidité
2/ pourquoi des compteurs déclaré en doubles alors que ce sont des entiers; pour 7000 lignes ce sont des Integers
integer=2octets, double: 8 octets
3/pour tes variables tableaux source et cible inutile de boucler
par exemple
tablo=range("A1:G" & derniereligne tableau de 1 à der_lig et ici 7 colonnes)
et tu supprimes la déclaration redim inutile et fausse si tu n'as pas mentionné "option base 1" en ent^te de module

4/ tu bosses alors uniquement de tableasource à tableau cible et tu crées une variable tableau T_resultats qui collecteras les résultats plutôt que d'écrire dans les cellules

et tu restitues le résultat
dans le genre: 'si plusieurs colonnes dans t_résultat
Range("depart").resize(ubound(t_resultats),nbrede colonnes)=t_resultats

le gros avantage des variables tableaux est d'éviter les AR Ram-processeur-cartegraphique très chronophage,donc à toi de jouer

Il est peut-^tre aussi intéressant d'utiliser un objet "dictionary" mais comme je ne pige ta demande...
0
Yderian Messages postés 7 Date d'inscription jeudi 21 mai 2015 Statut Membre Dernière intervention 22 mai 2015
22 mai 2015 à 18:27
Bonjour michel-m, merci de ton aide qui m'est déjà très précieuse. Je suis sur mon téléphone alors il faudra me pardonner des erreurs d'écriture.
Bref, l'idée du tableau est de trouver toutes les données en double. En gros je vais avoir des instituts des noms d'entreprises en entré (1 par ligne) et ensuite j'ai le pays. Donc ce que je veux faire c'est comparer le nom que je vais regarder aux noms d'entreprise qui seront déjà inscrit dans le tableau2. Si il trouve une occurence, alors j'ai un petit compteur qui monte a côté. Et c'est presque tout ! Enfin c'est le début déjà.

Alors déjà pour le vba je débute donc j'ai encore du mal avec ce langage(comme tt les langage^^) et donc je ne comprends pas tonpoint 3. Peux tu plus le détailler ? Si j'ai le temps, je vais voir pour regarder les modifications quand je rentre chez moi et je reviens vers toi au plus vite !
Merci encore
Yderian
0
Voici tout le code, il y a encore quelques modifications avec une tonne de boucle for ! Je vais voir pour ce que tu m'as dis pour balayer un tableau complet.

Sub TriageGephi()
 



 
 
     'On cible la première feuille contenant les info à manipuler
    ' Dim + nom_varialbe + As + type_varialbe (integer, long, String, ...)
    Dim Ws_Feuille_information As Worksheet
    Set Ws_Feuille_information = ThisWorkbook.Worksheets("Feuil1")

    'On cible la deuxième feuille contenant les résultat des traitements
    Dim Ws_Feuille_destination As Worksheet
    Set Ws_Feuille_destination = ThisWorkbook.Worksheets("Feuil2")
    
    'On utilise la feuille 3 pour pouvoir créer un tableau de valeur qui ne servira qu'à la comparaison des pays
    Dim Ws_Feuille_comparaison As Worksheet
    Set Ws_Feuille_comparaison = ThisWorkbook.Worksheets("Feuil3")
    
    'On cible la quatrième feuille pour créer les résultats à utiliser dans Gephi
    Dim Ws_feuille_Gephi As Worksheet
    Set Ws_feuille_Gephi = ThisWorkbook.Worksheets("Resultats")
    
    

    



    derniere_ligne = Sheets("Feuil2").Range("A1").End(xlDown).Row
    derniere_ligne2 = Sheets("Resultats").Range("A2").End(xlDown).Row
    derniere_colonne = Sheets("Feuil3").Range("G3").End(xlDown).Row

    Dim Verification As Boolean

    Dim Verification2 As Boolean
    Ws_feuille_Gephi.Cells(1, 1) = "Source"
    Ws_feuille_Gephi.Cells(1, 2) = "Target"

    
'  Application.ScreenUpdating = False
'    For t = 1 To derniere_colonne - 2
'       Ws_feuille_Gephi.Cells(1, t + 2) = "W_" + Ws_Feuille_comparaison.Cells(t + 2, 8)
'    Next
'
'    For u = 1 To derniere_ligne
'        For o = 3 To derniere_colonne
'            Ws_feuille_Gephi.Cells(u + 1, o) = 0
'        Next
'    Next
    
'   Application.ScreenUpdating = True
    
    Dim TableauSource() As String
    Dim TableauCible() As String
    Dim i As Integer
    Dim j As Integer
    Dim v As Integer
    Dim w As Integer
    w = 1
    ReDim TableauCible(derniere_ligne)
    ReDim TableauSource(derniere_ligne, derniere_colonne)
 
'    For v = 1 To derniere_colonne
'        If Ws_Feuille_comparaison.Cells(v + 2, 7) <> Ws_Feuille_destination(v, 3) Then
'        TableauSource(1) = Ws_Feuille_comparaison.Cells(v + 2, 8)
            For i = 1 To derniere_ligne 'On donne la dimension du tableau en fonction du nombre de ligne que l'on va étudier
                TableauSource(i) = Ws_Feuille_destination.Cells(i, 6)

                    For j = 1 To w
                        Verification = False
                    TableauCible(w) = Ws_feuille_Gephi.Cells(j + 1, 1)
'MsgBox (TableauCible(w))
'MsgBox (TableauSource(i))

'                    Ws_feuille_Gephi.Cells(j + 1, 1) = TableauCible(j)
                        
                        
                        If TableauSource(i) = TableauCible(w) Then
                            For vu = 3 To derniere_colonne
                                Peace = Ws_Feuille_destination.Cells(i, 6)
                                Poce = Ws_Feuille_comparaison.Cells(vu, 8)
                                    If LCase(Peace) = LCase(Poce) Then
                                            n = Ws_feuille_Gephi.Cells(j + 1, vu)
                                            n = n + 1
                                            Ws_feuille_Gephi.Cells(j + 1, vu) = n '
                                            Verification = True
                                    End If
                            Next
                            
                        ElseIf TableauCible(w) = "" And Verification = False Then
                            Ws_feuille_Gephi.Cells(j + 1, 1) = TableauSource(i)
                            Ws_feuille_Gephi.Cells(j + 1, 2) = Ws_Feuille_comparaison.Cells(v + 2, 8)
                            Ws_feuille_Gephi.Cells(j + 1, 3) = 1
                            Verification = True

                            w = w + 1
'                            MsgBox ("Vide")
                        ElseIf TableauCible(w) <> TableauSource(0) Then
'                        MsgBox ("PasOk")
                        End If
                        If Verification = True Then
                            Exit For
                        End If

                    Next j
                Next
'        End If
'    Next
    
    
    

    
End Sub
0
PlacageGranby Messages postés 393 Date d'inscription mercredi 26 mars 2014 Statut Membre Dernière intervention 7 mars 2019 26
Modifié par PlacageGranby le 22/05/2015 à 20:47
Bonjour,

Comme Michel_m le suggère dans son point #1.
Ton gain principal va se faire avec au debut de ta macro
Application.screenupdating = false 

Et à la toute fin.
Application.screenupdating - true  


En gros, en plus d'avoir a calculer, Excel se donne comme mission d'afficher en real time tout les changements au fur et a mesure et il perd énormément de temps et de ressource à le faire.
Donc avec screenupdating, on peut dire à Excel de ne pas s'enfarger avec l'affichage, et l'affichage sera rafraichit seulement à la fin du calcul.
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 303 > PlacageGranby Messages postés 393 Date d'inscription mercredi 26 mars 2014 Statut Membre Dernière intervention 7 mars 2019
23 mai 2015 à 08:02
il est inutile de terminer la macro par
Application.screenupdating - true
puisque la macro rend la main au système!

d'autre part
qui fige le défilement de l'écran: confort et rapidité
te semble insuffisant ?
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 303
23 mai 2015 à 07:59
bonjour,
le mieux serait que tu mettes un extrait (et non un exemple vite fait mal fait) de ton classeur
pour cela
Mettre le classeur sans données confidentielles en pièce jointe sur https://www.cjoint.com/
et coller le lien proposé dans le message de réponse

ce que je comprend mal :
Mon soucis c'est qu'à l'origine, mon tableau2 est vide. Ainsi j'ai trois cas de figure :

...
...
Dans le cas ou on n'a aucune des options précédente, c'est que la ligne du tableau2 est vide et donc on la rempli par la ligne X du tableau1
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 303
Modifié par michel_m le 23/05/2015 à 11:51
Re,
pas envie de mettre le nez dehors vu les rafales de mistral dans mon coin :-(

en attendant ci joint un exemple qui est -peut-^tre- ce que tu désires mais cela pourrait, toujours peut-^tre, t'aider à la conception de ton classeur

on compare 2 listes de 10000 lignes (3 colonnes mais peu importe) feuille1 et feuille2
et on restitue les communs en feuille3
le tout en un peu moins de 0,17 secondes
https://www.cjoint.com/?3ExlWbLIC85
0
Salut,

Je te remercie beaucoup pour ce que tu as fait. J'ai pu regarder chez moi mais la, prendre le fichier au bureau est juste impossible. Du coup, je n'y ai plus du tout accès... Comment faire ?
Sinon, ce qui est compliqué c'est qu'il ne faut pas que gérer les doublons. En fait ça ce passe en trois temps :

Les protagonistes :
- Tableau1 (c'est de lui qu'on va extraire les informations)
- Tableau2 (il est vide au début)

On prends la première ligne du Tableau 1 et on la compare au tableau 2. Si c'est vide, on rempli (donc la il faut faire une matrice qui évolue en fonction de ce qu'on va mettre dedans). Mais surtout, la difficulté, c'est que le Tableau2 est en deux dimensions ! Je m'explique

Pour chaque institut/Industriel/Pots de fleures, on va rajouter un petit compteur à côté. Et à chaque fois qu'on va en remarquer un (de doublon), on va faire une petite incrémentation de 1 (que j'appellerais, le poids). Donc ça c'est pour l'initialisation de la deuxième dimension. En gros, on aura le noms des pots de fleurs d'un côté et le poids de l'autre. Mais ce n'est toujours pas tout !

En plus du poids général, il faut un poids spécifique par instituts. Alors la il y a deux possibilité, sois je choisi les pots de fleurs à regarder, soit, a chaque fois que je vais avoir un nom de pots de fleurs que je ne connais pas, je l'ajoute sur l'autre dimension et j'incrementerais de 1 la valeur a chaque fois que je trouverais ce pots de fleurs travaillant avec un autre (je ne sais pas si vous me suivez...)

Exemple


X poids général X1 X2 X3 X4 X5 X6


X1 2 1 1 0 0 0 0

X2 11 0 7 2 1 0 1

X3 1 0 1 0 0 0 0

X4 14 5 0 5 0 4 0

X5 1 0 0 0 1 0 0

X6 6 0 2 0 2 0 2


Est-ce mieux avec cette exemple ?

Merci d'avance pour votre aide, je galère vraiment avec morceau de code....

Yderian
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 303 > Yderian
26 mai 2015 à 10:45
Pourquoi ne pas poser le VRAI problème au départ ? :(
Il faut bien te rendre compte que ce que tu demandes n'est pas forcément facile et que personne ne veut passer parfois plusieurs heures à essayer de résoudre un problème bénévolement pour se voir dire après coup « il faut en plus que.... »
0