IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

vitesse d'exécution sur plage > 100000 celles


Sujet :

Macros et VBA Excel

  1. #1
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 290
    Points : 84
    Points
    84
    Par défaut vitesse d'exécution sur plage > 100000 celles
    Bonjour à tous,

    J'ai une base de donnée de 15 colonnes et des lignes dynamiques. C'est à dire que les lignes s'incrémentent au fur et à mesure de la saisie via un formulaire userform.

    pour faire simple: mon formulaire est pourvu d'une textbox, la 18, qui peut contenir un nombre à 10 chiffres (au delà j'ai une erreur et je ne sais pas pourquoi alors j'ai limité à 10 chiffres). lorsque je saisis par exemple dans la textbox18 la valeur 1, le code va vérifier dans la base si le nombre 1 existe (Ma base de donnée est telle que les nombres sont classés en ordre décroissant). Si tel est le cas alors affiche le contenu du row (soit les 15 colonnes) dans d'autres textbox's' d'affichage pour IHM. Mais après avoir codé je me rends compte que si ma base s'accroit à 1000 lignes enregistrées alors le séquençage devient long (j'aimerai pouvoir traité jusqu'à 100 000lignes). C'est à dire si je tape 15000 dans mon textbox le temps qui balaye les lignes je peux aller me faire un café. après cette prise de conscience, je me prends maintenant la tête...

    comment puis-je rendre ma routine plus fluide dans le traitement de lecture de la base et y afficher le contenu associé selon la ligne saisie dans le champ textbox18 ?
    Ma première idée serait de traiter par paquet de ligne. Si ma valeur saisie est 50 alors balaye uniquement la base de 1 à 500. Si ma valeur à présent serait de 4500 alors balaye de 4000 à 4500 mais je ne sais guère par où commencer ? tout ce que je peux comprendre est la "longueur" de traitement en faisant
    Range("B9").End(xlDown).Row mais après comment découper ce truc en paquet équitable sachant que ma base s'alimente à chaque saisie, soit en dynamique ?

    voici un début de mon code mais pas sur que cela d'une grande aide aux spécialistes. car il n'est pas adapté en cours mais je ne sais pas comment m'y prendre en fait. pour ceux qui on eu la patience de me lire, Ici Ticket correspond à un numéro de ligne en quelque sorte

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    Function recherche(ByVal ticket As Long, ByVal debut As Integer) As String
    Dim i, initial, final, facteur As Double
    facteur = 10 ^ (Len(TextBox18.Value) - 1)
     
    If ticket < 500*facteur Then 'Len(TextBox18.Value) < 4 And Then
    initial = Range("B9").End(xlDown).Row - 10 * facteur: final = initial + 10 * facteur
    ElseIf ticket > 499 And ticket < 1000 Then
    initial = Range("B9").End(xlDown).Row - 1000: final = initial + 1000
    ElseIf ticket > 1499 And ticket < 2000 Then
    initial = Range("B9").End(xlDown).Row - 1500: final = initial + 1500
    End If
     
     
    For i = initial To final
     
     
    If Cells(i, 2).Value = ticket Then
    Me.Controls("TextBox" & debut).Value = Cells(i, 4)
    Me.Controls("TextBox" & debut + 1).Value = Cells(i, 6)
    Me.Controls("TextBox" & debut + 2).Value = Cells(i, 10)
    Me.Controls("TextBox" & debut + 3).Value = Cells(i, 8)
    End If
    If Cells(i, 2).Value = ticket And (Cells(i, 10).Value = "T" Or Cells(i, 10).Value = "C" Or Cells(i, 10).Value = "N") Then
    Me.Controls("TextBox" & debut + 4).Value = Cells(i, 12)
    Me.Controls("TextBox" & debut + 5).Value = Cells(i, 14)
    recherche = Cells(i, 10)
    Exit Function
    End If
    mais je ne traite pas en dynamique et ma formule ne convient et pas et surtout je voudrais généraliser, si c'est possible, pour éviter des if à gogo pour chaque intervalle. faut il se lancer dans des suites ???

    Quelqu'un sait il s'y prendre avec ce genre de problème ?

    merci d'avance..

  2. #2
    Expert éminent

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 073
    Points : 9 853
    Points
    9 853
    Billets dans le blog
    5
    Par défaut
    Bonjour,

    utilises la fonction FIND pour chercher directement la bonne cellule dans ta colonne, plutôt que d'analyser cellule par cellule

    l'aide en ligne VBA te montrera la façon d'utiliser FIND, ainsi que les arguments possibles (notamment le fait de chercher la contenu exact de la cellule .. XlWhole)

    tu peux également utiliser l'enregistreur de macro, en simulant une recherche (Ctrl+F) d'une valeur dans ta colonne. T'aura un début de code qu'il suffira d'adapter

    si tu coinces, revient avec le code que tu as testé et expliques le problème


    EDIT : un exemple tout simple
    les numéros sont en colonne 1
    les données sont en colonne B et C

    on va chercher la valeur 8, et on va écrire dans la fenêtre d'exécution la valeur de la colonne B et C

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Sub MaRecherche()
    Dim Cell As Range
    Dim Valeur As Long
    Valeur = 8
     
    Set Cell = ThisWorkbook.Worksheets("Feuil1").Columns(1).Find(Valeur, , , xlWhole)
     
    If Not Cell Is Nothing Then
        Debug.Print Cell.Offset(0, 1).Value
        Debug.Print Cell.Offset(0, 2).Value
    Else
        Debug.Print "Recherche n'a pas abouti avec la valeur : " & Valeur
    End If
     
    End Sub

  3. #3
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 290
    Points : 84
    Points
    84
    Par défaut
    Joe.levrai avant tout merci !

    ça marche du tonnerre de feu ce "Find".
    j'ai essayé sur 65000 éléments (lignes plutôt) et ça rame pas.

    Une grosse épine sortie du pied !

    MERCI...

    problème résolut

  4. #4
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 290
    Points : 84
    Points
    84
    Par défaut
    Je réouvre ce post, car à présent :

    le traitement de recherche d'une cellule est fait grâce à la méthode FIND(valeur,,,xwhole)
    le traitement de suppression d'une ligne entière est réalisée suivante cette commande

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Dim ligne As Long
    ligne = Sheets("Feuil1").Columns(2).Find(article, , , xlWhole).Row
    Rows(ligne).EntireRow.Delete Shift:=xlUp

    le traitement de remplacement reste à faire

    si je supprime une ligne alors toutes mes autres lignes remontent (donné par mon shift:=xlup)

    mon problème est comment agencé les articles suivant? car ils ont pourvu de numéros décroissant en colonne B


    ma première soluce est de traiter ligne à ligne: mais cela risque d'être long ! et je reviens à mon problème de vitesse d'exécution !
    avez-vous une piste sans spécialement m'écrire le code ?

    je donne un exemple pour être sur d'être compris

    Nom : Capture d’écran 2016-07-16 à 16.37.45.png
Affichages : 391
Taille : 8,8 Ko

    si je supprime la ligne excel 40 soit le numéro 45 de la colonne B
    alors par ma suppression toutes les autres dessous remonteront de 1 ligne chacune
    donc la ligne excel 40 aura le numéro 46 de la colonne B et ça ne va pas car ça sautera de 44 à 46 en colonne B

    Si vous savez comment on traite ce problème ??

  5. #5
    Expert éminent

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 073
    Points : 9 853
    Points
    9 853
    Billets dans le blog
    5
    Par défaut
    Bonjour,

    plusieurs méthodes possibles, qui dépendent de l'agencement des données

    tu peux très bien gérer par formule cette numérotation, si une corrélation entre ce numéro et la ligne excel existe. Voir dans ce cas la fonction Ligne() à laquelle tu ajoutes une constante numérique pour retomber sur le bon numéro. A chaque suppression d'une ligne, les numéros se mettront à jour automatiquement

    sinon, après avoir supprimé tes lignes, si les numéros doivent se suivre, il te suffit de faire une recopie incrémentée des numéros en partant de ta première ligne

    y'a des dizaines de façons de s'en sortir, sans même utiliser VBA ou (à défaut) sans utiliser de boucle

  6. #6
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 290
    Points : 84
    Points
    84
    Par défaut
    merci encore pour ton aide Joe.Levrai mais je n'y arrive pas ! (à moitié disons)

    un spécialiste comme toi me dira que je fais encore du ligne par ligne mais comme je débute en vBa excel je n'ai pas de recul sur toutes les techniques les plus optimums. actuellement voici mon code pour renuméroter mes cellules de -1 chacune (je précise que ma suppression se fait depuis un userform) et
    je m'interdis de mettre des formules simples dans la feuil1 de la colonne B du genre $B71 = $B70 + 1 etc...
    il n'y a pas spécialement de corrélation entre le numéro inscrit dans chaque cellule de la colonne B parce que à chaque saisis dans le formulaire USF la première ligne soit B9 récupère le plus grand numéro de +1 par rapport à son prédécesseur.

    la fonction ligne sois je suis nul et je n'ai rien trouvé à ce sujet en vBa soit elle est utile dans la feuille excel chose qui ne me convient pas.
    je préfère passé par du vBa. Bon je préviens c'est codé comme un barbare, mais je débute...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    Private Sub traitement(ByVal ticket As Long)
    Dim i, j, ligne, ligne_init, ligne_fin As Double
    Dim buffer_ticket As Long
    Dim Cell As Range
    j = 1
    'trouve la ligne du ticket
    Set Cell = Sheets("Feuil1").Columns(2).Find(ticket, , , xlWhole)
    ligne = Cell.Row
    'efface la ligne et remonte ensemble de 1 ligne
    Rows(ligne).EntireRow.Delete Shift:=xlUp
     
    'reclasse les items
    ligne_init = ligne
    ligne_fin = Range("B9").End(xlDown).Row
    For i = ligne_init To ligne_fin
    Set Cell = Sheets("Feuil1").Columns(2).Find(ticket + j, , , xlWhole)
    buffer_ticket = Cells(Cell.Row, 2).Value - 1
    Cells(i, 2) = buffer_ticket
    j = j + 1
    Next i
    End Sub
    pour traiter environ 4000 lignes, le code met au moins 8s avant de me redonner la main => trop long

    Suis désespéré, frustré de ne pas voir l'ensemble des fonctionalités/techniques vba.

  7. #7
    Expert éminent

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 073
    Points : 9 853
    Points
    9 853
    Billets dans le blog
    5
    Par défaut
    On ne sait toujours pas exactement comment doivent s'organiser ces numéros.
    Ca commence en B3 par la valeur 1, et tu veux ensuite une incrémentation automatique ?


    prend une nouvelle feuille et écrit en A3 la formule

    étire la formule sur autant de lignes que tu veux
    on retrouve le schéma de ta copie écran

    essaye maintenant cet exemple où le ticket est basé sur cette colonne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Sub Supprime(Ticket As Long)
    Dim Cell As Range
    Set Cell = Columns(1).Find(Ticket, , xlValues, xlWhole)
     
    If Not Cell Is Nothing Then
        MsgBox "La ligne " & Cell.Row & " contenant le ticket " & Cell.Value & " va être supprimée."
        Cell.EntireRow.Delete
    Else
        MsgBox "Ticket " & Ticket & " non trouvé."
    End If
     
    End Sub
     
     
    Sub toto()
    Supprime 24
    End Sub

    Tes numéros sont intacts, cette colonne n'est pas impactée par ta suppression de ligne

  8. #8
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 290
    Points : 84
    Points
    84
    Par défaut
    merci Joe

    allez je reprends explication à partir de cette image
    Nom : Capture d’écran 2016-07-16 à 22.24.27.png
Affichages : 429
Taille : 12,0 Ko


    -> lorsque j'appuie sur le commandbutton1 de mon userform "ajout"
    la valeur saisie d'un textbox s'ajoute dans une colonne quelconque mais son numéro d'enregistrement toujours en B9: toujours ! Ici le numéro 25. Ensuite fait descendre les anciens numéros(24, 23, 22, ...,1) d'une ligne => cette partie ne présente pas de ralentissement logique il n'a pas à vérifier l'ensemble de B9 : B1000000000000000000

    Maintenant

    -> lorsque j'appuie sur le commandbutton2 de mon userform "supprime"
    la valeur saisie d'un textbox donne le numéro dans la colonne B à supprimer
    exemple j'ai tapé 12 dans le textbox alors trouve déjà la valeur 12 dans la colonne B puis tue la ligne puis remonte les lignes précédentes de +1
    sauf que, sauf que ma liste sera 25, 24, 23 ...., 14, 13, 11, 10 ,9 ...,1 il existera une discontinuité . chose dont je ne veux pas (car ce n'est pas propre)!
    donc les précédents numéros doivent remonter leur valeur également de +1

    soit 11 devient 12
    soit 10 devient 11 etc... afin d'avoir une liste continue

    est-ce que cela est plus clair ?????
    en tout cas merci pour ta patience face à mon problème.

    en fait la colonne B est une espèce incrémenteur si je puis ainsi l'exprimer


    (j'ai un problème similaire avec une listbox, mais si je réussit à résoudre ce problème celui de monlistbox sera pas loin je pense)

  9. #9
    Expert éminent

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 073
    Points : 9 853
    Points
    9 853
    Billets dans le blog
    5
    Par défaut
    Admettons qu'en colonne C il y a toujours des données qui accompagnent ce numéro d'incrément inversé

    en B9 tu mets tu étires sur ta plage

    tu supprimes une lignes manuellement et tu regardes le résultat.


    si tu veux manipuler ça par VBA, tu actionnes l'enregistreur de macro en effectuant ces opérations

  10. #10
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 290
    Points : 84
    Points
    84
    Par défaut
    bon j'ai essayé ton code ça irait si et seulement si tu mets une formule dans les cellules de la feuille or je ne souhaite pas


    par contre l'élément qui te manque et oublié de dire dans mon dernier post

    la construction des numéros de la colonne b se fait par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dernier_numero = Range("B9").End(xlDown).Value
    si cela éclair davantage

  11. #11
    Expert éminent

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 073
    Points : 9 853
    Points
    9 853
    Billets dans le blog
    5
    Par défaut
    Une autre méthode, avec Autofill

    on écrit les deux premiers chiffres en B9 et B10, puis une recopie automatique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    Sub Supprime(Ticket As Long)
    Dim Nb_Tickets As Long
    Dim Cell As Range
    Set Cell = Columns(2).Find(Ticket, , xlValues, xlWhole)
     
    If Not Cell Is Nothing Then
        MsgBox "La ligne " & Cell.Row & " contenant le ticket " & Cell.Value & " va être supprimée."
        Cell.EntireRow.Delete
     
        With Cells(9, 2)
            Nb_Tickets = Application.WorksheetFunction.CountA(Range(.Offset(0, 1), .Offset(0, 1).End(xlDown)))
     
            If Nb_Tickets > 0 Then
                .Value = Nb_Tickets
     
                If Nb_Tickets > 1 Then
                    .Offset(1, 0).Value = Nb_Tickets - 1
                    If Nb_Tickets > 2 Then .Resize(2, 1).AutoFill Destination:=.Resize(Nb_Tickets, 1), Type:=xlFillDefault
                End If
            Else
                .Value = ""
            End If
        End With
    Else
        MsgBox "Ticket " & Ticket & " non trouvé."
    End If
     
    End Sub
     
     
    Sub Toto()
    Supprime 24
    End Sub

  12. #12
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 290
    Points : 84
    Points
    84
    Par défaut
    merci encore pour ton intervention mais là je ne comprends rien va falloir 1 semaine pour comprendre ton code...

    toi tu l'écris en 5mn moi il me faut 1 mois et encore...

    mais sommes d'accord sur la compréhension que :

    - il ne faut pas de formule dans la feuille
    - et mon gros problème est la vitesse d'exécution qui est trop longue car ma méthode ne convient pas (avec 40000 saisies =>30s)

    donc il me faut trouver une méthode efficace.

    je regarde demain Joe car la je ne sais plus ou je vais

    à demain peut être

  13. #13
    Expert éminent

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 073
    Points : 9 853
    Points
    9 853
    Billets dans le blog
    5
    Par défaut
    Il faut déjà voir si ça répond à ta demande, l'as-tu testé ?

    avec les commentaires :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    Sub Supprime(Ticket As Long)
    Dim Nb_Tickets As Long
    Dim Cell As Range
     
    ' on cherche le ticket dans la colonne B
    Set Cell = Columns(2).Find(Ticket, , xlValues, xlWhole)
     
    ' s'il existe
    If Not Cell Is Nothing Then
        ' on supprime la ligne
        Cell.EntireRow.Delete
     
        ' on fait référence à B9
        With Cells(9, 2)
            ' le nombre de tickets calculés avec la formule =NBVAL() appliqué sur la colonne C en partant de C9
            Nb_Tickets = Application.WorksheetFunction.CountA(Range(.Offset(0, 1), .Offset(0, 1).End(xlDown)))
     
            ' si au moins 1 ticket
            If Nb_Tickets > 0 Then
                ' on écrit B9
                .Value = Nb_Tickets
     
                ' si au moins 2 tickets
                If Nb_Tickets > 1 Then
                    ' on écrit B10
                    .Offset(1, 0).Value = Nb_Tickets - 1
     
                    ' si + de 2 tickets : on fait une recopie incrémentée de B9:B10 jusqu'en bas des données
                    If Nb_Tickets > 2 Then .Resize(2, 1).AutoFill Destination:=.Resize(Nb_Tickets, 1), Type:=xlFillDefault
                End If
            Else
                ' si on a aucun ticket, B9 est effacé
                .Value = ""
            End If
        End With
    Else
        MsgBox "Ticket " & Ticket & " non trouvé."
    End If
     
    End Sub
    Ne pas hésiter à désactiver le recalcul des formules (Application.Calculation) et le rafraichissement d'écran (Application.ScreenUpDating), voir même les évènements (Application.EnableEvents) si c'est encore trop long.

  14. #14
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 290
    Points : 84
    Points
    84
    Par défaut
    alors j'ai testé ta macro elle fonctionne déjà ! j'ai bataillé pour l'adapter à ma base de donnée la colonne C passe à colonne D pour vérifier le nbval().

    mais sur 40000 enregistrements (=nb_tickets) ça à l'air de passer rapidement.

    *****************************
    avec ma méthode des if à gogo j'étais à 40s
    avec application.screenupdating à false je gagnais 5s

    *******************************
    avec ta dernière méthode et avec le application.screenupdating=true ça passe de manière quasi instantanée... DONC C'est SUPER EN DE TERME VITESSE.
    donc je retiens ta méthode ! bon je chercherai application.worksheetfunction.countA (range ....) à quoi sert et comment cela marche, car actuellement, c'est trop dur pour moi ce truc, malgré tes précieux commentaires. DONC MERCI infiniment pour ta solution et ta patience et surtout ta gentillesse... et j'apprends des trucs en plus dont j'ignorais
    ********************************


    PAR CONTRE

    du coup évoqué quelques posts auparavant j'ai le problème similaire de vitesse d'exécution avec ma listbox située dans mon userform.
    j'affiche en colonne 0 du listbox1 des numéros d'article genre 5xxxxx (de la colonne H de ma feuil1) et dans sa 1 colonne ces fameux nb_tickets( de la colonne B de ma feuil1).
    mon principal problème est la vitesse d'affichage du listing après avoir choisit l'article dans mon combobox1 (colonne J de ma feuil1), parce qu'il va chercher dans ma base les informations en colonne H et B selon critère de J. J'ai effectué déjà 2 méthodes non efficace en temps

    une ligne par ligne encore

    Nom : Capture d’écran 2016-07-17 à 09.33.43.png
Affichages : 455
Taille : 14,9 Ko

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    For ligne = 9 To Sheets("Feuil1").Range("J" & Rows.Count).End(xlUp).Row
    If Cells(ligne, 10).Value = ComboBox1.Value Then
     
    ListBox1.AddItem
    Me.ListBox1.List(ListBox1.ListCount - 1, 0) = Cells(ligne, 8) 'pour la colonne H
    Me.ListBox1.List(ListBox1.ListCount - 1, 1) = Cells(ligne, 2) 'pour la colonne B
    End If
    Next ligne
    et une autre donnée par msnd microsoft sur leur site et adaptée à mon utilisation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    ligne = Worksheets("Feuil1").Range("J" & Rows.Count).End(xlUp).Row
    cellule = "$J$9" & ":" & "$J$" & ligne
    With Worksheets("Feuil1").Range(cellule)
    Set c = .Find(ComboBox1.Value, LookIn:=xlValues)
     
    If Not c Is Nothing Then
    adresse = c.Address 'adresse est la première adresse trouvée
     
    Do
    ListBox1.AddItem
     
    Me.ListBox1.List(ListBox1.ListCount - 1, 0) = Cells(c.Row, 8)
    Me.ListBox1.List(ListBox1.ListCount - 1, 1) = Cells(c.Row, 2)
    Set c = Worksheets("Feuil1").Range(cellule).FindNext(c)
    Loop While Not c Is Nothing And c.Address <> adresse
    End If
    End With
    les deux sont lentes pour 19347 enregistrements il faut attendre 14s pour voir apparaitre mon listing
    Images attachées Images attachées  

  15. #15
    Expert éminent

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 073
    Points : 9 853
    Points
    9 853
    Billets dans le blog
    5
    Par défaut
    Bonjour,

    je vois très bien l'utilisation d'un filtre automatique ou d'un filtre avancé (avec une feuille tampon pour le filtre avancé) ... mais y'a peut être encore plus simple.

    pour éviter des allers et retours infructueux, peux-tu joindre un fichier excel sans macro (.xlsx) et contenant un exemple de tes données ?

    Pour Application.Worksheetfunction.CountA ... c'est tout simplement l'utilisation VBA de la fonction de feuille de calcul NBVAL(Range1,Range2,Range3....)

  16. #16
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 290
    Points : 84
    Points
    84
    Par défaut
    voilà

    Classeur3.xlsx

    problème avec listbox et du coup je m'aperçois avec une saisie dans un textbox je galère avec un nombre important de donnée.

    peut-être un peu plus parlant, avec ce fichier mieux complété
    Classeur3.xlsx

    j'ai regardé sur range.filter ou range.filteradvanced mais bon ma combo filtre l'article déjà ou alors je ne sais pas comment on le couple avec ma listbox.

    De plus a priori certains ont essayés de mettre leur listing > 100 000 lignes dans un array puis de l'array vers le listbox idem. toujours un problème de vitesse et pas de soluce au bout...

    il ne me reste plus qu'à limité mon listing et à chaque 500 lignes de les stocker dans une autre feuille, mais bon je n'ai plus vraiment une base de donnée à proprement parlé

  17. #17
    Expert éminent Avatar de casefayere
    Homme Profil pro
    RETRAITE
    Inscrit en
    Décembre 2006
    Messages
    5 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations professionnelles :
    Activité : RETRAITE
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2006
    Messages : 5 138
    Points : 9 548
    Points
    9 548
    Par défaut
    Bonjour,
    sans regarder ton fichier, pour remplir ta ListBox, si tu passes par des tableaux, admettons avec l'évènement "Click"" de la Combo
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    Private Sub ComboBox1_Click()
    Dim TbG, Tb1(), ligne As Long, x As Long, Tb2(), TbL()
    With Sheets("Feuil1")
      TbG = .Range("B9", .Range("J" & Rows.Count).End(xlUp))
      x = 0
      For ligne = 1 To UBound(TbG, 1)
        If TbG(ligne, 9) = ComboBox1.Value Then
          x = x + 1: ReDim Preserve Tb1(1 To x): ReDim Preserve Tb2(1 To x)
          Tb1(x) = TbG(ligne, 7)
          Tb2(x) = TbG(ligne, 1)
        End If
      Next ligne
      ReDim TbL(1 To UBound(Tb1), 1 To 2)
      For ligne = 1 To UBound(TbL, 1)
          TbL(ligne, 1) = Tb1(ligne)
          TbL(ligne, 2) = Tb2(ligne)
      Next ligne
      ListBox1.List = TbL 'Application.Transpose()
    End With
     
    End Sub
    Cordialement,
    Dom
    _____________________________________________
    Vous êtes nouveau ? pour baliser votre code, cliquer sur cet exemple : Anomaly
    pensez à cliquer sur si votre problème l'est
    Par contre, il est désagréable de voir une discussion résolue sans message final du demandeur (satisfaction, désarroi, remerciement, conclusion...)

  18. #18
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 290
    Points : 84
    Points
    84
    Par défaut
    Merci Casefayere !


    1,62 secondes cela prend à balayer 38485 lignes
    3,17 secondes pour 50247 lignes
    10 secondes pour 100 000 lignes

    et à transposer dans un tableau dont j'aurai été incapable de le faire. Donc je suis jaloux de vos prouesses.

    Comme Joe.levrai je ne pige pas toute la macro.

    pour l'instant mes problèmes de :
    - supprimer les lignes et les reclasser en ordre décroissant dans ma base de donnée -> méthode de joe.levrai => marche super et rapidement bien même avec 100 000 lignes
    - faire apparaitre le listing de ma base de donnée dans ma listbox -> méthode de casefayere => je prend bien sur sans froisser quiconque si il y a plus rapide : je demande à voir/tester
    - Ma recherche via un textbox prend 3 à 4 secondes par appuye pour corréler le numéro saisit au numéro dans la base dont il fauta afficher les infos des colonnes B F H J L N et plus peut-être

    si y a encore plus rapide bien entendu je suis preneur (si joe sais faire avec l'histoire du filtre a transposer dans une autre feuille ...) ou en demanderai-je trop ...

    en tout cas merci, mes problèmes sont presque tous résolus

    Petite précision pour casefayere.

    Je l'ai mis dans combobox_change()
    Car ma première value du combo est "".

    Donc si je le mets dans l'evenement combobo_click comment le code peut savoir quel listing à afficher ?

  19. #19
    Expert éminent Avatar de casefayere
    Homme Profil pro
    RETRAITE
    Inscrit en
    Décembre 2006
    Messages
    5 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations professionnelles :
    Activité : RETRAITE
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2006
    Messages : 5 138
    Points : 9 548
    Points
    9 548
    Par défaut
    Petite précision pour casefayere.

    Je l'ai mis dans combobox_change()
    je ne donne qu'un exemple, après peu m'importe l'évènement
    Dès que j'ai 5 mn, je te renvoie le code avec explications

    il y a surement mieux mais, comme promis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    Private Sub ComboBox1_Click() 'donc à toi de voir l'évènement
    ci 'dessous, je déclare _
     Tbg qui comprendra toutes les données de B à J _
     Tb1() qui reprendra les données de H _
     Tb2() qui reprendra les dnnées de B _
     TbL() qui reprendra Tb2 en 1ère dimension, Tb1 en 2ème dimension
    Dim TbG, Tb1(), Tb2(), TbL(), ligne As Long, x As Long
    With Sheets("Feuil1")
      TbG = .Range("B9", .Range("J" & Rows.Count).End(xlUp)) 'voir ci-dessus
      x = 0
      For ligne = 1 To UBound(TbG, 1) 'on boucle sur le variable TbG
        If TbG(ligne, 9) = ComboBox1.Value Then 'la condition (traduit si J&ligne = combo)
          x = x + 1: ReDim Preserve Tb1(1 To x): ReDim Preserve Tb2(1 To x) 'je redimensionne les deux autres tableaux à 1 dimension
          Tb1(x) = TbG(ligne, 7) 'les valeurs de H&ligne pour Tb1(x)
          Tb2(x) = TbG(ligne, 1) 'les valeurs de B&ligne pour Tb2(x)
        End If
      Next ligne
      ReDim TbL(1 To UBound(Tb1), 1 To 2) 'je dimensionne à 2 dimensions, 1ère dimension le nombre de lignes, 2ème dimesion 2 colonnes (B & H)
      For ligne = 1 To UBound(TbL, 1) 'je boucle sur un des deux tableaux
          TbL(ligne, 1) = Tb1(ligne) '1ère dimension egal à B triée
          TbL(ligne, 2) = Tb2(ligne) '2ère dimension egal à H triée
      Next ligne
      ListBox1.List = TbL 'le résultat dans la ListBox
    End With
     
    End Sub
    à tester si plus rapide 2 tableaux en moins
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Private Sub ComboBox1_Click() 'donc à toi de voir l'évènement
    'ci-dessous, je déclare _
     Tbg qui comprendra toutes les données de B à J _
     Tb1() qui reprendra les données de B et H
    Dim TbG, Tb1(), ligne As Long, x As Long
    With Sheets("Feuil1")
      x = WorksheetFunction.CountIf(.Range("B9", .Range("J" & Rows.Count).End(xlUp)), ComboBox1.Value)
      TbG = .Range("B9", .Range("J" & Rows.Count).End(xlUp)) 'voir ci-dessus
      ReDim Tb1(1 To x, 1 To 2)
      x = 1
      For ligne = 1 To UBound(TbG, 1) 'on boucle sur le variable TbG
        If TbG(ligne, 9) = ComboBox1.Value Then 'la condition (traduit si J&ligne = combo)
          Tb1(x, 1) = TbG(ligne, 1): Tb1(x, 2) = TbG(ligne, 7): x = x + 1
        End If
      Next ligne
      ListBox1.List = Tb1 'le résultat dans la ListBox
    End With
     
    End Sub
    Cordialement,
    Dom
    _____________________________________________
    Vous êtes nouveau ? pour baliser votre code, cliquer sur cet exemple : Anomaly
    pensez à cliquer sur si votre problème l'est
    Par contre, il est désagréable de voir une discussion résolue sans message final du demandeur (satisfaction, désarroi, remerciement, conclusion...)

  20. #20
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2016
    Messages : 290
    Points : 84
    Points
    84
    Par défaut
    Merci pour ton aide Casefeyere.

    Je comprends un peu mieux. Grosso modo :
    On copie une plage de cellule dans un tableau TbG
    Puis on créée 2 tableaux à 1D (ou 1seul à 2D) qui sont (est) l'image des colonnes b et j de la feuille
    Puis on vient piocher dans tbG pour alimenter tb1 et tb2
    Puis remplit la listebox par tb1 et tb2

    Ok

    Quant à la 2ème version j'essayerai demain au boulot.

    Par compte je vois que tu fais TbG =.range("B9",.range("J.........,)
    C'est une plage en gros ? Si oui est-ce que cela ne va pas augmenté le ralentissement car finalement entre les colonnes B et J, je n'ai pas besoin d'afficher leurs valeurs dans mon listbox. Dit autrement crois-tu qu'en remplissant tbG uniquement par colonne b et j ça apporterai un gain en vitesse d'execution ? Si oui perso, du moins pour ce soir, je ne vois pas comment on fait... Il doit y avoir des aides certinement sur mdsn.

    J'aurai bien aimé que joe me montre une version, mais je ne peux pas vous embeter non plus avec mes problèmes...

    En tout cas merci et demain soir je vous tiens au courant

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. [XL-2010] Optimisation exécution de code : suppression espace de fin sur plage de données
    Par Poussemousse dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 16/02/2015, 14h25
  2. Problème d'exécution sur un OnMouseWheel
    Par Omeggg dans le forum Composants VCL
    Réponses: 7
    Dernier message: 15/04/2006, 18h24
  3. Réponses: 4
    Dernier message: 02/04/2006, 18h42
  4. [VBA-E]Arrêt d'exécution sur une requette d'enregistrement
    Par thierry27 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 11/02/2006, 18h53
  5. Exécutable sur un autre PC
    Par Yphon dans le forum Langage
    Réponses: 6
    Dernier message: 13/01/2006, 21h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo